PostSharp 6.9 / / Post­Sharp Documentation / Logging / Adjusting Logging Verbosity / Adjusting Logging Verbosity Programmatically

Adjusting Logging Verbosity Programmatically

If configuring verbosity using an XML file does not fit your scenario, you can do it using normal API calls. This article describes how.

This topic contains the following sections:

Enabling/disabling logging with the PostSharp Logging API

To tune the logging verbosity for a specific type or namespace, first get the default LoggingVerbosityConfiguration by evaluating the DefaultVerbosity property, then use one of the SetMinimalLevel(), SetMinimalLevelForType() or SetMinimalLevelForNamespace() method.

The default logging level is Debug.

Example

The following code will cause PostSharp to log only exceptions for the MyCompany namespace and at the same time all messages for the MyCompany.BusinessLayer namespace. The order of the two lines of code is important.

C#
LoggingServices.DefaultBackend.DefaultVerbosity.SetMinimalLevelForNamespace(LogLevel.Error, "MyCompany");
LoggingServices.DefaultBackend.DefaultVerbosity.SetMinimalLevelForNamespace(LogLevel.Debug, "MyCompany.BusinessLayer");
Configuring verbosity for the current execution context only

In the above section, you have configured verbosity through the DefaultVerbosity property. This property gives you access to the configuration of verbosity for the default execution context only. However, you can override verbosity for any execution context, for instance for a specific web request.

To selectively enable logging for the current execution context

  1. Disable detailed logging at global level.

    C#
    LoggingServices.DefaultBackend.DefaultVerbosity.SetMinimalLevel( LogLevel.Warning );
  2. Create a LoggingVerbosityConfiguration by calling the CreateVerbosityConfiguration() method. This LoggingVerbosityConfiguration will be used by all requests where you want to enable logging. Store it in a field. Note that the LoggingVerbosityConfiguration is a memory-heavy type, so you should avoid creating one instance for every request.

    By default, the verbosity is set to Debug. You can configure the LoggingVerbosityConfiguration as needed, for instance using SetMinimalLevelForNamespace(LogLevel, String).

    C#
    highVerbosity = backend.CreateVerbosityConfiguration();
  3. Intercept the request before it is passed to your application code (typically using an ASP.NET Action Filter or a WCF Behavior), decide whether the request should be logged, and call the LoggingVerbosityConfiguration.Use() method. Dispose the returned token once the request processing has completed.

    C#
    using ( IsInterestingRequest(request) ? this.highVerbosity.Use() : null )
    {
       // Process the transaction here.
    }
Enabling/disabling with the backend API

Several logging frameworks offer a configuration mechanism that allows you to enable or disable logging. For a PostSharp log record to be emitted, two conditions need to be met: logging must be enabled by PostSharp (see above) and by the backend logging framework.

Logging frameworks generally have a concept of a category or of a source (the terminology can vary), which typically is just determined by a string (typically a type or a namespace). The corresponding concept in PostSharp Logging is the LoggingTypeSource class, which is determined by two strings: a role (see LoggingRoles) and a type name or namespace.

By default, a LoggingTypeSource is mapped to a category according to the full type name. If you want to control logging using the backend framework, you will need to customize this mapping. This can be done by setting a property of the LoggingBackendOptions class. This property is different for each backend framework.

Therefore, you enable or disable logging using the facilities implemented by the backend logging framework, using the full type name as the source or category name.

Optimizing the execution time when logging is disabled

By default, PostSharp generates code that allows you to dynamically enable or disable logging for a specific type and severity. However, even if logging is disabled, your CPU still needs to execute the code that evaluates whether logging is enabled.

By setting the AllowDynamicEnabling property of the logging profile to false, you can ask PostSharp to generate instructions that can be fully eliminated by the JIT compiler when logging is disabled. Therefore, the cost of inactive logging will be close to zero. Note that our last tests show that the JIT compiler still emits instructions when logging is disabled, but it emits the equivalent of if ( false ) { Log; }, which has a very low performance overhead because of branch prediction.

When you set the AllowDynamicEnabling property to false, you need to configure the LoggingVerbosityConfiguration object when the application initializes. Any change done after a logged type is JIT-compiled will be ignored for this specific type.

Example

The following postsharp.config enables the JIT-compiler optimizations for the default profile.

XML
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
  <Logging xmlns="clr-namespace:PostSharp.Patterns.Diagnostics;assembly:PostSharp.Patterns.Diagnostics">
    <Profiles>
      <LoggingProfile Name="default" AllowDynamicEnabling="False"/>
    </Profiles>
  </Logging>
</Project>