https://github.com/airbrake/sharpbrake
Airbrake Notifier for .NET
https://github.com/airbrake/sharpbrake
airbrake c-sharp crash-reporting dotnet error-monitoring
Last synced: 5 months ago
JSON representation
Airbrake Notifier for .NET
- Host: GitHub
- URL: https://github.com/airbrake/sharpbrake
- Owner: airbrake
- License: mit
- Created: 2011-06-24T09:07:48.000Z (over 14 years ago)
- Default Branch: master
- Last Pushed: 2022-12-07T19:19:19.000Z (about 3 years ago)
- Last Synced: 2025-06-09T19:09:03.535Z (7 months ago)
- Topics: airbrake, c-sharp, crash-reporting, dotnet, error-monitoring
- Language: C#
- Homepage:
- Size: 1.36 MB
- Stars: 79
- Watchers: 9
- Forks: 15
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
README
Sharpbrake
==========
[](https://ci.appveyor.com/project/airbrake/sharpbrake/branch/master)
[](https://codecov.io/gh/airbrake/sharpbrake)
* [Example apps](https://github.com/airbrake/sharpbrake/tree/master/examples)
Introduction
------------
[Airbrake](https://airbrake.io) is an online tool that provides robust error
tracking in most of your C#/.NET applications. In doing so, it allows you to
easily review errors, tie an error to an individual piece of code, and trace the
cause back to recent changes. The Airbrake dashboard provides easy
categorization, searching, and prioritization of errors so that when they
occur, your team can quickly determine the root cause.
Sharpbrake is a C# notifier library for Airbrake. It provides minimalist API to
send C# exceptions and error messages to the Airbrake dashboard. The library
perfectly suits any type of C# applications.
Key features
------------
* Uses the new Airbrake JSON
(v3)[[link](https://airbrake.io/docs/#create-notice-v3)]
* SSL support (all communication with Airbrake is encrypted by default)
* Support for .NET 4.5.2 and above (including the latest .NET Core platforms)
[[net35](#net-35-support)]
* Asynchronous error reporting[[link](#notify)]
* Logging support[[link](#logfile)]
* Flexible configuration options (configure as many Airbrake notifiers in one
application as you want)[[link](#configuration)]
* Support for environments[[link](#environment)]
* Support for proxying[[link](#proxy)]
* Filters support (filter out sensitive or unwanted data that shouldn't be sent
to our servers)[[link](#blocklist)]
* Ability to ignore errors from specified environments[[link](#ignoreenvironments)]
* Severity support[[link](#setting-severity)]
The library comes with the following integrations:
* Web frameworks
* ASP.NET HTTP Module[[link](#aspnet-http-module)]
* ASP.NET Core Middleware[[link](#aspnet-core-middleware)]
* [NLog](http://nlog-project.org/) logging platform[[link](#nlog-integration)]
* [Apache log4net](http://logging.apache.org/log4net/) library[[link](#log4net-integration)]
* Provider for [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging) framework[[link](#microsoftextensionslogging-integration)]
Installation
------------
### NuGet
Package | Description | NuGet link
------------------------------|--------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------
Sharpbrake.Client | C# client with support for .NET 4.5.2 and above | [](https://www.nuget.org/packages/Sharpbrake.Client)
Sharpbrake.Http.Module | HTTP module for ASP.NET request pipeline | [](https://www.nuget.org/packages/Sharpbrake.Http.Module)
Sharpbrake.Http.Middleware | Middleware component for new ASP.NET Core pipeline | [](https://www.nuget.org/packages/Sharpbrake.Http.Middleware)
Sharpbrake.NLog | Airbrake NLog target | [](https://www.nuget.org/packages/Sharpbrake.NLog)
Sharpbrake.NLog.Web | Airbrake NLog target for ASP.NET | [](https://www.nuget.org/packages/Sharpbrake.NLog.Web)
Sharpbrake.Log4net | Airbrake log4net appender | [](https://www.nuget.org/packages/Sharpbrake.Log4net)
Sharpbrake.Log4net.Web | Airbrake log4net appender for ASP.NET | [](https://www.nuget.org/packages/Sharpbrake.Log4net.Web)
Sharpbrake.Extensions.Logging | Airbrake provider for Microsoft.Extensions.Logging | [](https://www.nuget.org/packages/Sharpbrake.Extensions.Logging)
For .NET 4.5.2 applications and above install the `Sharpbrake.Client` package
available on [NuGet](https://www.nuget.org/packages/Sharpbrake.Client) via your
[Package Manager Console](https://docs.nuget.org/docs/start-here/using-the-package-manager-console):
```
PM> Install-Package Sharpbrake.Client
```
Examples
--------
### Basic example
This is the minimal example that you can use to test Sharpbrake with your
project.
```csharp
using System;
using Sharpbrake.Client;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
var airbrake = new AirbrakeNotifier(new AirbrakeConfig
{
ProjectId = "113743",
ProjectKey = "81bbff95d52f8856c770bb39e827f3f6"
});
try
{
throw new Exception("Oops!");
}
catch (Exception ex)
{
var notice = airbrake.BuildNotice(ex);
var response = airbrake.NotifyAsync(notice).Result;
Console.WriteLine("Status: {0}, Id: {1}, Url: {2}", response.Status, response.Id, response.Url);
}
}
}
}
```
### .NET Core console app guide
Consult our [documentation][dotnet-core-console] to learn how to create an
Airbrake-enabled console app.
Configuration
-------------
Before using the library and its notifiers, you must configure them. In most
cases, it is sufficient to configure only one, default, notifier.
```csharp
var airbrake = new AirbrakeNotifier(new AirbrakeConfig
{
ProjectId = "113743",
ProjectKey = "81bbff95d52f8856c770bb39e827f3f6"
});
```
#### ProjectId & ProjectKey
You **must** set both `ProjectId` & `ProjectKey`.
To find your `ProjectId` and `ProjectKey` navigate to your project's _General
Settings_ and copy the values from the right sidebar.

There are multiple ways to set these values:
* Setting explicitly:
```csharp
var config = new AirbrakeConfig {
ProjectId = "113743",
ProjectKey = "81bbff95d52f8856c770bb39e827f3f6"
};
```
* Using `App.config` or `Web.config`:
```xml
```
```csharp
var settings = ConfigurationManager.AppSettings.AllKeys
.Where(key => key.StartsWith("Airbrake", StringComparison.OrdinalIgnoreCase))
.ToDictionary(key => key, key => ConfigurationManager.AppSettings[key]);
var airbrakeConfiguration = AirbrakeConfig.Load(settings);
```
* Using `airbrake.json`. Use comma-separated values to add more than one
argument for options that support it:
```json
{
"Airbrake": {
"ProjectId": "113743",
"ProjectKey": "81bbff95d52f8856c770bb39e827f3f6"
}
}
```
```csharp
var path = "airbrake.json";
var configurationBuilder = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile(path)
.Build();
var settings = configurationBuilder.AsEnumerable()
.Where(setting => setting.Key.StartsWith("Airbrake"))
.ToDictionary(setting => setting.Key, setting => setting.Value);
var airbrakeConfiguration = AirbrakeConfig.Load(settings);
```
#### LogFile
The library can log responses from Airbrake via the `LogFile` option. The option
accepts a path to the log file. Supports relative (to your app's executable) and
absolute paths. By default, it's not set.
```csharp
var config = new AirbrakeConfig {
LogFile = "airbrake.log"
};
```
#### Environment
Configures the environment the application is running in. Helps the Airbrake
dashboard to distinguish between errors occurring in different environments.
By default, it's not set.
```csharp
var config = new AirbrakeConfig {
Environment = "production"
};
```
#### AppVersion
The version of your application that you can pass to differentiate errors
between multiple versions. It's not set by default.
```csharp
var config = new AirbrakeConfig {
AppVersion = "1.0.1"
};
```
#### Host
By default, it is set to `api.airbrake.io`. A `host` is a web address containing a
scheme ("http" or "https"), a host and a port. You can omit the port (80 will be
assumed) and the scheme ("https" will be assumed).
```csharp
var config = new AirbrakeConfig {
Host = "http://127.0.0.1:8000"
};
```
#### Proxy options
If your server is not able to directly reach Airbrake, you can use a built-in
proxy. By default, Sharpbrake uses a direct connection.
##### ProxyUri, ProxyUsername, ProxyPassword
```csharp
var config = new AirbrakeConfig {
ProxyUri = "http://46.166.165.63:8080",
ProxyUsername = "username",
ProxyPassword = "s3kr3t"
};
```
#### IgnoreEnvironments
Setting this option allows Airbrake to filter errors occurring in unwanted
environments such as `test`. By default, it is not set, which means Sharpbrake
sends errors occurring in all environments.
```csharp
var config = new AirbrakeConfig {
IgnoreEnvironments = new List { "development" }
};
```
#### Blocklist
Specifies which keys in the payload (parameters, session data, environment data,
etc.) should be filtered. Before sending an error, filtered keys will be
substituted with the `[Filtered]` label.
```csharp
var config = new AirbrakeConfig {
Blocklist = new List { "password", "creditCard", "email" }
};
// The dashboard will display this parameter as filtered, but other values won't
// be affected:
// { user: 'John',
// password: '[Filtered]',
// email: '[Filtered]',
// creditCard: '[Filtered]' }
```
**Note:** `Blocklist` has higher priority than `Allowlist`. It means
that if you set the same value into both blacklist and whitelist - that value
will be filtered out.
#### Allowlist
Specifies which keys in the payload (parameters, session data, environment data,
etc.) should _not_ be filtered. All other keys will be substituted with the
`[Filtered]` label.
```csharp
var config = new AirbrakeConfig {
Allowlist = new List { "user", "email", "accountId" }
};
// The dashboard will display this parameter as is, but all other values will be
// filtered:
// { user: 'John',
// password: '[Filtered]',
// email: 'john@example.com',
// accountId: 42 }
```
#### FormatProvider
Specifies formatting information for error messages. Check [IFormatProvider][iformatprovider]
for details.
API
---
### AirbrakeConfig
#### Load
`AirbrakeConfig.Load` accepts a `Dictionary` consisting of config option names
and their values.
```csharp
// Construct a dictionary with configuration options
var settings = ConfigurationManager.AppSettings.AllKeys
.Where(key => key.StartsWith("Airbrake", StringComparison.OrdinalIgnoreCase))
.ToDictionary(key => key, key => ConfigurationManager.AppSettings[key]);
// Create a config from that dictionary
var config = AirbrakeConfig.Load(settings);
```
### AirbrakeNotifier
#### BuildNotice
`BuildNotice` builds a notice with error details that can be sent to the
Airbrake dashboard with the help of [`NotifyAsync`](#notifyasync):
```csharp
notifier.BuildNotice(Severity.Error, exception, "Failed with message {0}", exception.Message);
```
#### NotifyAsync
`NotifyAsync` asynchronously sends a notice with error details to the Airbrake
dashboard. It also provides control over the response object from Airbrake.
In .NET 4.5 and above you can use task-based programming model. Example of using
a continuation, which prints URL to the error in the Airbrake dashboard:
```csharp
airbrake.NotifyAsync(notice)
.ContinueWith(response => Console.WriteLine(response.Result.Url));
```
The method also supports `async/await`:
```csharp
var response = await airbrake.NotifyAsync(notice);
Console.WriteLine(response.Url);
```
#### SetHttpContext
`SetHttpContext` attaches HTTP context properties to the notice:
```csharp
var notice = notifier.BuildNotice(ex);
notifier.SetHttpContext(notice, new AspNetCoreHttpContext(context));
notifier.NotifyAsync(notice);
```
Usually, our integrations perform this for you.
#### `AddFilter`
A notice can be customized or ignored before it is sent to Airbrake via
`AddFilter`. A lambda expression that is passed to the `AddFilter` method
accepts `Notice` that can be processed by your code. The `Notice` object is
pre-populated with errors, context and params, so you can freely modify these
values if you wish. The `Notice` object is not sent to Airbrake if the lambda
expression returns `null`:
```csharp
airbrake.AddFilter(notice =>
{
// ignore notice if email is "test@example.com"
if (notice.Context.User?.Email == "test@example.com")
return null;
// clear environment variables with "token"-related keys
if (notice.EnvironmentVars != null)
{
new List(notice.EnvironmentVars.Keys).ForEach(key =>
{
if (key.ToLowerInvariant().Contains("token"))
notice.EnvironmentVars[key] = string.Empty;
});
}
return notice;
});
```
### Notice
`Exception` and `HttpContext` are properties that can be used to retrieve the
values that the `Notice` object was built from.
#### Exception
Used to access additional exception properties. For example, if your exception is
an `HttpException`, you can ignore it if `GetHTTPCode()` returns 404:
```csharp
airbrake.AddFilter(notice =>
{
var exception = notice.Exception as HttpException;
if (exception != null && exception.GetHttpCode() == 404)
return null;
return notice;
});
```
#### HttpContext
Used to retrieve HTTP context properties:
```csharp
airbrake.AddFilter(notice =>
{
notice.Params["response"] = notice.HttpContext.Response
return notice;
});
```
**Note:** Notice that exceeds 64 KB is truncated before sending.
#### Setting severity
[Severity][what-is-severity] allows categorizing how severe an error is. By
default, it's set to `error`. To redefine severity, simply pass the `Severity`
as a parameter to the `BuildNotice` method. For example:
```csharp
airbrake.BuildNotice(Severity.Critical, exception);
```
ASP.NET Integration
-------------------
### ASP.NET HTTP Module
1. Install the `Sharpbrake.Http.Module` package from NuGet (you can use "Package
Manager Console" from Visual Studio):
```
PM> Install-Package Sharpbrake.Http.Module
```
2. Configure `appSettings` in `Web.config` ([how to configure](#configuration)):
```xml
```
3. Add the `AirbrakeHttpModule` module to your `system.webServer` in
`Web.config`:
```xml
```
### ASP.NET Core Middleware
1. Install the `Sharpbrake.Http.Middleware` package from NuGet (you can use
"Package Manager Console" from Visual Studio):
```
PM> Install-Package Sharpbrake.Http.Middleware
```
2. Configure `appsettings.json`:
```json
"Airbrake": {
"ProjectId": "113743",
"ProjectKey": "81bbff95d52f8856c770bb39e827f3f6",
}
```
3. Add the middleware to your `Startup.cs`:
```csharp
using Sharpbrake.Http.Middleware;
```
Then make sure to add `AirbrakeMiddleware` to your pipeline by updating the
`Configure` method:
```csharp
app.UseAirbrake(Configuration.GetSection("Airbrake"));
```
**Note:** In most cases you want to put `AirbrakeMiddleware` as a topmost
middleware component to load it as early as possible. However, if you use
`app.UseDeveloperExceptionPage` and/or `app.UseExceptionHandler`, then
`AirbrakeMiddleware` must be put after these components.
You can use the `IAirbrakeFeature` feature from the `Features` collection of
`HttpContext` to access the notifier that was initialized by the middleware:
```csharp
var airbrake = HttpContext.Features.Get().GetNotifier();
```
NLog Integration
----------------
### Airbrake NLog target
Airbrake NLog target is used to pass an error and exception from log message
to the Airbrake dashboard.
1. Install the `Sharpbrake.NLog` package from NuGet (you can use "Package
Manager Console" from Visual Studio):
```
PM> Install-Package Sharpbrake.NLog
```
2. Register the `Sharpbrake.NLog` assembly in the `` section
of the [nlog.config][nlog-config] file:
```xml
```
3. Define the Airbrake target in the `` section and appropriate
routing rules in the `` section of `nlog.config`:
```xml
```
```xml
```
Note that both `projectId` and `projectKey` are required parameters. You can
set any configuration option supported by the Airbrake client in the declarative
way ([how to configure](#configuration)).
When you need to access `Notifier` programmatically (e.g. for setting up filters
in your code) you can get it from the `AirbrakeTarget` object:
```csharp
var airbrakeTarget = (AirbrakeTarget)LogManager.Configuration.AllTargets
.FirstOrDefault(t => t.GetType() == typeof(AirbrakeTarget));
airbrakeTarget?.Notifier.AddFilter(notice =>
{
// clear environment variables with "token"-related keys
new List(notice.EnvironmentVars.Keys).ForEach(key =>
{
if (key.ToLowerInvariant().Contains("token"))
notice.EnvironmentVars[key] = "[removed]";
});
return notice;
});
```
### Airbrake NLog target for ASP.NET
With Airbrake NLog target for ASP.NET you get, in addition, reporting of HTTP
context properties in web applications.
1. Install the `Sharpbrake.NLog.Web` package from NuGet (you can use "Package
Manager Console" from Visual Studio):
```
PM> Install-Package Sharpbrake.NLog.Web
```
2. Register the `Sharpbrake.NLog.Web` assembly in the `` section
of the [nlog.config][nlog-config] file:
```xml
```
3. Define the Airbrake target in the `` section and appropriate
routing rules in the `` section of `nlog.config`. All supported
settings are the same as for the regular Airbrake target.
```xml
```
```xml
```
4. For ASP.NET Core you need to call the following code in the `Configure` method
in `Startup.cs`:
```csharp
app.ConfigureAirbrakeTarget();
```
The `Notifier` object can be accessed from here for the additional configuration:
```csharp
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// add NLog to ASP.NET Core
loggerFactory.AddNLog();
// add NLog.Web
app.AddNLogWeb();
// configure the Airbrake target with HTTP context accessor
app.ConfigureAirbrakeTarget();
// example of getting access to the Notifier instance
var target = LogManager.Configuration.FindTargetByName("airbrake");
target?.Notifier.AddFilter(notice =>
{
// clear environment variables with "token"-related keys
new List(notice.EnvironmentVars.Keys).ForEach(key =>
{
if (key.ToLowerInvariant().Contains("token"))
notice.EnvironmentVars[key] = "[removed]";
});
return notice;
});
// remaining code...
}
```
Log4net Integration
-------------------
### Airbrake log4net appender
Airbrake log4net appender sends an exception or/and error from the logging
event to the Airbrake dashboard.
1. Install the `Sharpbrake.Log4net` package from NuGet (you can use "Package
Manager Console" from Visual Studio):
```
PM> Install-Package Sharpbrake.Log4net
```
2. Define the `Sharpbrake.Log4net.AirbrakeAppender` appender in the
[log4net configuration][log4net-config] file:
```xml
```
3. Add Airbrake appender to the root logger:
```xml
```
Note that both `projectId` and `projectKey` are required parameters. You can
set any configuration option supported by the Airbrake client in the declarative
way within `` section ([how to configure](#configuration)).
### Airbrake log4net appender for ASP.NET
With Airbrake log4net appender for ASP.NET you get, in addition, reporting of HTTP
context properties in web applications.
1. Install the `Sharpbrake.Log4net.Web` package from NuGet (you can use "Package
Manager Console" from Visual Studio):
```
PM> Install-Package Sharpbrake.Log4net.Web
```
2. Define the `Sharpbrake.Log4net.Web.AirbrakeAppender` appender in the
[log4net configuration][log4net-config] file:
```xml
```
Note that you need to use `Sharpbrake.Log4net.Web.AirbrakeAppender` from `Sharpbrake.Log4net.Web`
assembly and not plain `Sharpbrake.Log4net.AirbrakeAppender` (without `Web` part) to get support
for reporting HTTP context properties.
3. Add Airbrake appender to the root logger:
```xml
```
4. For ASP.NET Core apps you need to set `ContextAccessor` property in appender so it can
access `HttpContext`. You can do that directly or by calling the helper method from the
`AspNetCoreExtensions` class:
4.1. In `Startup.cs` add `using Sharpbrake.Log4net.Web` to get access to the
`AspNetCoreExtensions` class.
4.2. In the `Configure` method (`Startup.cs` file) call the `ConfigureAirbrakeAppender`
method after setting up log4net functionality:
```csharp
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var repoAssembly = Assembly.GetEntryAssembly();
var loggerRepository = log4net.LogManager.CreateRepository(repoAssembly,
typeof(log4net.Repository.Hierarchy.Hierarchy));
log4net.Config.XmlConfigurator.Configure(loggerRepository,
new FileInfo("log4net.config"));
app.ConfigureAirbrakeAppender(repoAssembly);
// remaining code...
}
```
Microsoft.Extensions.Logging Integration
----------------------------------------
Provider notifies the Airbrake dashboard of an error with the help of
[Microsoft.Extensions.Logging](https://github.com/aspnet/Logging) methods.
1. Install the `Sharpbrake.Extensions.Logging` package from NuGet (you can use "Package
Manager Console" from Visual Studio):
```
PM> Install-Package Sharpbrake.Extensions.Logging
```
2. Configure the Airbrake logging provider:
2.1. In your `Startup.cs` add the import:
```csharp
using Sharpbrake.Extensions.Logging
```
2.2. Add the Airbrake provider to the list of loggers:
* For ASP.NET Core 2.x the provider can be added in the `ConfigureServices` method:
```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// adds the Airbrake provider with HTTP Context accessor
// to the list of services
var contextAccessor = new HttpContextAccessor();
services.AddSingleton(contextAccessor);
services.AddLogging(logging =>
{
logging.AddAirbrake(Configuration.GetSection("Airbrake"), contextAccessor);
});
}
```
* If your project uses ASP.NET Core 1.x the provider can be added in the `Configure` method:
```csharp
loggerFactory.AddAirbrake(Configuration.GetSection("Airbrake"),
app.ApplicationServices.GetService());
```
The code above assumes that the configuration options are defined in the registered configuration
file (e.g. `appsettings.json`). Example of such configuration file:
```
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"Airbrake": {
"ProjectId": "113743",
"ProjectKey": "81bbff95d52f8856c770bb39e827f3f6"
}
}
```
To get access to the HTTP content `app.ApplicationServices.GetService()`
is used.
Minimum log level can be set here to filter errors with lower severities
(defaults to `LogLevel.Error`):
```csharp
loggerFactory.AddAirbrake(Configuration.GetSection("Airbrake"),
app.ApplicationServices.GetService(),
LogLevel.Warning);
```
More advanced setup can be used to better suit your needs. Here is an example of
how to define a notifier with additional filtering rules:
```csharp
var settings = Configuration.GetSection("Airbrake")
.GetChildren()
.ToDictionary(setting => setting.Key, setting => setting.Value);
var airbrakeNotifier = new AirbrakeNotifier(AirbrakeConfig.Load(settings));
// clear environment variables with "token"-related keys
airbrakeNotifier.AddFilter(notice =>
{
if (notice?.EnvironmentVars != null)
{
new List(notice.EnvironmentVars.Keys).ForEach(key =>
{
if (key.ToLowerInvariant().Contains("token"))
notice.EnvironmentVars[key] = "[removed]";
});
}
return notice;
});
loggerFactory.AddAirbrake(airbrakeNotifier,
app.ApplicationServices.GetService());
```
Debugging and Diagnostics
-------------------------
If something goes wrong with the notifier itself (a notice is not being sent,
some internal exception happens, etc.) you may want to turn on the tracing mode
and get more insights on what is going on.
Tracing to the Debug window can be enabled with the following code:
```csharp
Sharpbrake.Client.InternalLogger.Enable(msg => Debug.WriteLine(msg));
```
You can output to the file as well:
```csharp
var traceWriter = System.IO.TextWriter.Synchronized(
System.IO.File.AppendText("AirbrakeNotifier.log"));
Sharpbrake.Client.InternalLogger.Enable(msg =>
{
traceWriter.WriteLine(msg);
traceWriter.Flush();
});
```
Tracing can be disabled (this is the default state) with the code:
```csharp
Sharpbrake.Client.InternalLogger.Disable();
```
.NET 3.5 Support
----------------
Please refer to [Sharpbrake for .NET 3.5][sharpbrake-net35] if your app uses
.NET Framework before 4.5.2.
Contributing
------------
* [Contribution guide](CONTRIBUTING.md)
* [Sharpbrake developer documentation](https://github.com/airbrake/sharpbrake/blob/master/docs/developer-howto.md)
License
-------
The project uses the MIT License. See [LICENSE.md](LICENSE.md) for details.
[dotnet-core-console]: https://github.com/airbrake/sharpbrake/blob/master/docs/dotnet-core-console.md
[what-is-severity]: https://airbrake.io/docs/airbrake-faq/what-is-severity/
[sharpbrake-net35]: https://github.com/airbrake/sharpbrake-net35
[nlog-config]: https://github.com/NLog/NLog/wiki/Configuration-file
[log4net-config]: https://logging.apache.org/log4net/release/manual/configuration.html
[iformatprovider]: https://docs.microsoft.com/en-us/dotnet/api/system.iformatprovider