diff --git a/customer-samples/AutomaticTraceIdInjection/Log4NetExample/Log4NetExample.csproj b/customer-samples/AutomaticTraceIdInjection/Log4NetExample/Log4NetExample.csproj
new file mode 100644
index 000000000000..3e70bc0b16fd
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/Log4NetExample/Log4NetExample.csproj
@@ -0,0 +1,20 @@
+
+
+
+ Exe
+ netcoreapp2.1
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
\ No newline at end of file
diff --git a/customer-samples/AutomaticTraceIdInjection/Log4NetExample/Program.cs b/customer-samples/AutomaticTraceIdInjection/Log4NetExample/Program.cs
new file mode 100644
index 000000000000..89fb892ed0cb
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/Log4NetExample/Program.cs
@@ -0,0 +1,34 @@
+using System.IO;
+using Datadog.Trace;
+using log4net;
+using log4net.Config;
+
+namespace Log4NetExample
+{
+ class Program
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof(Program));
+
+ static void Main(string[] args)
+ {
+ var logRepository = LogManager.GetRepository(typeof(Program).Assembly);
+ XmlConfigurator.Configure(logRepository, new FileInfo("log4net.config"));
+
+ try
+ {
+ LogicalThreadContext.Properties["order-number"] = 1024;
+ log.Info("Message before a trace.");
+ using (var scope = Tracer.Instance.StartActive("Log4NetExample - Main()"))
+ {
+ log.Info("Message during a trace.");
+ }
+ }
+ finally
+ {
+ LogicalThreadContext.Properties.Remove("order-number");
+ }
+
+ log.Info("Message after a trace.");
+ }
+ }
+}
diff --git a/customer-samples/AutomaticTraceIdInjection/Log4NetExample/Properties/launchSettings.json b/customer-samples/AutomaticTraceIdInjection/Log4NetExample/Properties/launchSettings.json
new file mode 100644
index 000000000000..dbc3a69e3d8e
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/Log4NetExample/Properties/launchSettings.json
@@ -0,0 +1,11 @@
+{
+ "profiles": {
+ "Log4NetExample": {
+ "commandName": "Project",
+ "environmentVariables": {
+ "DD_LOGS_INJECTION": "true"
+ },
+ "nativeDebugging": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/customer-samples/AutomaticTraceIdInjection/Log4NetExample/log4net.config b/customer-samples/AutomaticTraceIdInjection/Log4NetExample/log4net.config
new file mode 100644
index 000000000000..55ea4f60d422
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/Log4NetExample/log4net.config
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/customer-samples/AutomaticTraceIdInjection/NLog45Example/NLog.config b/customer-samples/AutomaticTraceIdInjection/NLog45Example/NLog.config
new file mode 100644
index 000000000000..8902dab86bff
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/NLog45Example/NLog.config
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/customer-samples/AutomaticTraceIdInjection/NLog45Example/NLog45Example.csproj b/customer-samples/AutomaticTraceIdInjection/NLog45Example/NLog45Example.csproj
new file mode 100644
index 000000000000..6809fd87ff6d
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/NLog45Example/NLog45Example.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ netcoreapp2.1
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
\ No newline at end of file
diff --git a/customer-samples/AutomaticTraceIdInjection/NLog45Example/Program.cs b/customer-samples/AutomaticTraceIdInjection/NLog45Example/Program.cs
new file mode 100644
index 000000000000..f73e0c4b55a3
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/NLog45Example/Program.cs
@@ -0,0 +1,25 @@
+using Datadog.Trace;
+using NLog;
+
+namespace NLog45Example
+{
+ class Program
+ {
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+ static void Main(string[] args)
+ {
+ using (MappedDiagnosticsLogicalContext.SetScoped("order-number", 1024))
+ {
+ Logger.Info("Message before a trace.");
+
+ using (var scope = Tracer.Instance.StartActive("NLog45Example - Main()"))
+ {
+ Logger.Info("Message during a trace.");
+ }
+
+ Logger.Info("Message after a trace.");
+ }
+ }
+ }
+}
diff --git a/customer-samples/AutomaticTraceIdInjection/NLog45Example/Properties/launchSettings.json b/customer-samples/AutomaticTraceIdInjection/NLog45Example/Properties/launchSettings.json
new file mode 100644
index 000000000000..3d9206d93e00
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/NLog45Example/Properties/launchSettings.json
@@ -0,0 +1,11 @@
+{
+ "profiles": {
+ "NLog45Example": {
+ "commandName": "Project",
+ "environmentVariables": {
+ "DD_LOGS_INJECTION": "true"
+ },
+ "nativeDebugging": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/customer-samples/AutomaticTraceIdInjection/NLog46Example/NLog.config b/customer-samples/AutomaticTraceIdInjection/NLog46Example/NLog.config
new file mode 100644
index 000000000000..949f3e82efa6
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/NLog46Example/NLog.config
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/customer-samples/AutomaticTraceIdInjection/NLog46Example/NLog46Example.csproj b/customer-samples/AutomaticTraceIdInjection/NLog46Example/NLog46Example.csproj
new file mode 100644
index 000000000000..1ab72a92facc
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/NLog46Example/NLog46Example.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ netcoreapp2.1
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
\ No newline at end of file
diff --git a/customer-samples/AutomaticTraceIdInjection/NLog46Example/Program.cs b/customer-samples/AutomaticTraceIdInjection/NLog46Example/Program.cs
new file mode 100644
index 000000000000..f682d98dc3bf
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/NLog46Example/Program.cs
@@ -0,0 +1,25 @@
+using Datadog.Trace;
+using NLog;
+
+namespace NLog46Example
+{
+ class Program
+ {
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+ static void Main(string[] args)
+ {
+ using (MappedDiagnosticsLogicalContext.SetScoped("order-number", 1024))
+ {
+ Logger.Info("Message before a trace.");
+
+ using (var scope = Tracer.Instance.StartActive("NLog46Example - Main()"))
+ {
+ Logger.Info("Message during a trace.");
+ }
+
+ Logger.Info("Message after a trace.");
+ }
+ }
+ }
+}
diff --git a/customer-samples/AutomaticTraceIdInjection/NLog46Example/Properties/launchSettings.json b/customer-samples/AutomaticTraceIdInjection/NLog46Example/Properties/launchSettings.json
new file mode 100644
index 000000000000..5d9b9f9e2999
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/NLog46Example/Properties/launchSettings.json
@@ -0,0 +1,11 @@
+{
+ "profiles": {
+ "NLog46Example": {
+ "commandName": "Project",
+ "environmentVariables": {
+ "DD_LOGS_INJECTION": "true"
+ },
+ "nativeDebugging": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/customer-samples/AutomaticTraceIdInjection/README.md b/customer-samples/AutomaticTraceIdInjection/README.md
new file mode 100644
index 000000000000..a93fbcc2f2bd
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/README.md
@@ -0,0 +1,21 @@
+# Automatic Trace ID injection
+Follow the official documentation steps to set up [C# log collection](https://docs.datadoghq.com/logs/log_collection/csharp/) and [automatic trace ID injection](https://docs.datadoghq.com/tracing/connect_logs_and_traces/?tab=net), then run these samples to see the feature in action!
+
+If there is a logging layout that you would like to see documented here, please feel free to reach out with an issue or contribution!
+
+## Supported Logging Frameworks
+### Log4Net
+Layouts configured in the sample:
+- JSON format: `SerializedLayout` (from the `log4net.Ext.Json` NuGet package)
+- Raw format: `PatternLayout` (requires a custom Datadog Log Pipeline for processing)
+
+### NLog
+Layouts configured in the sample:
+- JSON format: `JsonLayout`
+- Raw format: Custom layout (requires a custom Datadog Log Pipeline for processing)
+
+### Serilog
+Layouts configured in the sample:
+- JSON format: `JsonFormatter`
+- JSON format: `CompactJsonFormatter` (from the `Serilog.Formatting.Compact` NuGet package)
+- Raw format: output template (requires a custom Datadog Log Pipeline for processing)
diff --git a/customer-samples/AutomaticTraceIdInjection/SerilogExample/Program.cs b/customer-samples/AutomaticTraceIdInjection/SerilogExample/Program.cs
new file mode 100644
index 000000000000..288b7a0d7eae
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/SerilogExample/Program.cs
@@ -0,0 +1,69 @@
+using System.IO;
+using Datadog.Trace;
+using Serilog;
+using Serilog.Context;
+using Serilog.Formatting.Compact;
+using Serilog.Formatting.Json;
+
+namespace SerilogExample
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ // Regardless of the output layout, your LoggerConfiguration must be
+ // enriched from the LogContext to extract the `dd.trace_id` and `dd.span_id`
+ // properties that are automatically injected by the .NET tracer
+ //
+ // Additions to LoggerConfiguration:
+ // - .Enrich.FromLogContext()
+ var loggerConfiguration = new LoggerConfiguration()
+ .Enrich.FromLogContext()
+ .MinimumLevel.Is(Serilog.Events.LogEventLevel.Information);
+
+ // When using a message template, you must emit all properties using the {Properties} syntax in order to emit `dd.trace_id` and `dd.span_id` (see: https://github.com/serilog/serilog/wiki/Formatting-Output#formatting-plain-text)
+ // This is because Serilog cannot look up these individual keys by name due to the '.' in the key name (see https://github.com/serilog/serilog/wiki/Writing-Log-Events#message-template-syntax)
+ // Additionally, Datadog will only parse log properties if they are in a JSON-like map, and the values for dd.trace_id and dd.span_id must be surrounded by quotes
+ //
+ // Additions to layout:
+ // - {Properties}
+ //
+ loggerConfiguration = loggerConfiguration
+ .WriteTo.File(
+ "log-Serilog-textFile.log",
+ outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Properties} {Message:lj} {NewLine}{Exception}");
+
+ // The built-in JsonFormatter will display all properties by default, so no extra work is needed to emit `dd.trace_id` and `dd.span_id`
+ //
+ // Additions to layout: none
+ //
+ loggerConfiguration = loggerConfiguration
+ .WriteTo.File(
+ new JsonFormatter(),
+ "log-Serilog-jsonFile-allProperties.log");
+
+ // The CompactJsonFormatter from the Serilog.Formatting.Compact NuGet package will display all properties by default, so no extra work is needed to emit `dd.trace_id` and `dd.span_id`
+ //
+ // Additions to layout: none
+ //
+ loggerConfiguration = loggerConfiguration
+ .WriteTo.File(
+ new CompactJsonFormatter(),
+ "log-Serilog-compactJsonFile-allProperties.log");
+
+ // Main procedure
+ var log = loggerConfiguration.CreateLogger();
+ using (LogContext.PushProperty("order-number", 1024))
+ {
+ log.Information("Message before a trace.");
+
+ using (var scope = Tracer.Instance.StartActive("SerilogExample - Main()"))
+ {
+ log.Information("Message during a trace.");
+ }
+
+ log.Information("Message after a trace.");
+ }
+ }
+ }
+}
diff --git a/customer-samples/AutomaticTraceIdInjection/SerilogExample/Properties/launchSettings.json b/customer-samples/AutomaticTraceIdInjection/SerilogExample/Properties/launchSettings.json
new file mode 100644
index 000000000000..7613ba2babb2
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/SerilogExample/Properties/launchSettings.json
@@ -0,0 +1,11 @@
+{
+ "profiles": {
+ "SerilogExample": {
+ "commandName": "Project",
+ "environmentVariables": {
+ "DD_LOGS_INJECTION": "true"
+ },
+ "nativeDebugging": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/customer-samples/AutomaticTraceIdInjection/SerilogExample/SerilogExample.csproj b/customer-samples/AutomaticTraceIdInjection/SerilogExample/SerilogExample.csproj
new file mode 100644
index 000000000000..e77f95022e71
--- /dev/null
+++ b/customer-samples/AutomaticTraceIdInjection/SerilogExample/SerilogExample.csproj
@@ -0,0 +1,15 @@
+
+
+
+ Exe
+ netcoreapp2.1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/customer-samples/customer-samples.sln b/customer-samples/customer-samples.sln
new file mode 100644
index 000000000000..cd391e0562ee
--- /dev/null
+++ b/customer-samples/customer-samples.sln
@@ -0,0 +1,59 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29324.140
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AutomaticTraceIdInjection", "AutomaticTraceIdInjection", "{8AD58831-2198-4661-AC87-EFA754EDC4E9}"
+ ProjectSection(SolutionItems) = preProject
+ AutomaticTraceIdInjection\README.md = AutomaticTraceIdInjection\README.md
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Log4NetExample", "AutomaticTraceIdInjection\Log4NetExample\Log4NetExample.csproj", "{1115F7F9-B6A6-4E4C-8731-E3E875616DF7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SerilogExample", "AutomaticTraceIdInjection\SerilogExample\SerilogExample.csproj", "{51F8B356-6F95-460A-9549-52534B85042D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F901F53D-6A53-421C-91F6-B6E32A65826A}"
+ ProjectSection(SolutionItems) = preProject
+ Directory.Build.props = Directory.Build.props
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NLog45Example", "AutomaticTraceIdInjection\NLog45Example\NLog45Example.csproj", "{B987A36C-111D-41B7-9DA0-35DF790DD450}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NLog46Example", "AutomaticTraceIdInjection\NLog46Example\NLog46Example.csproj", "{82DD704F-20C9-4F77-B3ED-7E555E8077C8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1115F7F9-B6A6-4E4C-8731-E3E875616DF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1115F7F9-B6A6-4E4C-8731-E3E875616DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1115F7F9-B6A6-4E4C-8731-E3E875616DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1115F7F9-B6A6-4E4C-8731-E3E875616DF7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {51F8B356-6F95-460A-9549-52534B85042D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {51F8B356-6F95-460A-9549-52534B85042D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {51F8B356-6F95-460A-9549-52534B85042D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {51F8B356-6F95-460A-9549-52534B85042D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B987A36C-111D-41B7-9DA0-35DF790DD450}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B987A36C-111D-41B7-9DA0-35DF790DD450}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B987A36C-111D-41B7-9DA0-35DF790DD450}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B987A36C-111D-41B7-9DA0-35DF790DD450}.Release|Any CPU.Build.0 = Release|Any CPU
+ {82DD704F-20C9-4F77-B3ED-7E555E8077C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {82DD704F-20C9-4F77-B3ED-7E555E8077C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {82DD704F-20C9-4F77-B3ED-7E555E8077C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {82DD704F-20C9-4F77-B3ED-7E555E8077C8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {1115F7F9-B6A6-4E4C-8731-E3E875616DF7} = {8AD58831-2198-4661-AC87-EFA754EDC4E9}
+ {51F8B356-6F95-460A-9549-52534B85042D} = {8AD58831-2198-4661-AC87-EFA754EDC4E9}
+ {B987A36C-111D-41B7-9DA0-35DF790DD450} = {8AD58831-2198-4661-AC87-EFA754EDC4E9}
+ {82DD704F-20C9-4F77-B3ED-7E555E8077C8} = {8AD58831-2198-4661-AC87-EFA754EDC4E9}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {1C64C3C7-7F87-46D4-88F8-1DB81303FBAC}
+ EndGlobalSection
+EndGlobal