Introducing the LogScope: the cleaner way of logging and tracing methods.

6/7/2021 by Yuriy Frankiv

Introducing the LogScope: the cleaner way of logging and tracing methods.

LogScope is not yet another logger. It is an extension of existing logging libraries that provides alternative way of logging and measuring a performance of critical parts of code. It also helps building a cleaner picture of executing asynchronous calls. It can used along with any existing logging provider.

The whole idea is based on a logging scope. Based on IDisposable interface, scope:

  1. Logs it instantiation and disposal;
  2. Can log lines as part of the scope;
  3. Can be created from logging manager or as part of another scope (a nested scope);

Setup

LogScope package is available on NuGet (https://www.nuget.org/packages/DevInstance.LogScope/). The default implementation is based on simple Console.Log calls. There is an extension available for the standard Microsoft logger: https://www.nuget.org/packages/DevInstance.LogScope.Extensions.MicrosoftLogger/

So, add the package reference to your project:

PM>Install-Package DevInstance.LogScope.Extensions.MicrosoftLogger

Or

PM>Install-Package DevInstance.LogScope

We encourage people to write they own extension to the logging libraries they need. Please contribute to the open-source project: https://github.com/devInstance/LogScope.

Initialization

Initialization differs based on the type of the application and logging provider. If application uses dependency injection just call the AddConsoleScopeLogging extension method:

public void ConfigureServices(IServiceCollection services)
{
...
    services.AddConsoleScopeLogging(LogLevel.DEBUG);
...
}

For console application if can be instantiated by using DefaultScopeLogFactory directly:

var manager = DefaultScopeLogFactory.CreateConsoleLogger(LogLevel.DEBUG);

For MicrosoftLogger extension, call:

public void ConfigureServices(IServiceCollection services)
{
...
            services.AddMicrosoftScopeLogging(new DefaultFormattersOptions { ShowTimestamp = true, ShowThreadNumber = true });
...
}

Usage

Scope can be instantiated from the manager directly or from another scope. Later will create a nested scope. The following example demonstrates creation of the scope for the class directly from the manager and the nested method scopes for "MethodA" and "MethodB":

class TestClass
{
    IScopeLog classScope;

    public TestClass(IScopeManager manager)
    {
        classScope = manager.CreateLogger(this);
    }

    public void MethodA()
    {
        using (var methodScope = classScope.DebugScope())
        {
            methodScope.D("Wait for 200 msec");
            Thread.Sleep(200);
            methodScope.D("Done.");
            using (var aScope = methodScope.DebugScope("a-scope"))
            {
                aScope.D("Inside of a scope");
            }
            MethodB();
        }
    }

    private void MethodB()
    {
        using (var methodScope = classScope.DebugScope())
        {
            methodScope.D("Inside of method B scope");
            Thread.Sleep(200);
        }
    }
}

Like most of logging techniques, every scope or log line should specify a logging level. LogScope provides a set of extension methods for creating scopes and logs such as DebugScope() or TraceScope() and D() or T(). So in example above, MethodA logs few debug lines using D() then creates another nested scope “a-scope” and logs another debug line inside that scope. Then it call MethodB. Here is what will be the output:

21-01-29 23:07:24--> TestClass:MethodA
21-01-29 23:07:24    TestClass:MethodA:Wait for 200 msec
21-01-29 23:07:25    TestClass:MethodA:Done.
21-01-29 23:07:25--> TestClass:MethodA:a-scope
21-01-29 23:07:25    TestClass:MethodA:a-scope:Inside of a scope
21-01-29 23:07:25<-- TestClass:MethodA:a-scope, time:2.1252 msec
21-01-29 23:07:25--> TestClass:MethodB
21-01-29 23:07:25    TestClass:MethodB:Inside of method B scope
21-01-29 23:07:25<-- TestClass:MethodB, time:212.748 msec
21-01-29 23:07:25<-- TestClass:MethodA, time:480.5525 msec

Please refer to the documentation for more information: http://logscope.devinstance.net/