p-org / PSharp

A framework for rapid development of reliable asynchronous software.
MIT License
390 stars 37 forks source link

refactored logger to separate concerns #465

Closed pdeligia closed 5 years ago

pdeligia commented 5 years ago

Refactored the ILogger interface and MachineLogger 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 the ILogger interface for logging messages. The previous MachineLogger has now become RuntimeLogWriter, which owns these two interfaces, and is used by the runtime to format and log all runtime messages. In some sense, the ILogger 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 the RuntimeLogWriter formats messages (e.g. a language like P on top of P# can change the log messages to its own versions). Finally, the RuntimeLogWriter can be subclassed (similar to how MachineLogger 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.

pdeligia commented 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.

pdeligia commented 5 years ago

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"!