I experimented with application level tracing/profiling of d applications similar to what is described in https://dlang.org/blog/2020/03/13/tracing-d-applications/ as the "writef-based approach". Only difference is, that I am emitting json (https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit#heading=h.lpfof2aylapb) that is compatible with https://ui.perfetto.dev/ which gives nice interactive insights of the data.
The code is available at https://github.com/gizmomogwai/profiled and can be used as dub package by registering it locally with dub add-local. The github repository also contains one screenshot produced with a patched unit-threaded library to emit the tracing information on a small project of mine.
I do have a few question on how to do things in dlang though:
-
I went for a singleton for storing tracing/logging information that needs to be initialized manually. Is __gshared the right way to do that?
-
The data is stored in a std.array.appender protected by a mutex and only later printed as json. Any way to do this more elegantly than with the scope(exit) constructs to unlock the mutex?
-
For the tracing/profiling events I went with subclasses of an abstract event class (I only implemented one kind of event, whereas the tracing json format supports a lot more scenarios). When one is interested in when something happens and how long it takes, one can call
public Unique!CompleteEventProcess start(string name)
on the profiler which an uniquepointer that is then automatically deleted if it goes out of scope (and then takes the time). Is this a reasonable way todo it? E.g. it would be an error if the unique ptr is passed to another thread, because the CompleteEvents of the tracing format expect to be starting and stopping on the same thread. -
Would something like that be interesting for others as a dub package (ATM its so small, that having it as an external dependency is not worth it IMHO)?
-
The complete event normally expects the real process and thread id as used by the os. Looks like https://dlang.org/phobos/std_process.html#.Pid.processID delivers the process id. Is there also a way to get the "real" threadid?
Thanks in advance,
Christian