4

I am using the Semantic Logging Application Block, and I have the following two EventSource based classes (inner constant classes omitted for brevity:

[EventSource(Name = EventSourceNames.Prism)]
public sealed class PrismEventSource: EventSource
{
  public static PrismEventSource Log = new PrismEventSource();
  [Event(1, Keywords = EventKeywords.None, Level = EventLevel.Informational)]
  public void PrismEvent(string message, Category category, Priority priority)
  {
    if (IsEnabled())
    {
      WriteEvent(1, message, category);
    }
  }
}

and

[EventSource(Name = EventSourceNames.Application)]
public sealed class ApplicationEventSource : EventSource
{
  public static ApplicationEventSource Log = new ApplicationEventSource();
  [Event(2, Message = "Duplicate menu item: {0}", Keywords = Keywords.Menu, Level = EventLevel.LogAlways, Task = Tasks.ImportMenu)]
  public void DuplicateMenuItem(string menuItemPath)
  {
    if (IsEnabled())
    {
      WriteEvent(2, menuItemPath);
    }
  }
}

I have a project wide singleton listener for both:

RollingLog = RollingFlatFileLog.CreateListener("XTimeDev.log", 2048, "yyyyMMdd HHmmss", RollFileExistsBehavior.Overwrite, RollInterval.None);
RollingLog.EnableEvents(EventSourceNames.Prism, EventLevel.LogAlways);
RollingLog.EnableEvents(EventSourceNames.Application, EventLevel.LogAlways);

Yet when I try and log from my Application source, nothing appears in the log file:

try
{
  Current.RegisterMenuItem(xtimeItem);
}
catch (ArgumentException ax)
{
  ApplicationEventSource.Log.DuplicateMenuItem(ax.Message);
} 

All I see in my log file is the startup events Prism logs through its event source, the one I give it in MefBootstrapper.CreateLogger:

class BootLogger : ILoggerFacade
{
  public void Log(string message, Category category, Priority priority)
  {
    PrismEventSource.Log.PrismEvent(message, category, priority);
  }
}

Why should only the PrismEventSource and not the ApplicationEventSource write to the file?

Gh61
  • 9,222
  • 4
  • 28
  • 39
ProfK
  • 49,207
  • 121
  • 399
  • 775

1 Answers1

4

Your method signature doesn't match the number of parameters you pass to WriteEvent.

If you change it to this it should work:

public void PrismEvent(string message, Category category, Priority priority)
{
  if (IsEnabled())
  {
    WriteEvent(1, message, category, priority);
    //                                 ^  ^
  }
}

Matching signatures are required for it to work properly.


You can detect future issues like this in a unit test by using EventSourceAnalyzer. I recommend using it, as it will find these errors much quicker.

Ernie S
  • 13,902
  • 4
  • 52
  • 79
Kendall Frey
  • 43,130
  • 20
  • 110
  • 148
  • Thanks for the tip about `EventSourceAnalyszer`, but `WriteEvent` isn't aware of how many parameters are passed to `PrismEvent`, so it cannot detect the mismatch. It has overloads that allow from 1 to 3 string parameters, and even one that takes `params object[]`. It is also the only one that is actually working. As I said, "All I see in my log file is the startup events Prism logs through its event source", that being the one you cite. Thanks also for pointing out my little bug. – ProfK May 01 '14 at 05:15
  • 1
    A normal C# method couldn't detect that, but the event source can, and it will cause problems. I think it goes by the registry for event signatures. Also, it could be that the Prism event source is somehow breaking the Application event source, which is enabled after it. – Kendall Frey May 01 '14 at 11:41
  • Other things that come to my head: `Log` is a field, where it's usually a property. You might have public methods or properties (or even events!) that are not events, and are not marked with `[NonEvent]`. I know this can cause errors. – Kendall Frey May 01 '14 at 11:43