September 04, 2014
On Wednesday, 3 September 2014 at 22:34:30 UTC, Kevin Lamonte wrote:
> I've got a feature request in for just that: https://issues.dlang.org/show_bug.cgi?id=13406

Interesting! I am not 100% convinced that scope(failure/success) is the way to go since it will cause potentially a lot of extra work when unwinding the stack in case of an exception? Or maybe the stack unwinder could to the tracing directly without using the scope construct.

Another option would be to only trace the landing-pad ("catch statement") for exceptions, so you would get something like "exception X caught in functionname()", but not sure how to do it without loosing information. You might need a counter for each enter/exit or something like that and let the stack-unwinder count down.
September 04, 2014
On Thursday, 4 September 2014 at 04:53:36 UTC, Ola Fosheim Grøstad wrote:
> You might need a counter for each enter/exit or something like that and let the stack-unwinder count down.

I meant: you might need to "increment a stack specific counter", but that does not sound practical. I guess it is better to have a more complex stack unwinder.

Co-routines create some problems here. You probably need to trace that they yield.
September 05, 2014
On Tuesday, 2 September 2014 at 15:10:35 UTC, Ola Fosheim Grøstad wrote:
> On Tuesday, 2 September 2014 at 14:53:17 UTC, Dicebot wrote:
>> If you are going to speak more about abstract performance I am going to simply ignore any of your further posts on topic.
>
> I am not abstract. These are very concrete requirements:
>
> 1. You have to be able to determine types and formatting at compile time otherwise you cannot do binary logging.
>
> 2. You have to be able to determine types and formatting at compile time otherwise you cannot minimize the probability of introducing run-time errors by turning on full logging.

Ok, this is much more specific. With a similar concerns in mind I have proposed to add a `log` overload that doesn't have variadic arguments and takes a single pre-formatted string (with file/line/module as default run-time arguments). With a custom formatting function (compile-time or run-time at users choice) it should fit these requirements. Does that sounds feasible to you?
September 05, 2014
On Friday, 5 September 2014 at 18:24:01 UTC, Dicebot wrote:
> Ok, this is much more specific. With a similar concerns in mind I have proposed to add a `log` overload that doesn't have variadic arguments and takes a single pre-formatted string (with file/line/module as default run-time arguments). With a custom formatting function (compile-time or run-time at users choice) it should fit these requirements. Does that sounds feasible to you?

P.S. Reason why compile-time format checking can't be added to base API is rather simple - it needs to be at least somewhat similar to one of writefln
September 05, 2014
On Friday, 5 September 2014 at 18:27:12 UTC, Dicebot wrote:
> P.S. Reason why compile-time format checking can't be added to base API is rather simple - it needs to be at least somewhat similar to one of writefln

Hm. My experience with Python for server use tells me that the problem with dynamic languages isn't the primarily the main execution paths, but the exceptional ones. Having to update a server because a request erroneously fails due to a logging statement (or typos in asserts or any other kind of debugging statement) is annoying.

Upon further reflection I think it is important to require logging to be a fail-safe transparent operation (conceptually close to an annotation).

I don't think monitoring statements should be able to cause runtime errors at all.
September 05, 2014
On Wednesday, 3 September 2014 at 22:34:30 UTC, Kevin Lamonte wrote:
>> Sounds like a candidate for an attribute, just prefix a function or function call with @trace(level)?
>
> I've got a feature request in for just that: https://issues.dlang.org/show_bug.cgi?id=13406
>
> While thinking about it I realize that it's actually very easy to generalize @trace into the equivalent of Common Lisp :before, :after, and :around methods: @scope(&scopeFn) .  (It would work even better if scope(success) and scope(failure) exposed what they are returning/throwing.)
>
> In the meantime Log4D has a (barely tested) mixin.

This can already be implemented in a library if "mixin of an implementation" idiom is used. I think it fits D style better (having attributes modify actual code flow is unprecedented)
September 06, 2014
On Wednesday, 3 September 2014 at 13:13:31 UTC, Ola Fosheim Grøstad wrote:

> If you accept slightly out of sync logging then you can have thread local buffers and on x86 use the command RDTSC which gives you a (good enough) timer value so you can merge the buffers from threads later. It takes roughly 20-30 cycles which I presume is better than CAS instructions, or you can just write directly to a global counter without CAS and accept that it jitters?

