Table of Contents

Logging

This tutorial will teach you the basics of logging in your services.

Prerequisites

  1. Windows 10/11
  2. Visual studio 2019/2022
  3. Phoesion Glow Blaze , with Reactor running (see getting started guide)

Sample Code

You can download the Sample Code archive from the downloads section.
This tutorial follows the 0b_Logging sample in the archive. (View code on GitHub)

Introduction

Phoesion Glow provides you with a complete build-in logging solution, that includes both producing logs from your services and consuming them using the Blaze UI. The logging framework is based on the Microsoft.Extensions.Logging framework, so if you need more in-depth information you can read the Logging in .NET documentation

Loggers

FireflyModules automatically create an ILogger<> with the correct module category, so you can simply use it like so :

[Action(Methods.GET)]
public void MyAction()
{
    logger.LogDebug("This is a simple DEBUG message");
}

for other classes that will be instantiated using Dependency-injection, you need to request a logger like so :

class MyClass
{
    readonly ILogger logger;

    public MyClass(ILogger<MyClass> _logger)
    {
        this.logger = _logger;
    }
}
Note

Make sure you have using Microsoft.Extensions.Logging; to enable the logging extensions (eg logger.LogDebug())

Producing logs

1. Simple Logs

You can log a simple message with a specific LogLevel :

logger.LogDebug("This is a simple DEBUG message");
logger.LogInformation("This is a simple INFORMATION message");
logger.LogWarning("This is a simple WARNING message");

2. Logs with variables (structured logging)

Structured logging makes it easier to store and query log-events.

logger.LogInformation("Logon by user:{username} from ip_address:{ip}", "Kenny", "127.0.0.1");
logger.LogInformation("Shopitem:{item} added to basket by user:{user}", item.Name, user.Name);

3. Exceptions

You can log an exception as error using :

try
{
    //...
}
catch (Exception ex)
{
    logger.LogError(ex, "Unhandled exception caught");
}

The exception message, stack trace and any inner-exceptions will be recorder for later examination.

4. Scopes

When performing your business logic actions, you can create a logging scope to group all the log messages that will be produced until the scope is disposed

[Action(Methods.GET)]
public string CreateScopedLog()
{
    logger.LogInformation("Entering CreateScopedLog()");

    //create a scope
    using (logger.BeginScope("Performing migrations on user {username}", "john"))
    {
        logger.LogInformation("Log within the scope");
        logger.LogInformation("Another log within the scope");

        //create a inner scope
        using (logger.BeginScope("Converting user files"))
        {
            logger.LogInformation("converting file 1");
            logger.LogInformation("converting file 2");
            logger.LogInformation("converting completed");
        }
        
        //create a inner scope
        using (logger.BeginScope("Converting user emails"))
        {
            logger.LogInformation("converting email 1");
            logger.LogInformation("converting email 2");
            logger.LogInformation("converting completed");
        }
        
        logger.LogInformation("Another log within the first scope");
    }
        
    logger.LogInformation("Finished CreateScopedLog()");
    return "done!";
}

Rays - the request logging context

Each incoming request entering your cloud (through prism) will generate a new Ray, that will be used as the context container throughout the handling of the request. A Ray will persist across requests from entity-to-entity and service-to-service and all logs produced by each entity/service will be registered in the context of the Ray. This is a very useful feature when you will be examining the logs, since from the Blaze UI all logs will be collected and grouped together so you can easily examine the propagation of the request in the system and your services.

Examine logs

You can examine the logs produced by your service using Phoesion Glow Blaze log viewer UI.
To see logs, connect with Blaze to your Lighthouse, and select your Quantum Space. Then from the Quantum-Space dashboard you can click the Logs button to open the logs dashboard.

Blaze_Dashboard

1. Dashboard overview

In the Log Dashboard you can see all the Rays that produced log messages (Left), a variety of filtering tools (Top) and the Ray Inspector (Right) for examining the ray logs Blaze_Logs_Dashboard

2. Viewing Exceptions

When a log message is an error with an exception you can click on the red bug icon Blaze_Logs_Dashboard_ExceptionIcon

to open the Exception Viewer Blaze_ExceptionViewer

Creating a Ray Logging context programmatically

When a new request arrives at the Prism it will automatically generate a new Ray to handle it, but in many occasions you may have a Worker/HostedService or other business logic in your service from which you need to start a new context/scope to properly handle it. You can create a new Ray from a logger like so :

using (logger.CreateRayScope())
{
    //... handle event ...
}
Tip

The correct use of handling external requests is demonstrated in the ExternalEventConsumer Sample

Testing the sample

After you deploy the 0b_Logging sample you can test it using the following paths (assuming local deployment) :

Note

To see the logs from Blaze you need to deploy the sample to a Quantum Space and not just run it using the debugger in Visual studio