Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: NLog support #993

Merged
merged 5 commits into from
May 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions __tests__/__snapshots__/documentation.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ Array [
"platforms/dotnet/index.html",
"platforms/dotnet/log4net/index.html",
"platforms/dotnet/microsoft-extensions-logging/index.html",
"platforms/dotnet/nlog/index.html",
"platforms/dotnet/serilog/index.html",
"platforms/index.html",
"platforms/javascript/advance-settings/index.html",
Expand Down
173 changes: 173 additions & 0 deletions src/collections/_documentation/platforms/dotnet/nlog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---
title: NLog
sidebar_order: 13
---

Sentry has an integration with `NLog` through the [Sentry.NLog NuGet package](https://www.nuget.org/packages/Sentry.NLog).

## Installation

Using package manager:

```powershell
Install-Package Sentry.NLog -Version {% sdk_version sentry.dotnet.nlog %}
```

Or using the .NET Core CLI:

```sh
dotnet add package Sentry.NLog -v {% sdk_version sentry.dotnet.nlog %}
```

This package extends `Sentry` main SDK. That means that besides the logging related features, through this package you'll also get access to all API and features available in the main `Sentry` SDK.

> NOTE: Messages logged from assemblies with the name starting with `Sentry` will not generate events.

## Features

* Store log messages as breadcrumbs
* Send events to sentry

Two separate settings define the minimum log level to keep the log entry as a `Breadcrumb` and to send an `Event` to Sentry. The events include any stored breadcrumb on that [scope]({% link _documentation/enriching-error-data/scopes.md %}).

By default, Sentry will keep any message with log level `Info` or higher as a `Breadcrumb`.

The default value to report a log entry as an event to Sentry is `Error`.

This means that out of the box, any `Error` call will create an `Event` which will include all log messages of level `Info`, `Warn` and also `Error` and `Critical`.


## Configuration

You can configure the Sentry NLog target via code as follows:

```csharp
LogManager.Configuration = new LoggingConfiguration();
LogManager.Configuration
.AddSentry(o =>
{
// Optionally specify a separate format for message
o.Layout = "${message}";
// Optionally specify a separate format for breadcrumbs
o.BreadcrumbLayout = "${logger}: ${message}";

// Debug and higher are stored as breadcrumbs (default is Info)
o.MinimumBreadcrumbLevel = LogLevel.Debug;
// Error and higher is sent as event (default is Error)
o.MinimumEventLevel = LogLevel.Error;

// Send the logger name as a tag
o.AddTag("logger", "${logger}");

// All Sentry Options are accessible here.
});
```

It's also possible to initialize the SDK through the NLog integration (as opposed to using `SentrySdk.Init`).
This is useful when NLog is the only integration being used in your application. To initialize the Sentry SDK through the NLog integration, provide it with the DSN:

```csharp
LogManager.Configuration = new LoggingConfiguration();
LogManager.Configuration
.AddSentry(o =>
{
// The NLog integration will initialize the SDK if DSN is set:
o.Dsn = new Dsn("___PUBLIC_DSN___"));
});
```

> NOTE:
The SDK only needs to be initialized once. If a `DSN` is made available to this integration, by default it **will** initialize the SDK. If you do not wish to initialize the SDK via this integration, set the `InitializeSdk` flag to **false**. Not providing a DSN or leaving it as `null` instructs the integration not to initialize the SDK and unless another integration initializes it or you call `SentrySdk.Init`, the SDK will stay disabled.

> Minimum log level
Two log levels are used to configure this integration (see options below). One will configure the lowest level required for a log message to become an event (`MinimumEventLevel`) sent to Sentry. The other options (`MinimumBreadcrumbLevel`) configures the lowest level a message has to be to become a breadcrumb. Breadcrumbs are kept in memory (by default the last 100 records) and are sent with events. For example, by default, if you log 100 entries with `logger.Info` or `logger.Warn`, no event is sent to Sentry. If you then log with `logger.Error`, an event is sent to Sentry which includes those 100 `Info` or `Warn` messages. For this to work the `SentryTarget` needs to receive all log entries in order to decide what to keep as breadcrumb or sent as event. Make sure to set the `NLog` `LogLevel` configuration to a value lower than what you set for the `MinimumBreadcrumbLevel` and `MinimumEventLevel` to make sure `SentryTarget` receives these log messages.


The SDK can also be configured via `NLog.config` XML file:

```xml
<?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"
>
<extensions>
<add assembly="Sentry.NLog" />
</extensions>

<targets>
<target xsi:type="Sentry" name="sentry"
dsn="___PUBLIC_DSN___"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I just thought of is that I specified that the Dsn is specified as a required parameter in the SentryTarget, which means that if a sentry target is defined in the NLog.config file without a dsn specified, it will probably not register the target correctly.

I'd have to test it to verify that, but that could cause issues if people want to set the dsn another way. So that should either be documented here or else changed on the target, which I'm happy to do if you think that's the better option.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. We should make this not required then. Firstly because the lack of DSN means don't initialize Sentry at all but also because It's important to make it possible for integration not to initialize the SDK. The canonical way to init any Sentry SDK from the unified API is via Sentry.Init so allowing an integration initialize the SDK is just a convenience for those who use a single integration. It also helps making things idiomatic.

Could you please modify the integration to make DSN optional?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do. I should be able to send a PR this weekend.

layout="${message}"
debug="true"
breadcrumbLayout="${message}"
minimumBreadcrumbLevel="Debug"
minimumEventLevel="Error">

<!-- Advanced options can be configured here-->
<options
environment="Development"
attachStacktrace="true"
sendDefaultPii="true"
shutdownTimeoutSeconds="5"
>
<!--Advanced options can be specified as attributes or elements-->
<includeEventDataOnBreadcrumbs>true</includeEventDataOnBreadcrumbs>
</options>

<!--Add any desired additional tags that will be sent with every message -->
<tag name="logger" layout="${logger}" />
<tag name="example" layout="sentry-nlog" />
</target>
</targets>

<rules>
<logger name="*" writeTo="sentry" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that might be good to super clarify is that as of now, it doesn't use the standard NLog way of specifying the log level.

For example, you typically you set the minlevel on the rule for the lowest rule you want to be logged, but here there are the MinimumEventLevel and MinimumBreadcrumbLevel in addition to the standard. I think it's pretty straight forward and it is explained in these docs, but it might be good to draw attention to this difference here, e.g.:

<!--
      NOTE: If the `minlevel` for the logger is higher than `MinimumBreadcrumbLevel`, those messages 
      won't be added as breadcrumbs.

      Set the minlevel as low as possible to allow all messages to 
      pass through sentry target, and configure levels for breadcrumbs and events above.
-->
<logger name="*" writeTo="sentry" />
<!-- The above is equivalent to <logger name="*" minlevel="Trace" writeTo="sentry"/> -->

It could be worded however, but I think it would be good to make sure that is super duper clear so people can make sure their breadcrumbs are sent to sentry correctly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a note about this. I tried to be detailed on how it works but still seems confusing. Would appreciate some suggestions.
Or feel free to make a PR on this branch too if you wish :)

</rules>
</nlog>
```

### Options

#### MinimumBreadcrumbLevel

A `LogLevel` that indicates the minimum level a log message needs to be in order to become a breadcrumb. By default, this value is `Info`.

#### MinimumEventLevel

A `LogLevel` which indicates the minimum level a log message has to be sent to Sentry as an event. By default this value is `Error`.

#### InitializeSdk

Whether or not this integration should initialize the SDK. If you intend to call `SentrySdk.Init` yourself you should set this flag to `false`.

#### IgnoreEventsWithNoException

To ignore log messages that don't contain an exception.

#### SendEventPropertiesAsData

Determines whether event-level properties will be sent to sentry as additional data. Defaults to true.

#### SendEventPropertiesAsTags

Determines whether event properties will be sent to sentry as Tags or not. Defaults to false.

#### IncludeEventDataOnBreadcrumbs

Determines whether or not to include event-level data as data in breadcrumbs for future errors. Defaults to false.

#### BreadcrumbLayout

Custom layout for breadcrumbs. See [NLog layout renderers](https://nlog-project.org/config/?tab=layout-renderers) for more.

#### Layout

Configured layout for the NLog logger.

#### Tags

Any additional tags to apply to each logged message.

### Samples

* A [simple example](https://github.com/getsentry/sentry-dotnet/tree/master/samples/Sentry.Samples.NLog).