PostSharp6.3/Logging/Enabling and Disabling Logging At Run Time

Enabling and Disabling Logging At Run Time

Sometimes when an issue happens in production, you will want to enable tracing for a specific type or namespace dynamically, without rebuilding the application. To prepare for this scenario, you need to add as much logging as is reasonable at build time, but disable it by default at run time, and then enable it selectively.

This topic contains the following sections:

Enabling/disabling 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.

Note Note

PostSharp Logging does not implement a mechanism to enable or disable tracing through a configuration file. If you need to be able to configure logging without editing source code, you will have to implement yourself the code reading the configuration and calling the LoggingVerbosityConfiguration methods with proper arguments. Alternatively, you can use backend configuration mechanism (see below).

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");

Changing verbosity for the current execution context only

The DefaultVerbosity property has influence on the default execution context. To learn how to override the verbosity for a specific execution context, letting the default verbosity unchanged, see Choosing Which Requests to Log.

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