Closed pdeligia closed 5 years ago
@ankushdesai this will allow custom logging support for P to P#. The interfaces have changed slightly (see PR description above and link to the doc). Will review PR internally and let you know when its ready for merging.
I don't think the word "Format" belongs on all the IRuntimeLogFormatter methods and I think the interface should be called IRuntimeLog. Your ILogger is really the formatter. I think of IRuntimeLog as a way to "know what is going on in the state machine". One reason for knowing what is going on is to write a log using the "ILogger", although call that one ILogFormatter. Another reason to know what is going on is to do something like DGML visualization. And for that kind of tooling integration "Format" seems weird. In fact if you strip off Format the methods will all be called On so the interface should be IRuntimeEvents, or IRuntimeTraceEvents. Now as for ILogger, I think it should move closer to other logging frameworks like https://www.codeproject.com/Articles/140911/log-net-Tutorial where it knows about warnings, errors, and informational log events, and then allow a client to "subscribe" to receive only certain class of log messages. Basically ETW if you know that from windows. See more details comments inline.
Great suggestion and I fully agree Chris. I want to keep a bigger refactoring of the logging infrastructure seperate from this PR though, as the short term goal is primarily to split the logger into log related functionality (where you write) and runtime-specific log messages which should be customizable (what you write). We can add what you suggested in our feature backlog!
Agreed about changing the name instead of "formatter"!
Refactored the
ILogger
interface andMachineLogger
implementation to improve the design, separate the concerns and support custom logging/formatting during systematic testing.To summarize, there are now two logging-related interfaces: the
IRuntimeLogFormatter
interface for formatting messages, and theILogger
interface for logging messages. The previousMachineLogger
has now becomeRuntimeLogWriter
, which owns these two interfaces, and is used by the runtime to format and log all runtime messages. In some sense, theILogger
interface is now runtime-agnostic and only contains the methods for actually writing the log (so someone who is interested in intercepting and using their own log mechanism only needs to customize this interface). On the other hand,IRuntimeLogFormatter
allows customization of how theRuntimeLogWriter
formats messages (e.g. a language like P on top of P# can change the log messages to its own versions). Finally, theRuntimeLogWriter
can be subclassed (similar to howMachineLogger
could be subclassed previously) to intercept log messages, filter them, change them, etc.Although this slightly breaks backwards compatibility, the change is minimal, as someone just needs to separate their logger, and set the interfaces calling the corresponding runtime APIs (as seen in the guide below), but most of the implementation remains the same.
The details are in the updated documentation here.
The nice thing is that now someone can easily customize logging output during testing (not possible before), and the logging interface complexity is reduced, since if someone just wants to override
Write
/WriteLine
do not have to deal with a complex runtime logging interface. Likewise, the tester can inject its own in-memory logger (required for capturing the trace to then dump it out), without interfering with a custom formatter / runtime log writer.