Dependency Issues EventSource implementation for semantic logging in a large application

I am working on a large product consisting of three window services and several regular window applications (.exe). Now we want to switch to ETW and Semantic Logging and use Microsoft.Diagnostics.Tracing.EventSource.

I read somewhere that all logically connected parts of an application must use the same event source. This means that it is desirable that we have a lot of one EventSource for our services. But how can we do this without introducing dependencies among almost all assemblies in the product?

Currently, the application consists of 70 assemblies. And in order to be able to create a log method in EventSource, which, for example, takes the value enum, the assembly containing the event source must refer to the assembly that defines the enumeration, which means that the definition of the enumeration must be transferred from the assembly using it .exe, it is possible , to something that all assemblies refer to.

Is there a way to have multiple classes derived from EventSource in a single application that still uses the same ETW EventSource? Or what would be a good way to implement semantic registration with ETW in such a scenario when it is undesirable to introduce a whole bunch of new dependencies to create your journal class?

+7
etw etw-eventsource
source share
3 answers

There are three strategies:

  • Create a single assembly that contains only the derived EventSource class that defines events for all applications. Add a link to this assembly to all required projects. For simplicity, you can wrap it in a nuget package.
  • Create one test project with only one derived EventSource class. Use it only for validation purposes. Copy this class into all the necessary projects. This is basically the same solution, but without binary dependencies.
  • Create a new derived EventSource class for each project, but specify the same Guid attribute for them. In this case, you need to make sure that all these event sources have the same declaration for overlapping (with the same identifier) ​​events. And in this case, you need to write a merge manifest tool to create a combined manifest.
0
source share

Be careful, EventSource classes must be sealed! If you want to use dependency injection using EventSource , there is a workaround ...

Define a simple interface:

 // A simple interface to log what you need ... public interface ILog { void Debug(string message); void Info(string message); void Warn(string message); void Error(string message); void Error(string message, Exception exception); } 

And implementation (the implementation of your interface should be decorated with NonEventAttribute :

 [EventSource(Name = "MyLogEventsource")] public class Log : EventSource, ILog { public Log() { EventSourceAnalyzer.InspectAll(this); } [NonEvent] public void Debug(string message) { DebugInternal(message); } [Event(1)] private void DebugInternal(string message) { WriteEvent(1, message); } [NonEvent] public void Info(string message) { InfoInternal(message); } [Event(2)] private void InfoInternal(string message) { WriteEvent(2, message); } [NonEvent] public void Warn(string message) { WarnInternal(message); } [Event(3)] private void WarnInternal(string message) { WriteEvent(3, message); } [NonEvent] public void Error(string message) { ErrorInternal(message, "", ""); } [NonEvent] public void Error(string message, Exception exception) { ErrorInternal(message, exception.Message, exception.ToString()); } [Event(4)] private void ErrorInternal(string message, string exceptionMessage, string exceptionDetails) { WriteEvent(4, message, exceptionMessage, exceptionDetails); } } 

you can now enter the logging class ^^

0
source share

I usually do this so that there is a segregation of interfaces, although they use the same instance of the event source. In my ioc, all code with ISingletonDependency is registered as singleton. Thus, you can call interfaces using very specific methods, but they are still the same EventSource.

Hope this helps.

 public MyCompanyEventSource: IMyCompanyEventSource, ISingletonDependency{ } public IMyCompanyEventSource: IComponentLogger1, IComponentLogger2, IComponentLogger3{ } public Component1{ public Component1(IComponentLogger logger){ } } 
0
source share

All Articles