LogoLogo
HomePricingDocumentation
  • 💿Getting Started
    • Installation and Project Setup
    • Hello Perigee!
    • Perigee Application Design
    • Hello Configuration
    • Hello Logs
    • Hello Integration
    • Troubleshooting
    • Case Studies
  • 📃License + Notice
    • 📂Licensing
    • Notice of Third Party Agreements
  • 🚀Perigee and Beyond
    • Extending - Threads
    • Extending - Loaders
    • ⏳All about CRON
  • 🔮API Generation
    • What is API Generation?
    • API Builder
  • 🗺️Architecting YOUR App
    • Design and Requirements
    • Define Sources
    • Requirements
  • 🧩Core Modules
    • 🌐PerigeeApplication
    • 🪡Thread Registry
    • Event Sources
      • Scheduled/Logic
        • CRON Thread
        • Scheduler
        • Sync Agent
      • Watchers
        • SalesForce
        • Sharepoint
        • Directory Watch
        • Directory Notifier
        • IMAP
    • Credential Management
      • Connection Strings
      • Custom Refresh Logic
      • RestSharp Authenticator
      • Credential Store SDK
      • ⁉️Troubleshooting Credentials
    • Integration Utilities
      • HTTP(S) - RestSharp
      • Transaction Coordinator
      • Limiter
      • Watermarking
    • Alert Managers
      • SMS
      • Email
      • Discord
      • Teams
    • File Formats
      • Excel
      • CSV
    • 📁File System Storage
      • File Revision Store
      • Concurrent File Store
      • FileSync + Cache
    • Third Party
      • SmartSheets
      • Microsoft Graph
    • Perigee In Parallel
      • Parallel Processing Reference
      • Extensions
      • GroupProcessor
      • SingleProcessor
    • 🧱Utility Classes
      • Metrics
      • F(x) Expressions
      • Multi-Threaded Processor (Scatter Gather)
      • OpenAI - GPT
      • XML Converter
      • Dynamic Data Table
      • Debounce
      • Thread Conditions
      • Perigee Utility Class
      • Network Utility
      • Lists
      • FileUtil
      • Inclusive2DRange
      • Strings, Numbers, Dates
      • Nested Sets
      • Behavior Trees
      • JsonCompress
      • Topological Sorting
      • DBDownloader
    • 🈁Bit Serializer
  • 📣Examples and Demos
    • API + Perigee
    • 📰Excel Quick Load
    • SalesForce Watcher
    • Report Scheduler
    • Agent Data Synchronization
    • 📩IMAP Echo bot
    • Watch and load CSVs
    • Graph Delegated Authorization + DataVerse
    • Coordinator Demo
    • Azure Service Bus
    • QuickBooks Online
  • 📘Blueprints
    • Perigee With .NET Hosting
    • Web Host Utilities
    • 🔌Plugin Load Context
  • 🎞️Transforms
    • 🌟What is Transforms?
    • 📘Terminology
    • 🦾The Mapping Document
    • 👾Transformation Process
    • 😎Profile
    • 🎒Automation
      • 🕓Package Options
      • 🔳Configuration
    • 🔧Utilities
      • 🧹Clean
      • 📑Map File
      • 🔎File Identification
      • 🗺️Map Generation
      • 🪅Insert Statement Generation
  • 🗃️Transform SDK
    • 👋Quick Start Guide
    • 🥳MapTo
    • 🔌Authoring Plugins
      • 🔘File IO Process
      • 📢Data Quality
      • 🟢Transform Process
    • SDK Reference
      • 🔘FileIOProcessData
      • 📢DataQualityContext
      • 🎛️TransformDataContext
      • 🏅TransformResult
Powered by GitBook
On this page
  • Logging Introduction
  • Log Sinks
  • Configure logs
  • Configuration - With Hosting
  • Perigee Logging
  • Getting a logger directly
  • Log Scopes
Export as PDF
  1. Getting Started

Hello Logs

PreviousHello ConfigurationNextHello Integration

Last updated 2 months ago

Logging Introduction

When building an application it is very important to have information communicated clearly about what is going on inside your application. Whether this is a success message or a critical failure that needs someones attention.

We use behind the scenes. So any configuration you can perform with , also applies here.

Log Sinks

