Enable Logs-in-context with Serilog

BETA

New Relic offers a Serilog extension to connect your log data to New Relic Logs-in-context for .NET, allowing you link to your log data with related data across the rest of the New Relic platform. This document explains how to enable this feature and get started using it.

New Relic's logs-in-context (linking logs directly to Applications, APM errors, and APM traces and spans) for New Relic Logs is currently available as a beta feature. Your use of the early access service is at your own risk. New Relic disclaims all warranties, express or implied, regarding the beta services.

Compatibility and Requirements

To use New Relic Logs-in-context with Serilog, ensure your configuration meets the following requirements:

New Relic Logs must be enabled prior to enabling logs-in-context. For more information, see Introduction to New Relic Logs.

Overview

Serilog is a structured logging framework that records log messages from your application and creates a LogEvent to store the message data. Using Enrichers, you can add additional information to the log events, while Sinks and Formatters allow you to format and output those log events for downstream consumption and viewing.

This diagram illustrates the flow of log messages through Serilog.

Logs-in-context Serilog
This diagram illustrates the flow of log messages through Serilog, highlighting specific components of the New Relic Serilog extension.

The above diagram highlights several components of the Serilog extension:

  • New Relic Enricher: The NewRelicEnricher adds contextual information from the .NET Agent (using the API) to the log events generated by the application. This contextual information, known as linking metadata, is used by New Relic to link log messages to the transactions and spans from which they were created.

  • New Relic Formatter: The NewRelicFormattertranslates enriched log events into the JSON format expected by New Relic. A sink instructs Serilog to output the JSON to a file in the location that the Log Forwarder expects.

  • New Relic Log Forwarder: The NewRelicFormattertranslates enriched log events into the JSON format expected by New Relic. A sink instructs Serilog to output the JSON to a file in the location that the log forwarder expects. The example below uses the New Relic Fluentd log forwarded, however there are many other log forwarders that can be used. For more information, see Introduction to New Relic Logs.

For more information about Serilog log events, see the Serilog Getting started documentation.

Enable logs-in-context with New Relic Logs

To enable New Relic logs-in-context with Serilog:

  1. Install or update the .NET agent.
  2. Enable and configure the Serilog extension.
  3. Check for logging data.

Install or update the .NET agent

Install or update to the most recent .NET agent version, and enable Distributed tracing.

Enable and configure the Serilog extension

To enable logs-in-context with the Serilog extension, complete the following steps:

  1. Using the Visual Studio NuGet Package Manager, locate and install the NewRelic.LogEnrichers.Serilog package.

  2. In your application code, update your logging configuration to add the NewRelicEnricher and NewRelicFormatter.

    The following code example enriches log events with New Relic linking metadata. In addition to the existing log files, it outputs new log files in a specific JSON format at C:\logs\SerilogExample.log.json for consumption by the Log Forwarder:

     var loggerConfig = new LoggerConfiguration()
            
     loggerConfig
        .Enrich.WithThreadName()
        .Enrich.WithThreadId()    
        .Enrich.WithNewRelicLogsInContext()
        .WriteTo.File( path: @"C:\logs\ExistingLoggingOutput.txt")
        .WriteTo.File(
            formatter: new NewRelicFormatter(), 
            path: @"C:\logs\SerilogExample.log.json");
    
     var log = loggerConfig.CreateLogger();
    

    The above configuration results in new JSON files that are written to disk. Some of these configuration options may be useful in managing the amount of disk space used and/or the performance of the sink.

    • restrictedToMinimumLevel
    • buffered
    • rollingInterval
    • rollOnFileSizeLimit
    • retainedFileCountLimit

    Though not required, using the Serilog Asynchronous Sink Wrapper may help improve the performance by performing formatting and output of log files on a different thread.​

  3. Once you have enabled the Serilog extension and updated your logging file, you can configure your extension to send data to New Relic Logs. See below for an example of this configuration using the Fluentd plugin for New Relic Logs:

    <!--NewRelicLoggingExample.conf-->
    <source> 
        @type tail 
        path C:\logs\SerilogExample.log.json
        pos_file C:\logs\SerilogExample.log.json.pos 
        tag logfile.*
     <parse> 
        @type json 
    </parse>
    </source>
    <match **> 
        @type newrelic 
        license_key <YOUR NEW_RELIC_LICENSE_KEY>
        base_uri https://log-api.newrelic.com/log/v1
    </match>

File Based Configuration

Configuration of the New Relic Logs Serilog extension may also be accomplished with file based configuration providers.

appsettings.json based configuration

The example code below creates a logger based on settings contained in an appSettings.json file.

The following additional NuGet Packages are required:

Instantiating Logger using appsettings.json

var builder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json");
        
var configuration = builder.Build();

var logger = new LoggerConfiguration()
        .ReadFrom.Configuration(configuration)
        .CreateLogger();

Sample appsettings.json file

{
  "Serilog": {
    "Using": [ 
          "Serilog.Sinks.Console",
          "Serilog.Sinks.File",
          "NewRelic.LogEnrichers.Serilog" 
    ],
    "MinimumLevel": "Debug",
    "Enrich": [ "WithNewRelicLogsInContext" ],
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "C:\\Logs\\SerilogExample.log.json",
          "formatter": "NewRelic.LogEnrichers.Serilog.NewRelicFormatter, NewRelic.LogEnrichers.Serilog"
          }
      }
    ],
    
    "Properties": {
      "Application": "NewRelic Logging Serilog Example"
    }
  }
}
.Config based configuration

The example code below creates a logger based on settings contained in an web.config file.

The Serilog.Settings.AppSettings NuGet Package is required.

Instantiating Logger using .config file

var logger = new LoggerConfiguration()
    .ReadFrom.AppSettings()
    .CreateLogger();

Sample web.config file

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="serilog:using:NewRelic" value="NewRelic.LogEnrichers.Serilog" />
    <add key="serilog:using:File" value="Serilog.Sinks.File" />
    <!--Add other enrichers here-->
    <add key="serilog:enrich:WithNewRelicLogsInContext" />
    <add key="serilog:write-to:File.path" value="C:\logs\SerilogExample.log.json" />
    <add key="serilog:write-to:File.formatter" value="NewRelic.LogEnrichers.Serilog.NewRelicFormatter, NewRelic.LogEnrichers.Serilog" />
  </appSettings>

What's next?

Now that you've enabled logs-in-context, here are some potential next steps:

For more help

Recommendations for learning more: