Open zah opened 4 years ago
@zah ,
Since I'm testing and learning about the serialization
and faststreams
libraries anyway, I figured I'd go ahead and take on a bounty task as you suggested in another conversation. This one sounds interesting. Do you need any kind of notice when a programmer picks up on one of these projects?
That's great to hear @JohnAD. Just get started and try to open an work-in-progress PR as soon as possible. I hope the description above is clear enough, but in case you need any help, don't hesitate to contact me on Gitter.
When I create the serializations for textLines
and textBlocks
, would you like those serializations stored in new libraries similar to nim-json-serialization
? aka nim-textline-serialization
and nim-textblock-serialization
? Or would you prefer them embedded in the nim-chronicles
repo?
I think they will sit fine here. We are also interested only in Writers for these formats, not the full spectrum of features.
Chronicles allows you to specify the style of the log output (e.g.
textlines
,textblocks
,json
, etc) as explained in the README of the library.At the moment, the human-readable text formats (textlines and textblocks) suffer from the fact that they rely on Nim's
$
operator to produce the logged strings. The user may override this by specifying a filtering function through thechronicles.formatIt
API. This reliance on$
has a number of drawbacks:1) Composite objects may be printed by Nim with characters that must be escaped within the Chronicles output (making the log reading experience less pleasant).
2) A field of an object may have a type for which a custom formatting exists (specified with
formatIt
), but the$
operator has no way of knowing that (the custom formatting will work only when the value of the particular type was directly used as akey = val
property in a log statement).3) Some specific types (such as Exceptions) are printed in way that's very hard to read. Ideally, the stack trace of the exception should appear as multiple indented lines following the formatted logged properties.
To solve all of these issues, it's possible to define all output types as nim-serialization formats. Please study to implementation of the
JsonRecord
output type as an example of this. Please note that the code is slightly less trivial due to the existing support for JavaScript compilation.Each log statement creates a
Record
instance of the designated output type. Then a series of calls are executed over this instance (initLogRecord
,setFirstProperty
,setProperty
,flushRecord
) to send it to its intended destination.After the suggested refactoring here, it's expected that there will be single generic Record type accepting as a parameter the name of a nim-serialization format. In nim-serialization, each format is associated with a
Writer
type created over anOutputStream
. You use the writer to issue a sequence of calls (beginRecord
,writeField(name, value)
,endRecord
) that will buffer in memory the output of the log statement before it's finally sent to the screen withflushRecord(logRecord)
. If a composite record is passed towriteField
, this may result in more recursive calls of the same nature thus implementing the arbitrary nesting possible in json.The same mechanism should work fine for text lines and text blocks. To implement pretty-printing, the json writer maintains a counter for the current nesting level (the text blocks format can do the same). The exceptions can be buffered in a variable within the writer and appended at the end of the record in
endRecord
.Once this refactoring is done, it would be possible to configure Chronicles with arbitrary nim-serialization formats. When the user specifies a sink type such as
json
orxml
, Chronicles could try importing a package with a name such asjson_serialization
orxml_serialization
. Within the imported module, there will be symbols such asSerializationFormat
,WriterType
andReaderType
. Thus, nim-serialization will become generic on the package level.