Since we are talking about performance, I did some tests and found to my surprise that ~95% of the time consumed in a log call is Clock.currTime's call to clock_gettime().  I submitted a report for it (https://issues.dlang.org/show_bug.cgi?id=13433), but it also brings up how to expose it in the std.logger API.

The API automatically grabs thisTid and Clock.currTime during construction of the LogEntry (plus it should also grab Thread.getThis and Fiber.getThis).  Should this behavior be modifiable by clients, by subclasses, or neither?  If so, how?
September 06, 2014
On Saturday, 6 September 2014 at 19:41:54 UTC, Kevin Lamonte wrote:
> The API automatically grabs thisTid and Clock.currTime during construction of the LogEntry (plus it should also grab Thread.getThis and Fiber.getThis).  Should this behavior be modifiable by clients, by subclasses, or neither?  If so, how?

I think maybe we should start with creating a high performance inlined (for ldc/gdc) in-memory multi-threaded binary reference logger and then extend the interface in ways that does not make it noticeably slower using the reference logger as the baseline. (Noticeably > 100%?)

When logging to an external logging service you might want the logging service do the time-keeping so you don't get merged logs from multiple servers that are out of sync. In that case collecting absolute time locally is kinda pointless (although you might want to submit serial numbers and relative time between logging events from the same server).
September 08, 2014
On Saturday, 30 August 2014 at 02:11:49 UTC, Dicebot wrote:
> On Tuesday, 26 August 2014 at 21:04:28 UTC, Robert burner Schadek wrote:
>
> ====================================
> Jakob Ovrum
> ====================================
>
> "The *API* must support minimal dynamic memory allocation for
> the normal execution path. However, theoretical *implementation*
> changes that reduce memory allocation are not a deal-breaker."
>
> This seems to be addressed but though it is desired to verify it via @nogc unittest block which uses stub no-op logger (to verify that nothing in between allocates). One place were GC allocations is unavoidable is core.d:1628 - it will always create FileLogger first and allow assigning custom one later. Is there any way to circumvent it?
>
> "API must specify a strong stance on threading, whatever the
> form it takes"
>
> Does not seem to be addressed at all. At least I see no mentions of it in core.d documentation and logger instance itself is plain __gshared thing.
>
> $ grep -R -n "shared" std/experimental/logger/
> std/experimental/logger/core.d:1625:    static __gshared Logger logger;
> std/experimental/logger/core.d:1635:    static __gshared LogLevel ll = LogLevel.all;
>
> Does not seem enough for sure.

I working on this

>
> "This one might seem unnecessarily strict, but I think the fact
> that Logger is a class and not an interface smells of poor
> design. I might still be convinced that having it as a class is
> justified, but my current stance is that it must be an interface."
>
> Neither does seem to be addressed nor I can find any comment on why it is not going to be addressed.

Every Logger has to have a LogLevel, interfaces won't work there

>
> ====================================
> Francesco Cattoglio
> ====================================
>
> "As far as I undestood, there's no way right now to do logging
> without using the GC. And that means it is currently impossible
> to log inside destructor calls. That is a blocker in my book."
>
> First part partially addressed - missing @nogc @nothrow logger implementation out of the box. Considering this request does not go very well with current language implementation it may be ignored for now but official stance about it must be clearly documented.

at least for logf nothrow will not work because of a wrong formatting string or args. log can not be nothrow because custom toString for structs and class are allowed.

nogc is not possible because of custom toString

that won't fix, but for default types it is nogc.
>
> ====================================
> Byron Heads
> ====================================
>
>
> "Logger should include a shared Logger, or include it in the interface for
> outside libraries to handle the implementation.  There will be libraries
> that thread internally and will need to support shared logging."
>
> Is not addressed.

See Jakob Ovrun

September 08, 2014
On Saturday, 30 August 2014 at 02:16:55 UTC, Dicebot wrote:
>
> ==============================
> Martin Nowak
> ==============================
>
> "Support duck-typing for the log functions.
> Logger should be a concept and log functions should be free-standing
> UFCS functions that take any `isLogger!T`.
> To support a global `defaultLog` variable, you could add a Logger
> interface and a loggerObject shim. See
> http://dlang.org/phobos/std_range.html#inputRangeObject for this a pattern."
>
> Neither seem to be addressed nor countered.

Overly complicated IMO