![]() |
VOOZH | about |
dotnet add package Serilog.Sinks.ApplicationInsights --version 5.0.1
NuGet\Install-Package Serilog.Sinks.ApplicationInsights -Version 5.0.1
<PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="5.0.1" />
<PackageVersion Include="Serilog.Sinks.ApplicationInsights" Version="5.0.1" />Directory.Packages.props
<PackageReference Include="Serilog.Sinks.ApplicationInsights" />Project file
paket add Serilog.Sinks.ApplicationInsights --version 5.0.1
#r "nuget: Serilog.Sinks.ApplicationInsights, 5.0.1"
#:package Serilog.Sinks.ApplicationInsights@5.0.1
#addin nuget:?package=Serilog.Sinks.ApplicationInsights&version=5.0.1Install as a Cake Addin
#tool nuget:?package=Serilog.Sinks.ApplicationInsights&version=5.0.1Install as a Cake Tool
A sink for Serilog that writes events to Microsoft Application Insights. This sink comes with several defaults that send
Serilog LogEvent messages to Application Insights as either EventTelemetry or TraceTelemetry.
dotnet add package Serilog.Sinks.ApplicationInsights
The recommended way to configure the sink is to reuse the TelemetryConfiguration (or TelemetryClient) already configured by your application (for example via dependency injection in ASP.NET Core, Azure Functions, Worker Services).
Log.Logger = new LoggerConfiguration()
.WriteTo.ApplicationInsights(
telemetryConfiguration, // from DI (recommended)
TelemetryConverter.Traces)
.CreateLogger();
If you don't have an existing TelemetryConfiguration (uncommon), you can use the connection string overload:
Log.Logger = new LoggerConfiguration()
.WriteTo.ApplicationInsights(
"<your Application Insights connection string>",
TelemetryConverter.Traces)
.CreateLogger();
Legacy: some older application types used TelemetryConfiguration.Active. This is not recommended on modern .NET and may be deprecated depending on the Application Insights SDK version.
You can also pass an instrumentation key and this sink will create a new
TelemetryConfigurationbased on it, however it's actively discouraged compared to using already initialised telemetry configuration, as your telemetry won't be properly correlated.
Note: Whether you choose Events or Traces, if the LogEvent contains any exceptions it will always be sent
as ExceptionTelemetry.
TelemetryConfiguration.Active is deprecated in the App Insights SDK for .NET Core, what do I do?The
singleton TelemetryConfiguration.Active has been deprecated in the Application Insights SDK on .NET Core in favor of dependency injection pattern
.
Therefore, now we need to pass in the TelemetryConfiguration instance that was added either
by services.AddApplicationInsightsTelemetryWorkerService() (if you're developing
a non-http application)
or services.AddApplicationInsightsTelemetry() (if you're developing
an ASP.Net Core application) during Startup
in ConfigureServices.
Log.Logger = new LoggerConfiguration()
.WriteTo.ApplicationInsights(
serviceProvider.GetRequiredService<TelemetryConfiguration>(),
TelemetryConverter.Traces)
.CreateLogger();
However, you probably want to setup your Logger as close to the entry point of your application as possible, so that any
startup errors can be caught and properly logged. The problem is that now we're in a chicken-and-egg situation: we want
to setup the logger early, but we need the TelemetryConfiguration which still haven't been added to our DI container.
Luckily from version 4.0.x of the Serilog.Extensions.Hosting we have the possibility to configure a bootstrap logger
to capture early errors, and then change it using DI-dependent services once they are configured.
// dotnet add package Serilog.Extensions.Hosting
public static class Program
{
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateBootstrapLogger();
try
{
CreateHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "An unhandled exception occurred during bootstrapping");
}
finally
{
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog((context, services, loggerConfiguration) => loggerConfiguration
.WriteTo.ApplicationInsights(
services.GetRequiredService<TelemetryConfiguration>(),
TelemetryConverter.Traces))
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}
ReadFrom.Configuration()Configuring in code, as shown above, is recommended because the existing TelemetryClient can be injected.
The following configuration shows how to create an ApplicationInsights sink with ReadFrom.Configuration(configuration).
{
"Serilog": {
"Using": [
"Serilog.Sinks.ApplicationInsights"
],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "ApplicationInsights",
"Args": {
"connectionString": "[your connection string here]",
"telemetryConverter":
"Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights"
}
}
],
"Enrich": [ "FromLogContext" ],
"Properties": {
"Application": "Sample"
}
}
}
The telemetryConverter has to be specified with the full type name and the assembly name.
A connectionString can be omitted if it's supplied in the APPLICATIONINSIGHTS_CONNECTION_STRING environment variable.
By default, trace telemetry submits:
OperationId property, or the LogEvent.TraceId property.ParentSpanId property.OperationName property.Version property.Event telemetry submits:
OperationId property, or the LogEvent.TraceId property.ParentSpanId property.OperationName property.Version property.Exception telemetry submits:
OperationId property, or the LogEvent.TraceId property.ParentSpanId property.OperationName property.Version property.Note that log context properties are also included in customDimensions when Serilog is configured with
.Enrich.FromLogContext().
By default custom properties are converted to compact JSON, for instance:
var position = new { Latitude = 25, Longitude = 134 };
var elapsedMs = 34;
var numbers = new int[] { 1, 2, 3, 4 };
Logger.Information("Processed {@Position} in {Elapsed:000} ms., str {str}, numbers: {numbers}",
position, elapsedMs, "test", numbers);
will produce the following properties in customDimensions:
| Property | Value |
|---|---|
| Elapsed | 34 |
| Position | {"Latitude":25,"Longitude":134} |
| numbers | [1,2,3,4] |
This is a breaking change from v2 which was producing these properties:
| Property | Value |
|---|---|
| Elapsed | 34 |
| Position.Latitude | 25 |
| Position.Longitude | 134 |
| numbers.0 | 1 |
| numbers.1 | 2 |
| numbers.2 | 3 |
| numbers.3 | 4 |
You can revert the old behavior by overriding standard telemetry formatter, for instance:
private class DottedOutTraceTelemetryConverter : TraceTelemetryConverter
{
public override IValueFormatter ValueFormatter => new ApplicationInsightsDottedValueFormatter();
}
Additionally, you can also customize whether to send the LogEvents at all, if so which type(s) of Telemetry to send
and also what to send (all or no LogEvent properties at all) by passing your own ITelemetryConverter instead
of TelemetryConverter.Traces or TelemetryConverter.Events by either implementing your own ITelemetryConverter or
deriving from TraceTelemetryConverter or EventTelemetryConverter and overriding specific bits.
Log.Logger = new LoggerConfiguration()
.WriteTo.ApplicationInsights(configuration, new CustomConverter())
.CreateLogger();
// ...
private class CustomConverter : TraceTelemetryConverter
{
public override IEnumerable<ITelemetry> Convert(LogEvent logEvent, IFormatProvider formatProvider)
{
// first create a default TraceTelemetry using the sink's default logic
// .. but without the log level, and (rendered) message (template) included in the Properties
foreach (ITelemetry telemetry in base.Convert(logEvent, formatProvider))
{
// then go ahead and post-process the telemetry's context to contain the user id as desired
if (logEvent.Properties.ContainsKey("UserId"))
{
telemetry.Context.User.Id = logEvent.Properties["UserId"].ToString();
}
// post-process the telemetry's context to contain the operation id
if (logEvent.Properties.ContainsKey("OperationId"))
{
telemetry.Context.Operation.Id = logEvent.Properties["OperationId"].ToString();
}
// post-process the telemetry's context to contain the operation parent id
if (logEvent.Properties.ContainsKey("ParentSpanId"))
{
telemetry.Context.Operation.ParentId = logEvent.Properties["ParentSpanId"].ToString();
}
// typecast to ISupportProperties so you can manipulate the properties as desired
ISupportProperties propTelemetry = (ISupportProperties)telemetry;
// find redundant properties
var removeProps = new[] { "UserId", "ParentSpanId", "OperationId" };
removeProps = removeProps.Where(prop => propTelemetry.Properties.ContainsKey(prop)).ToArray();
foreach (var prop in removeProps)
{
// remove redundant properties
propTelemetry.Properties.Remove(prop);
}
yield return telemetry;
}
}
}
If you want to skip sending a particular LogEvent, just return null from your own converter method.
The easiest way to customise included properties is to subclass one of the ITelemetryConverter implementations. For
instance, let's include renderedMessage in event telemetry:
private class IncludeRenderedMessageConverter : EventTelemetryConverter
{
public override void ForwardPropertiesToTelemetryProperties(LogEvent logEvent,
ISupportProperties telemetryProperties, IFormatProvider formatProvider)
{
base.ForwardPropertiesToTelemetryProperties(logEvent, telemetryProperties, formatProvider,
includeLogLevel: false,
includeRenderedMessage: true,
includeMessageTemplate: false);
}
}
As explained by the Application Insights documentation , the default behaviour of the AI client is to buffer messages and send them to AI in batches whenever the client seems fit. However, this may lead to lost messages when your application terminates while there are still unsent messages in said buffer.
You can control when AI shall flush its messages, for example when your application closes:
TelemetryClient and hold on to it in a field or property:// private TelemetryClient _telemetryClient;
// ...
var telemetryConfiguration = TelemetryConfiguration.CreateDefault();
telemetryConfiguration.ConnectionString = "<your Application Insights connection string>";
_telemetryClient = new TelemetryClient(telemetryConfiguration);
TelemetryClient to initialize the Sink:var log = new LoggerConfiguration()
.WriteTo.ApplicationInsights(_telemetryClient, TelemetryConverter.Events)
.CreateLogger();
_telemetryClient.Flush();
// The AI documentation mentions that calling `Flush()` *can* be asynchronous and non-blocking so
// depending on the underlying Channel to AI you might want to wait some time
// specific to your application and its connectivity constraints for the flush to finish.
await Task.Delay(1000);
// or
System.Threading.Thread.Sleep(1000);
Application Insight's operation id is set from the following sources in order of precedence:
OperationId LogEvent propertyTraceId LogEvent propertyThis can be set like so:
public class OperationIdEnricher : ILogEventEnricher
{
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
if (logEvent.Properties.TryGetValue("RequestId", out var requestId))
{
logEvent.AddPropertyIfAbsent(new LogEventProperty("OperationId", requestId));
}
}
}
Application Insight supports component version and is pushed out if you set Version log event property. If it's
present, AI's operation version will include the value from this property.
SerilogTracing provides tracing primitives that integrate with Serilog's structured logging. When used with this sink, tracing context is automatically included in Application Insights telemetry.
The following LogEvent properties are mapped to Application Insights telemetry:
| LogEvent Property | Application Insights Telemetry | Notes |
|---|---|---|
TraceId |
Context.Operation.Id |
From TraceId captured in LogEvent |
SpanId |
Id (for Request/Dependency telemetry) |
From SpanId captured in LogEvent |
ParentSpanId |
Context.Operation.ParentId |
|
OperationName |
Context.Operation.Name |
|
OperationId |
Context.Operation.Id |
Overrides TraceId |
Version |
Context.Component.Version |
If present, Baggage is forwarded to Application Insights custom dimensions (telemetry.Properties).
Precedence for Context.Operation.Id: OperationId property > TraceId property (when both OperationId and TraceId properties are absent).
Activity (explicit opt-in)This sink is designed to work well with Serilog's asynchronous/batched processing. To keep telemetry deterministic, adding OperationName and Baggage from the ambient Activity is an explicit opt-in: copy the values onto the LogEvent before it reaches the sink.
The sink includes an enricher that adds this by default. Enable it using the provided Enrich extension method:
Log.Logger = new LoggerConfiguration()
.Enrich.WithActivityDetails(includeOperationName: true, includeBaggage: true)
.WriteTo.ApplicationInsights(telemetryConfiguration, TelemetryConverter.Traces)
.CreateLogger();
This is a new major release (5.0). Notable changes:
LogEvent properties (use the built-in enricher above or your own enricher).ITelemetry.Context and are not duplicated into telemetry.Properties unless enabled.TelemetryConverterBase constructor flagsConverters derived from TelemetryConverterBase can be configured to also include selected operation-related values in telemetry.Properties (custom dimensions):
public TelemetryConverterBase(
bool includeOperationIdPropertyAsTelemetryProperty,
bool includeParentSpanIdPropertyAsTelemetryProperty,
bool includeOperationNamePropertyAsTelemetryProperty,
bool includeVersionPropertyAsTelemetryProperty)
If you previously relied on these values being present in telemetry.Properties, enable the relevant flags when constructing your converter, or post-process telemetry in a custom converter.
Azure functions has out of the box integration with Application Insights, which automatically logs functions execution start, end, and any exception. Please refer to the original documentation on how to enable it.
This sink can enrich AI messages, preserving operation_Id and other context information which is already provided by functions runtime. The easiest way to configure Serilog in this case is to use the injected TelemetryClient which should be automatically configured by the environment through the APPLICATIONINSIGHTS_CONNECTION_STRING appsetting. You can, for instance, initialise logging in the static constructor:
[assembly: FunctionsStartup(typeof(MyFunctions.Startup))]
namespace MyFunctions
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<ILoggerProvider>((sp) =>
{
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.ApplicationInsights(sp.GetRequiredService<TelemetryClient>(), TelemetryConverter.Traces)
.CreateLogger();
return new SerilogLoggerProvider(Log.Logger, true);
});
}
}
}
Copyright © 2025 Serilog Contributors - Provided under the Apache License, Version 2.0.
See also: Serilog Documentation
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 is compatible. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 is compatible. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on Serilog.Sinks.ApplicationInsights:
| Package | Downloads |
|---|---|
|
Bet.Extensions.Logging
The Collection of the Logging related functionality for AspNetCore or GenericHost. |
|
|
Apprio.Enablement.Telemetry.Properties
Package Description |
|
|
Apprio.Enablement.Telemetry
Package Description |
|
|
Serilog.Extensions.Logging.ApplicationInsights
Add application insights logging to ASP.NET Core apps with one line of code. |
|
|
Arcus.Observability.Telemetry.Serilog.Sinks.ApplicationInsights
Provides capability to improve telemetry with Serilog that is sent to Azure Application Insights |
Showing the top 14 popular GitHub repositories that depend on Serilog.Sinks.ApplicationInsights:
| Repository | Stars |
|---|---|
|
ardalis/CleanArchitecture
Clean Architecture Solution Template: A proven Clean Architecture Template for ASP.NET Core 10
|
|
|
Dotnet-Boxed/Templates
.NET project templates with batteries included, providing the minimum amount of code required to get you going faster.
|
|
|
microsoft/AttackSurfaceAnalyzer
Attack Surface Analyzer can help you analyze your operating system's security configuration for changes during software installation.
|
|
|
NuGet/NuGetGallery
NuGet Gallery is a package repository that powers https://www.nuget.org. Use this repo for reporting NuGet.org issues.
|
|
|
isaacrlevin/presencelight
PresenceLight is a solution to broadcast your various statuses to light bulbs.
|
|
|
planetarium/NineChronicles
Unity client application for Nine Chronicles, a fully decentralized idle RPG powered by the community.
|
|
|
damienbod/AspNetCoreOpenIddict
OpenIddict with Angular and Blazor WASM BFF OpenID Connect Code Flow with PKCE clients and ASP.NET Core APIs
|
|
|
damienbod/AspNetCoreHybridFlowWithApi
Different ASP.NET Core applications using OpenID Connect Hybrid flow Code Flow, Code Flow with PKCE, JWT APIs, MFA examples
|
|
|
Daniel-Krzyczkowski/Cars-Island-On-Azure
Cars Island is a fake car rental company which used Microsoft Azure cloud services to implement the system for managing car renting.
|
|
|
damienbod/AspNetCoreCertificates
Certificate Manager in .NET Core for creating and using X509 certificates
|
|
|
rayrfan/Fanray
A blog built with ASP.NET Core
|
|
|
KevinDockx/AspNetCoreWebApiFundamentals
Fully functioning sample code for my ASP.NET Core Web API Fundamentals course, currently targeting .NET 8, .NET 9, and .NET 10.
|
|
|
postsharp/PostSharp.Samples
PostSharp Samples
|
|
|
damienbod/AspNetCoreServiceBus
ASP.NET Core with Azure Service Bus
|
| Version | Downloads | Last Updated |
|---|---|---|
| 5.0.1 | 844,463 | 4/17/2026 |
| 5.0.1-dev-02327 | 1,552 | 2/15/2026 |
| 5.0.1-dev-02326 | 143 | 2/15/2026 |
| 5.0.0 | 2,855,841 | 1/8/2026 |
| 5.0.0-dev-02323 | 168 | 1/7/2026 |
| 5.0.0-dev-02322 | 1,437 | 12/24/2025 |
| 4.1.0 | 2,404,087 | 11/12/2025 |
| 4.1.0-dev-02321 | 259 | 12/24/2025 |
| 4.1.0-dev-02318 | 260 | 12/22/2025 |
| 4.1.0-dev-02311 | 282 | 12/5/2025 |
| 4.1.0-dev-02307 | 665 | 11/11/2025 |
| 4.1.0-dev-02304 | 63,877 | 3/28/2025 |
| 4.0.1-dev-02303 | 13,605 | 3/28/2025 |
| 4.0.1-dev-00050 | 2,038 | 3/27/2025 |
| 4.0.1-dev-00049 | 639 | 3/27/2025 |
| 4.0.1-dev-00046 | 104,433 | 11/1/2024 |
| 4.0.1-dev-00043 | 655,210 | 3/15/2023 |
| 4.0.1-dev-00040 | 292,104 | 7/25/2022 |
| 4.0.1-dev-00038 | 3,559 | 6/21/2022 |
| 4.0.0 | 76,499,082 | 6/21/2022 |