LogScope .NET Standard 2: Logging, tracing and profiling

Overview

LogScope is a supplemental library that extends the logging function by implementing logging scope. Current version supports the logging to the system console only but be extensible to support any other logging solutions like log4net, NLog, etc. To keep things simple, it consists of three components: Provider, Formatter and Manager. Manager creates logging scopes, passing the implementation of the provider ILogProvider and formatter IScopeFormater. Provider implements the actual logging function and formatter oversees formatting message line. The library includes console provider and default formatter.

Installation

LogScope is available in NuGet package manager: https://www.nuget.org/packages/DevInstance.LogScope/ or https://www.nuget.org/packages/DevInstance.LogScope.NET/

Power shell:

.Net Standard 2.0:

dotnet add package DevInstance.LogScope

.Net 6.0:

dotnet add package DevInstance.LogScope.NET

Package manager:

.Net Standard 2.0:

Install-Package DevInstance.LogScope

.Net 6.0:

Install-Package DevInstance.LogScope.NET

Setup

The first step is using ScopeLogFactory to instantiate a manager. For instance, logging to the console with debug level, manager can be instantiated using:

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

Also, you can provide additional parameters the formatter by:

var manager = ScopeLogFactory.CreateConsoleLogger(LogLevel.DEBUG, new DefaultFormaterOptions { ShowTimestamp = true, ShowThreadNumber = true });

If you need to provide custom log provider or formatter:

var manager = ScopeLogFactory.Create(LogLevel.DEBUG, customProvider, customrFormater);

For ASP.NET Core applications or WebAsembly, DevInstance.LogScope.NET package provides extensions to add manager to Service collection (IServiceCollection):

services.AddConsoleLogging(LogLevel.INFO); 

Usage scenario

The whole idea is around using a "scope". Scope can be method or a specific part of it. The implementation is based on IDisposable where calling Dispose ends the scope. To understand how it works, let's look into the following example. Let's define a simple class:

class TestClass
{
        IScopeLog log;

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

        public void MethodFoo()
        {
            using (var methodScope = log.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");
                }
            }
        }
    }

... and instantiate it:

new TestClass(manager).MethodFoo();

Here the result in the log:

-->TestClass:MethodFoo
        TestClass:MethodFoo:Wait for 200 msec
        TestClass:MethodFoo:Done.
-->TestClass:MethodFoo:a-scope
        TestClass:MethodFoo:a-scope:Inside of a scope
<--TestClass:MethodFoo:a-scope, time:0.52 msec
<--TestClass:MethodFoo, time:211.0924 msec

As you can see, there are three scopes in this example: TestClass (created in the constructor), MethodFoo and a local scope "a-scope". Every logging line contains the "scope path" (e.g "TestClass:MethodFoo:a-scope") as well as "-->" begin and end "<--" of every scope. Knowing the scope's being and end can be useful when analyzing asynchronous parts of the code.

Documentation

Please check API reference

  • Improve this Doc
In This Article
Back to top Generated by DocFX