Review: std.logger
Jakob Ovrum via Digitalmars-d
digitalmars-d at puremagic.com
Thu Jul 24 16:40:54 PDT 2014
On Thursday, 24 July 2014 at 23:01:56 UTC, Robert burner Schadek
wrote:
> I do this lazily in a function, because having it global froze
> std.concurrency and std.process unittest. I couldn't figure out
> why.
It could still be initialized lazily, using `emplace`, ala
---
private static __gshared Logger _defaultLogger;
Logger defaultLogger() @safe @nogc
{
static __gshared ubyte[__traits(classInstanceSize,
StdoutLogger)] buffer;
if(!_defaultLogger) // TODO: thread safety
_defaultLogger = () @trusted { return
emplace!StdoutLogger(buffer); }();
return _defaultLogger;
}
void defaultLogger(Logger newDefaultLogger) @safe @nogc
{
_defaultLogger = newDefaultLogger;
}
---
> As said earlier, I think GC and Logger is a none issue. I mean
> how often has anyone seen a Logger created in a loop over and
> over again.
Some programs want to forego having a GC-heap entirely. That
means any GC allocation is a no-go.
Class instances don't have to be GC-allocated, so it's not an
issue to use classes.
> nothrow will be hard as std.logger uses format, same for nogc
How often have you seen a formatted log message logged in a loop?
I'd wager that happens quite often. Using `format` is a no-go as
it completely thrashes the GC, it needs to use `formattedWrite`
to write directly to the underlying buffer (such as a file).
Even using `formattedWrite` though, `nothrow` is still a problem,
and since exceptions are still GC-allocated, it doesn't help with
@nogc either. The latter is something we can fix in the future
though.
> So you're thinking of a stack array?
No, MultiLogger could manage a non-GC yet still heap-allocated
array using std.container.array.Array. It uses the C heap
internally, i.e. malloc, realloc and free. Sortedness can be used
for searching by name in logarithmic time if desired.
> What about the log functions and there implementation as well
> as the Logger specific LogLevel and name?
The log functions don't need to be virtual, only the
`writeLogMsg` function does, so these implementations can either
be final member functions of the interface, or UFCS functions as
I suggested in the corresponding line comment.
The Logger-specific LogLevel and the name do not have to be
implemented by Logger. Leave it to concrete classes to implement
those. As an internal aid, an abstract GenericLogger base class
that manages these properties as member variables (as Logger
currently does) can help.
More information about the Digitalmars-d
mailing list