Better Stack .NET logging

Start logging in 2 minutes

Which .NET logger do you want to use to send logs to Better Stack?

Send logs to Better Stack using NLog

1. Install

Install NLog.Extensions.Logging and BetterStack.Logs.NLog packages:

Dotnet CLI
dotnet add package NLog.Extensions.Logging
dotnet add package BetterStack.Logs.NLog

Using Visual Studio?

Install packages in Tools → Manage NuGet Packages....

2. Setup

Set up NLog logging with Better Stack. Save the following config as nlog.config in your project root:

NLog config
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        autoReload="true"
        internalLogLevel="Warn"
        internalLogFile="internal.txt">
    <extensions>
        <add assembly="BetterStack.Logs.NLog" />
    </extensions>

    <targets>
        <target xsi:type="BetterStack.Logs"
            name="mybetterstack"
            layout="${message}"
            sourceToken="$SOURCE_TOKEN"
            endpoint="https://$INGESTING_HOST" />
    </targets>

    <rules>
        <logger name="*" minlevel="Trace" writeTo="mybetterstack" />
    </rules>
</nlog>


Add the following configuration to your .csproj file:

Project config
<ItemGroup>
  <None Update="nlog.config" CopyToOutputDirectory="Always" />
</ItemGroup>

Using Visual Studio?

Right-click file nlog.config → Quick Properties → Copy to Output Directory.

3. Start logging

Use NLog logger as usual:

Send logs to Better Stack
// Configures NLog to color properties based on their type, you can remove it if you don't want it
NLog.LogManager.Setup().SetupSerialization(
  setupBuilder => setupBuilder.RegisterValueFormatter(new BetterStack.Logs.NLog.ColorValueFormatter())
);

var logger = NLog.LogManager.GetCurrentClassLogger();

logger.Error("Something bad happened.");
logger.Info("Log message with structured logging. {object}", new {
  item="Orange Soda",
  price=100.00,
});
logger.Info("User has bought {item} for {price}.", "Orange Soda", 100.00);

You should see your logs in Better Stack → Live tail.
Find passed structured data under the context.properties field.

.NET Framework 4.6.2+, .NET Core 2.0+, or .NET 5+ is required

Send logs to Better Stack using Serilog

1. Install

Install Serilog.Extensions.Logging and BetterStack.Logs.Serilog packages:

Dotnet CLI
dotnet add package Serilog.Extensions.Logging
dotnet add package BetterStack.Logs.Serilog

Using Visual Studio?

Install packages in Tools → Manage NuGet Packages....

2. Configure Serilog and start logging

Use Serilog logger with configured .WriteTo.BetterStack() sink:

Send logs to Better Stack
using Serilog;

Log.Logger = new LoggerConfiguration()
    .WriteTo.BetterStack(
        sourceToken: "$SOURCE_TOKEN",
        betterStackEndpoint: "https://$INGESTING_HOST"
    )
    .MinimumLevel.Information()
    .CreateLogger();

Log.Error("Something bad happened.");
Log.Information("Log message with structured logging. {Object}", new {
  item="Orange Soda",
  price=100.00,
});
Log.Information("User has bought {Item} for {Price}.", "Orange Soda", 100.00);

Log.CloseAndFlush();


You should see your logs in Better Stack → Live tail.
Find passed structured data under the properties field.

.NET Framework 4.6.2+, .NET Core 2.0+, or .NET 5+ is required

Additional information

You can see example projects for both NLog and Serilog integration.

Configure the NLog target

Fine-tune logging with more attributes of the BetterStack.Logs target in nlog.config.

Target attributes

sourceToken
required string
endpoint
EU region string
layout
NLog default Layout
maxBatchSize
1000 int
flushPeriodMilliseconds
250 int
retries
10 int
maxFlushTimeMilliseconds
30000 int
maxQueueSize
100000 int
captureSourceLocation
true bool
includeGlobalDiagnosticContext
true bool
includeScopeProperties
false bool

Using Serilog

For logs to be sent to Better Stack reliably, Serilog must be properly closed by Log.CloseAndFlush(), even when the application ends unexpectedly. Log.CloseAndFlush() waits at most maxFlushTime, 30 seconds by default, for queued logs to be sent. For more information, see Lifecycle of Loggers in Serilog docs.

For more on Serilog configuration, see their official docs.

Configure the Serilog sink

Fine-tune logging with more arguments of .WriteTo.BetterStack().

Sink options

sourceToken
required string
betterStackEndpoint
EU region string
outputTemplate
string
formatProvider
IFormatProvider
restrictedToMinimumLevel
Verbose LogEventLevel
levelSwitch
LoggingLevelSwitch
batchSize
1000 int
batchInterval
1 second TimeSpan
queueLimitBytes
300 MB long
retries
10 int
maxFlushTime
30 seconds TimeSpan
httpClientHandler
HttpClientHandler

To configure the sink in appsettings.json instead, install the Serilog.Settings.Configuration package and read the configuration with .ReadFrom.Configuration():

appsettings.json
{
  "Serilog": {
    "WriteTo": [
      {
        "Name": "BetterStack",
        "Args": {
          "sourceToken": "$SOURCE_TOKEN",
          "betterStackEndpoint": "https://$INGESTING_HOST",
          "outputTemplate": "[{Level:u3}] {SourceContext} - {Message:lj}",
          "maxFlushTime": "00:00:30",
          "retries": 10
        }
      }
    ]
  }
}


Need help?

Please let us know at hello@betterstack.com.
We're happy to help! 🙏