Skip to content

Commit

Permalink
Added support for TraceId and SpanId
Browse files Browse the repository at this point in the history
  • Loading branch information
snakefoot committed Dec 17, 2024
1 parent 61c5a0d commit dbc3ab4
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 58 deletions.
2 changes: 1 addition & 1 deletion Benchmark/Benchmark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net48;net6.0</TargetFrameworks>
<TargetFrameworks>net48;net8.0</TargetFrameworks>
<LangVersion>Latest</LangVersion>
<Configurations>Debug;Release;Test;Test</Configurations>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>Latest</LangVersion>
<Configurations>Debug;Release;Test;Test</Configurations>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>Latest</LangVersion>
<Configurations>Debug;Release;Test</Configurations>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\NLog.Targets.OpenTelemetryProtocol\NLog.Targets.OpenTelemetryProtocol.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NLog.Targets.OpenTelemetryProtocol\NLog.Targets.OpenTelemetryProtocol.csproj" />
</ItemGroup>

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

</Project>
2 changes: 2 additions & 0 deletions NLog.Targets.OpenTelemetryProtocol.Test/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public static void Main()

var message = "testing";

using var currentActivity = new System.Diagnostics.Activity("Hello World").Start();

logger.Fatal("message: {messageField}", message);

Thread.Sleep(10000);
Expand Down
52 changes: 52 additions & 0 deletions NLog.Targets.OpenTelemetryProtocol/ActivityExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System.Diagnostics;

namespace NLog.Targets.OpenTelemetryProtocol
{
/// <summary>
/// Formats elements of <see cref="Activity.Current"/> for inclusion in log events. Non-W3C-format activities are
/// ignored (Seq does not support the older Microsoft-proprietary hierarchical activity id format).
/// </summary>
internal static class ActivityExtensions
{
private static readonly System.Diagnostics.ActivitySpanId EmptySpanId = default(System.Diagnostics.ActivitySpanId);
private static readonly System.Diagnostics.ActivityTraceId EmptyTraceId = default(System.Diagnostics.ActivityTraceId);

public static string GetSpanId(this Activity activity)
{
return activity.IdFormat == ActivityIdFormat.W3C ?
SpanIdToHexString(activity.SpanId) :
string.Empty;
}

public static string GetTraceId(this Activity activity)
{
return activity.IdFormat == ActivityIdFormat.W3C ?
TraceIdToHexString(activity.TraceId) :
string.Empty;
}

private static string SpanIdToHexString(ActivitySpanId spanId)
{
if (EmptySpanId.Equals(spanId))
return string.Empty;

var spanHexString = spanId.ToHexString();
if (ReferenceEquals(spanHexString, EmptySpanId.ToHexString()))
return string.Empty;

return spanHexString;
}

private static string TraceIdToHexString(ActivityTraceId traceId)
{
if (EmptyTraceId.Equals(traceId))
return string.Empty;

var traceHexString = traceId.ToHexString();
if (ReferenceEquals(traceHexString, EmptyTraceId.ToHexString()))
return string.Empty;

return traceHexString;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

<ItemGroup>
<PackageReference Include="NLog" Version="5.0.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.10.0-beta.1" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.11.0-rc.1" />
</ItemGroup>

<ItemGroup Condition=" '$(Configuration)' == 'Test' ">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData)
}
}