Serilog can output it's data to all kinds of sources. The console, Azure, Amazon, Elastic, Log4Net, Loggly, NLog, SQL Server, file... just to name a few. These sources are called Log Sinks.

Any time a sink is added to the configuration, all logging within Perigee automatically sends it's log data to the configured sources. This simple configuration strategy makes it incredibly easy to send log data wherever you need it.

Configure logs

We recommend doing most of this configuration within the appsettings.json file, so let's take a look at configuring a simple logger.

In the we configured the console sink to have a different logging template. using the following section of code:

{
    "Serilog": {
        "MinimumLevel": "Debug",
        "WriteTo": [
            {
                "Name": "Console",
                "Args": {
                    "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}]({ThreadName}) {Message:lj}{NewLine}{Exception}"
                }
            }
        ]
    }
}

The first tag, MinimumLevel - This describes what events get emitted to the sinks. At Debug, anything logged at the Verbose level is ignored. It's great for controlling what types of messages are visible.

The seconds tag, WriteTo is the array of configured logging sinks. You can control these sinks with the various settings they accept and can be found on the Serilog Sink Configuration page for the given sink.

If you configure another sink like the Microsft SQL Server sink, don't forget to also add the relevent nuget package to your project or it will be ignored!

1) Add the appropriate object to the AppSettings.Serilog.WriteToarray:

{ "Name": "MSSqlServer", ...}

2) Install the package with Nuget:

Install-Package Serilog.Sinks.MSSqlServer

3) You're now ready to log away as usual!

Configuration - With Hosting

The hosting configuration also includes a few additional keys, let's take a look here:

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning",
        "Microsoft.AspNetCore": "Warning"
      }
    },
    "WriteTo": [
      { "Name": "Console" }
    ]
  }
}

This time, the MinimumLevel is an object, not a string. This allows us to set the default logging level, as well as override the logging levels for several other namespaces.

The overrides supplied here will squash the incredible amount of information being logged from ASPNetCore hosting by default.

Perigee Logging

Logging is built throughout Perigee. Any thread that is managed and created is automatically sent a logger with the appropriate configurations.

PerigeeApplication.ApplicationNoInit("DemoApp", (c) =>
{
    c.AddRecurring("Recurring Task" (ct, l) => {
    
        l.LogInformation("See how this Thread is automatically sent a logger?");
    
    });
});

Getting a logger directly

We can easily get a logger directly from the ThreadRegistry any time we want outside of a ManagedThread. This logger is tied into the Serilog system and will automatically inherit the configuration defined.

PerigeeApplication.ApplicationNoInit("DemoApp", (c) =>
{
    //Get a logger from the ThreadRegistry
    c.GetLogger<Program>();
    
});

Log Scopes

As shown above, you can override the logging template with additional parameters. Here we've added the ThreadName to the logging template. The reason this works out of the box is because Perigee's internal thread management system injects this log scope before sending an ILogger back.

You can add as many custom log scopes as you need. They will appear differently for different log sinks. This is very helpful when adding a BatchID, CorrelationID, SystemID, NetworkID or other identifying information to the log request.

  • If logging to a database with an additional column added to the logging table - any matching log scope will fill that column value

  • If logging to something like Splunk, you'll see those log scopes present in the additional log data

  • If an overriden template in the console logger includes the custom scope, it will be written when present

Scope demo

Make sure to setup your appsettings.json with the modified logging template:

{
    "Serilog": {
        "MinimumLevel": "Debug",
        "WriteTo": [
            {
                "Name": "Console",
                "Args": {
                    "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}]({ThreadName}) {Message:lj}{NewLine}{Exception}"
                }
            }
        ]
    }
}

Then add a simple recurring method and override the ThreadName supplied by Perigee:

PerigeeApplication.ApplicationNoInit("Scopes", (c) =>
{
    c.AddRecurring("RecurringLogger", (ct, l) => {

        //Begin a new log scope on this logger, overriding the ThreadName
        using var scopes = l.BeginScope(new Dictionary<string, object> { { "ThreadName", "CUSTOMIZED" } });

        //Anything now logged from here will have it's "ThreadName" set to "CUSTOMIZED"
        l.LogInformation("See the overriden thread name?");

    });
});

The output will look like this:

[15:09:16 INF](CUSTOMIZED) See the overriden thread name?

Want to see more information about ?

Serilog
Serilog
Hello Configuration Section
💿
Page cover image
perigee application design