digitalmars.D.learn - GC free Writer
- David (16/16) Feb 08 2013 I am currently implementing a logging module, I want to make logging to
- Sean Kelly (9/29) Feb 08 2013 (logging
- David (27/30) Feb 08 2013 I don't understand, you mean I should pass `args` directly to the
- Lee Braiden (15/28) Feb 08 2013 Will this module be published for others to use? If so, can I suggest a...
- David (6/39) Feb 08 2013 Well, here it is:
I am currently implementing a logging module, I want to make logging to stderr/stdout/"any file" possible, also during runtime-shutdown (logging from dtors) Atm it lookes like this: ---- void log(LogLevel level, Args...)(Args args) { string message = format(args); ... pass string to writer } --- But format allocates! That makes it throw an InvalidMemoryOperationError when calling the logging function from a dtor. So I need a GC-free writer for std.format.formattedWrite, similiar to std.stdio's LockingTextWriter but with a buffer instead of a file (std.array.Appender GC free something like that). I couldn't come up with a working solution, I hope you have ideas.
Feb 08 2013
On Feb 8, 2013, at 7:57 AM, David <d dav1d.de> wrote:I am currently implementing a logging module, I want to make logging =tostderr/stdout/"any file" possible, also during runtime-shutdown =(loggingfrom dtors) =20 Atm it lookes like this: =20 ---- void log(LogLevel level, Args...)(Args args) { string message =3D format(args); =20 ... pass string to writer } --- =20 But format allocates! That makes it throw an =InvalidMemoryOperationErrorwhen calling the logging function from a dtor. So I need a GC-free writer for std.format.formattedWrite, similiar to std.stdio's LockingTextWriter but with a buffer instead of a file (std.array.Appender GC free something like that). I couldn't come up with a working solution, I hope you have ideas.Does your IO layer require one call per log line or can you do multiple = writes followed by an "end log line" terminator? Assuming the former, = the most obvious approach would be for the writer to have a static array = equal to the max log line size, accumulate until done and then issue one = write to the output layer.=
Feb 08 2013
Does your IO layer require one call per log line or can you do multiple writes followed by an "end log line" terminator? Assuming the former, the most obvious approach would be for the writer to have a static array equal to the max log line size, accumulate until done and then issue one write to the output layer.I don't understand, you mean I should pass `args` directly to the writer? I tried it, ended up with linker errors, since writer is an interface: ---- interface IWriter { void log(LogLevel level, string name, const(char)[] message); property bool bubbles(); property void bubbles(bool); } ---- So I have to pass a string around, which isn't a big deal, until the runtime shuts down. jA_cOp pointed me to std.string.sformat on IRC, I tried it with a stack-allocated buffer, unfortunatly it seems to allocate somewhere: ---- immutable(char)[], uint).sformat(char[], const(char[]), void*, immutable(char)[], uint) ---- So this is also no solution, since I wasn't able to find the origin of this allocation (it's not because an error is thrown, well very unlikely, formatting with the same arguments at "runtime" works)
Feb 08 2013
On Fri, 08 Feb 2013 16:57:39 +0100, David wrote:I am currently implementing a logging module, I want to make logging to stderr/stdout/"any file" possible, also during runtime-shutdown (logging from dtors) Atm it lookes like this: ---- void log(LogLevel level, Args...)(Args args) { string message = format(args); ... pass string to writer } ---Will this module be published for others to use? If so, can I suggest a feature? One thing that's really important with logging, but rarely available, is not levels, but code areas. I believe python, for example, allows you to name log sections: logger("mainsection.subsection.subsubsection1", "message1") logger("mainsection.subsection.subsubsection2", "message2") and then you can enable, say, everything related to "subsection", but then filter out everything in "subsubsection2". That's really important, when debugging/auditing complex apps, without actually wanting to modify the code just to find out what's going on. Especially since modifying the code can CHANGE what's going on. -- Lee
Feb 08 2013
Am 08.02.2013 22:53, schrieb Lee Braiden:On Fri, 08 Feb 2013 16:57:39 +0100, David wrote:Well, here it is: https://github.com/Dav1dde/BraLa/blob/master/brala/utils/log.d You can't name section, but you can create loggers with different names. But this actually a good idea (design is similiar, but less complex and powerful, to logbook http://packages.python.org/Logbook/ )I am currently implementing a logging module, I want to make logging to stderr/stdout/"any file" possible, also during runtime-shutdown (logging from dtors) Atm it lookes like this: ---- void log(LogLevel level, Args...)(Args args) { string message = format(args); ... pass string to writer } ---Will this module be published for others to use? If so, can I suggest a feature? One thing that's really important with logging, but rarely available, is not levels, but code areas. I believe python, for example, allows you to name log sections: logger("mainsection.subsection.subsubsection1", "message1") logger("mainsection.subsection.subsubsection2", "message2") and then you can enable, say, everything related to "subsection", but then filter out everything in "subsubsection2". That's really important, when debugging/auditing complex apps, without actually wanting to modify the code just to find out what's going on. Especially since modifying the code can CHANGE what's going on.
Feb 08 2013