private void WriteEvent(EventLevel eventLevel, string? eventMessage, IReadOnlyList<object> payload)
private void WriteEvent(EventLevel eventLevel, string eventMessage, IReadOnlyList<object> payload)
{
switch (eventLevel)
{
Expand Down
13 changes: 12 additions & 1 deletion NLog.Targets.OpenTelemetryProtocol/OtlpTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ public class OtlpTarget : TargetWithContext

public Layout ServiceName { get; set; }

public Layout TraceId { get; set; } = Layout.FromMethod(evt => System.Diagnostics.Activity.Current?.GetTraceId());

public Layout SpanId { get; set; } = Layout.FromMethod(evt => System.Diagnostics.Activity.Current?.GetSpanId());

public Layout<int> ScheduledDelayMilliseconds { get; set; } = 5000;

public Layout<int> MaxQueueSize { get; set; } = 2048;
Expand Down Expand Up @@ -246,6 +250,13 @@ protected override void Write(LogEventInfo logEvent)
Timestamp = logEvent.TimeStamp,
};

var spanId = RenderLogEvent(SpanId, logEvent);
if (!string.IsNullOrEmpty(spanId))
data.SpanId = System.Diagnostics.ActivitySpanId.CreateFromString(spanId.AsSpan());
var traceId = RenderLogEvent(TraceId, logEvent);
if (!string.IsNullOrEmpty(traceId))
data.TraceId = System.Diagnostics.ActivityTraceId.CreateFromString(traceId.AsSpan());

if (IncludeFormattedMessage && (logEvent.Parameters?.Length > 0 || logEvent.HasProperties))
{
var formattedMessage = RenderLogEvent(Layout, logEvent);
Expand Down Expand Up @@ -353,7 +364,7 @@ private static LogRecordSeverity ResolveSeverity(LogLevel logLevel)

private OpenTelemetry.Logs.Logger GetLogger(string name)
{
if (!_loggers.TryGetValue(name, out OpenTelemetry.Logs.Logger? logger))
if (!_loggers.TryGetValue(name, out OpenTelemetry.Logs.Logger logger))
{
lock (_sync)
{
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ This target can export logs in the format defined in the OpenTelemetry specifica
For an explanation of the log data model, see https://opentelemetry.io/docs/specs/otel/logs/data-model/. <br>
For an example, see https://opentelemetry.io/docs/specs/otel/protocol/file-exporter/#examples.

**Note that the OpenTelemetry logging API is still unfinished, which means that it is internal in stable releases and public in prelease versions of the OpenTelemetry package.
This package has a reference to OpenTelemetry version 1.9.0-alpha.1. If your project has a reference to a stable version higher than that,
**Note that the OpenTelemetry logging API is still unfinished, which means that it is internal in stable releases and public in pre-release versions of the OpenTelemetry package.
This package has a reference to pre-release version of the OpenTelemetry-nuget-package. If your project has a reference to a stable version higher than that,
you will get a runtime error.**

## Configuration
Expand All @@ -29,7 +29,7 @@ Example XML config:
scheduledDelayMilliseconds="1000"
useDefaultResources="false"
includeFormattedMessage="true"
onlyIncldueParameters="correlationId,messageId">
onlyIncludeProperties="correlationId,messageId">
<attribute name="thread.id" layout="${threadid}" />
<resource name="process.name" layout="${processname}" />
<resource name="process.id" layout="${processid}" />
Expand All @@ -55,6 +55,8 @@ Example XML config:
- **Attribute** : Attributes to be included with each LogEvent (optional)
- _Name_ : Name of Attribute.
- _Layout_ : Value of Attribute (If value is the same for all LogEvents, then add as resource instead)
- **SpanId** : Capture the SpanId value from System.Diagnostics.Activity.Current. Assign to empty value to skip SpanId.
- **TraceId** : Capture the TraceId value from System.Diagnostics.Activity.Current. Assign to empty value to skip TraceId.
- **MaxQueueSize** : The target uses a batch exporter, this defines the max queue size. By default 2048, optional.
- **MaxExportBatchSize** : The target uses a batch exporter, this defines the max batch size. By default 512, optional.
- **ScheduledDelayMilliseconds** : The target uses a batch exporter, this defines how often it is flushed in milliseconds. By default 5000, optional.
Expand Down
2 changes: 1 addition & 1 deletion TestWebApp/TestWebApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.8" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.15" />
</ItemGroup>

<ItemGroup>
Expand Down
72 changes: 36 additions & 36 deletions UnitTests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>

<SignAssembly>True</SignAssembly>

<AssemblyOriginatorKeyFile>debug.snk</AssemblyOriginatorKeyFile>

<Configurations>Debug;Release;Test;Test</Configurations>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NLog.Targets.OpenTelemetryProtocol\NLog.Targets.OpenTelemetryProtocol.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>

<SignAssembly>True</SignAssembly>

<AssemblyOriginatorKeyFile>debug.snk</AssemblyOriginatorKeyFile>

<Configurations>Debug;Release;Test</Configurations>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NLog.Targets.OpenTelemetryProtocol\NLog.Targets.OpenTelemetryProtocol.csproj" />
</ItemGroup>

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

</Project>

0 comments on commit dbc3ab4

Please sign in to comment.