0

When setting up Semantic Logging Application Block (SLAB) to use multiple sinks (for example a flat file and rolling file) it's not writing to each sink based on the level in my logic; I am trying to understand why. I can get it to write to different sinks base on Keywords but not based on EventLevel.

I wanted one sink to get all logs and another sink to get only logs with a level of Warning (or worst). When I defined 2 listeners, one sink with level of "EventLevel.LogAlways" and another sink with level of "EventLevel.Warning", I am not getting any logging entries. (I define an EventSource method with a EventLevel of Verbose and was expecting to see logging from the listener defined with EventLevel.LogAlways)

Bellow is the logic I am trying to implement (Please let me know if this is not enough logic and I will update accordingly):

1) Using the aExpense as an example bellow, this is how the listeners are defined in my Application_Start:

//Log to file with EventLevel of at least Warning 
this.fileListener = FlatFileLog.CreateListener("aExpense.DataAccess.log", formatter: new XmlEventTextFormatter(EventTextFormatting.Indented), isAsync: true);
fileListener.EnableEvents(AExpenseEvents.Log, EventLevel.Warning, Keywords.All);

//Log to Rolling file with any EventLevel
this.rollingfileListener = RollingFlatFileLog.CreateListener("aExpense.UserInterface.log", rollSizeKB: 10, timestampPattern: "yyyy", rollFileExistsBehavior: RollFileExistsBehavior.Increment, rollInterval: RollInterval.Day, formatter: new JsonEventTextFormatter(EventTextFormatting.Indented), isAsync: true);
rollingfileListener.EnableEvents(AExpenseEvents.Log, EventLevel.LogAlways, Keywords.All);    

2) Writing a log is done like this:

//Log the event for application starting using Symmantic Logging (in-process)
AExpenseEvents.Log.ApplicationStarting();

3) The AExpenseEvents (EventSource) method for ApplicationStarting() is:

[Event(100, Level = EventLevel.Verbose, Keywords = Keywords.Application, Task = Tasks.Initialize, Opcode = Opcodes.Starting, Version = 1)]
public void ApplicationStarting()
{

    if (this.IsEnabled(EventLevel.Verbose, Keywords.Application))
    {
        this.WriteEvent(100);
    }
}
pnuts
  • 58,317
  • 11
  • 87
  • 139
mgalpy
  • 369
  • 4
  • 13

2 Answers2

0

I have done similar implementation with a small change. You can change implementation as follows. The public method ApplicationStarting checks that logging is enabled or not. It has decorated with with [NoEvent] which indicates SLAB not to generate an event when method is invoked. If logging is enabled then the private method will be called to write the event.

    [NonEvent]
    public void ApplicationStarting()
    {
        if (this.IsEnabled(EventLevel.Verbose, Keywords.Application))
        {
            this.ApplicationStartingImplementation();
        }
    }

    [Event(100, Level = EventLevel.Verbose, Keywords = Keywords.Application, Task = Tasks.Initialize, Opcode = Opcodes.Starting, Version = 1)]
    private void ApplicationStartingImplementation()
    {
        this.WriteEvent(100);
    }
Amit Gupta
  • 23
  • 8
  • When the check of IsEnabled is attempted inside the public method, the logic does not proceed into calling the private ApplicationStarting() method -- It seems that the setting of EventLevel.Warning overrides any other level definition. Also on a side note, when naming the public and private method the same, I get an error that the call in ambiguous and had to change the names of the method] – mgalpy Oct 19 '15 at 19:57
  • Wrote the above code for reference only which I have updated now :). The private method name has renamed to ApplicationStartingImplementation. Another point, The event level signifies the severity of an event. Lower severity levels encompass higher severity levels. For example, Warning includes the Error and Critical levels, which are higher in severity. The order of event level is Critical, Error, Warning, Informational, Verbose. – Amit Gupta Oct 20 '15 at 06:03
  • Thanks Amit :) I did not expect the fileListener (above) to log the error (since it was defined with event level of Warning), but I did expect the rollingfileListener (which is set to a log level of LogAlways with All keywords). I thought that this.IsEnabled(EventLevel.Verbose, Keywords.Application) would evaluate to true since the rollingfileListener listener is listening for those values. But it seems like just running this.IsEnabled() without any parameters "works" but is less specific in checking what log level and keywords are being listened to? – mgalpy Oct 20 '15 at 17:15
  • Just to clarify a little more, based on the listener definitions above, I expected that this.IsEnabled(EventLevel.Verbose, Keywords.Application) evaluates to true and would log to the rollingfileListener but not the fileListener. Instead this.IsEnabled(EventLevel.Verbose, Keywords.Application) evaluates to false and does not log to either the fileListener or the rollingfileListener. – mgalpy Oct 20 '15 at 17:45
0

Removing the if statement (which is checking if a particular EventLevel or Keyword IsEnabled) before calling this.WriteEvent accomplished my goal; I now have multiple sinks listening to different EventLevel's.

In my original question above, numbers 1 and 2 would stay the same, and #3 would look like this:

3) The AExpenseEvents (EventSource) method for ApplicationStarting() is:

[Event(100, Level = EventLevel.Verbose, Keywords = Keywords.Application, Task = Tasks.Initialize, Opcode = Opcodes.Starting, Version = 1)]
public void ApplicationStarting()
{
    this.WriteEvent(100);
}
mgalpy
  • 369
  • 4
  • 13