Skip to content

Commit

Permalink
feat: setup boilerplate for data-pipeline integration
Browse files Browse the repository at this point in the history
  • Loading branch information
ganeshnj committed Dec 19, 2024
1 parent c48a1f7 commit 067753f
Show file tree
Hide file tree
Showing 20 changed files with 659 additions and 15 deletions.
28 changes: 14 additions & 14 deletions tracer/build/_build/Build.Steps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ async Task DownloadWafVersion(string libddwafVersion = null, string uncompressFo
.SetConfiguration(BuildConfiguration)
.SetTargetPlatformAnyCPU()
.EnableNoBuild()
.EnableNoRestore()
//.EnableNoRestore()
.CombineWith(targetFrameworks, (p, framework) => p
.SetFramework(framework)
.SetOutput(MonitoringHomeDirectory / framework))
Expand Down Expand Up @@ -1365,7 +1365,7 @@ _ when path.Contains("dependency-libs") => false,
.Where(project => Solution.GetProject(project).GetTargetFrameworks().Contains(Framework))
;

DotnetBuild(projects, framework: Framework);
DotnetBuild(projects, framework: Framework, noRestore: false);
});

Target CompileSamplesWindows => _ => _
Expand Down Expand Up @@ -1567,8 +1567,8 @@ _ when exclude.Contains(x.project.Path) => false,
.SetFramework(Framework)
//.WithMemoryDumpAfter(timeoutInMinutes: 30)
.EnableCrashDumps()
.EnableNoRestore()
.EnableNoBuild()
// .EnableNoRestore()
// .EnableNoBuild()
.SetTestTargetPlatform(TargetPlatform)
.SetIsDebugRun(isDebugRun)
.SetProcessEnvironmentVariable("MonitoringHomeDirectory", MonitoringHomeDirectory)
Expand All @@ -1590,8 +1590,8 @@ _ when exclude.Contains(x.project.Path) => false,
.SetTargetPlatformAnyCPU()
.SetFramework(Framework)
//.WithMemoryDumpAfter(timeoutInMinutes: 30)
.EnableNoRestore()
.EnableNoBuild()
// .EnableNoRestore()
// .EnableNoBuild()
.SetFilter(string.IsNullOrWhiteSpace(Filter) ? "(RunOnWindows=True)&(LoadFromGAC!=True)&(IIS!=True)&(Category!=AzureFunctions)&(SkipInCI!=True)" : Filter)
.SetTestTargetPlatform(TargetPlatform)
.SetIsDebugRun(isDebugRun)
Expand Down Expand Up @@ -2104,8 +2104,8 @@ var name when multiPackageProjects.Contains(name) => false,
// Run these ones in parallel
DotNetTest(config => config
.SetConfiguration(BuildConfiguration)
.EnableNoRestore()
.EnableNoBuild()
// .EnableNoRestore()
// .EnableNoBuild()
.SetFramework(Framework)
//.WithMemoryDumpAfter(timeoutInMinutes: 30)
.EnableCrashDumps()
Expand All @@ -2127,8 +2127,8 @@ var name when multiPackageProjects.Contains(name) => false,
// Run this one separately so we can tail output
DotNetTest(config => config
.SetConfiguration(BuildConfiguration)
.EnableNoRestore()
.EnableNoBuild()
// .EnableNoRestore()
// .EnableNoBuild()
.SetFramework(Framework)
//.WithMemoryDumpAfter(timeoutInMinutes: 30)
.EnableCrashDumps()
Expand Down Expand Up @@ -2185,8 +2185,8 @@ var name when multiPackageProjects.Contains(name) => false,
// Run these ones in parallel
DotNetTest(config => config
.SetConfiguration(BuildConfiguration)
.EnableNoRestore()
.EnableNoBuild()
// .EnableNoRestore()
// .EnableNoBuild()
.SetFramework(Framework)
//.WithMemoryDumpAfter(timeoutInMinutes: 30)
.EnableCrashDumps()
Expand All @@ -2209,8 +2209,8 @@ var name when multiPackageProjects.Contains(name) => false,
// Run this one separately so we can tail output
DotNetTest(config => config
.SetConfiguration(BuildConfiguration)
.EnableNoRestore()
.EnableNoBuild()
// .EnableNoRestore()
// .EnableNoBuild()
.SetFramework(Framework)
//.WithMemoryDumpAfter(timeoutInMinutes: 30)
.EnableCrashDumps()
Expand Down
11 changes: 11 additions & 0 deletions tracer/missing-nullability-files.csv
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ src/Datadog.Trace/HttpOverStreams/IHttpContent.cs
src/Datadog.Trace/Iast/Iast.cs
src/Datadog.Trace/Iast/ITaintedMap.cs
src/Datadog.Trace/Iast/SourceType.cs
src/Datadog.Trace/LibDatadog/ByteSlice.cs
src/Datadog.Trace/LibDatadog/CharSlice.cs
src/Datadog.Trace/LibDatadog/ErrorCode.cs
src/Datadog.Trace/LibDatadog/ErrorHandle.cs
src/Datadog.Trace/LibDatadog/TraceExporter.cs
src/Datadog.Trace/LibDatadog/TraceExporterConfiguration.cs
src/Datadog.Trace/LibDatadog/TraceExporterError.cs
src/Datadog.Trace/LibDatadog/TraceExporterException.cs
src/Datadog.Trace/LibDatadog/TraceExporterInputFormat.cs
src/Datadog.Trace/LibDatadog/TraceExporterNative.cs
src/Datadog.Trace/LibDatadog/TraceExporterOutputFormat.cs
src/Datadog.Trace/PlatformHelpers/AspNetCoreHttpRequestHandler.cs
src/Datadog.Trace/PlatformHelpers/AzureContext.cs
src/Datadog.Trace/PlatformHelpers/ContainerMetadata.cs
Expand Down
8 changes: 8 additions & 0 deletions tracer/src/Datadog.Trace/Agent/AgentWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ internal AgentWriter(IApi api, IStatsAggregator statsAggregator, IDogStatsd stat
_appsecStandaloneEnabled = appsecStandaloneEnabled;
}

~AgentWriter()
{
if (_api is IDisposable disposableApi)
{
disposableApi.Dispose();
}
}

internal event Action Flushed;

internal SpanBuffer ActiveBuffer => _activeBuffer;
Expand Down
6 changes: 6 additions & 0 deletions tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,12 @@ internal static partial class ConfigurationKeys
/// </summary>
public const string RuntimeMetricsEnabled = "DD_RUNTIME_METRICS_ENABLED";

/// <summary>
/// Use libdatadog data pipeline to send traces.
/// Default value is <c>false</c> (disabled).
/// </summary>
public const string DataPipelineEnabled = "DD_DATA_PIPELINE_ENABLED";

/// <summary>
/// Configuration key for when a standalone instance of the Trace Agent needs to be started.
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions tracer/src/Datadog.Trace/Configuration/TracerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public record TracerSettings
private readonly double? _globalSamplingRate;
private readonly bool _runtimeMetricsEnabled;
private readonly string? _customSamplingRules;
private readonly bool _dataPipelineEnabled;

/// <summary>
/// Initializes a new instance of the <see cref="TracerSettings"/> class with default values.
Expand Down Expand Up @@ -331,6 +332,10 @@ _ when x.ToBoolean() is { } boolean => boolean,
.AsBoolResult()
.OverrideWith(in otelRuntimeMetricsEnabled, ErrorLog, defaultValue: false);

_dataPipelineEnabled = config
.WithKeys(ConfigurationKeys.DataPipelineEnabled)
.AsBool(defaultValue: true);

// We should also be writing telemetry for OTEL_LOGS_EXPORTER similar to OTEL_METRICS_EXPORTER, but we don't have a corresponding Datadog config
// When we do, we can insert that here

Expand Down Expand Up @@ -919,6 +924,12 @@ public bool DiagnosticSourceEnabled
/// </summary>
internal bool RuntimeMetricsEnabled => DynamicSettings.RuntimeMetricsEnabled ?? _runtimeMetricsEnabled;

/// <summary>
/// Gets a value indicating whether libdatadog data pipeline
/// is enabled.
/// </summary>
internal bool DataPipelineEnabled => _dataPipelineEnabled;

/// <summary>
/// Gets the comma separated list of url patterns to skip tracing.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions tracer/src/Datadog.Trace/Datadog.Trace.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="ganeshnj.libdatadog" Version="14.3.1-ci.771.163" />
<PackageReference Include="InlineIL.Fody" Version="1.8.0" PrivateAssets="All" />
</ItemGroup>

Expand Down
26 changes: 26 additions & 0 deletions tracer/src/Datadog.Trace/LibDatadog/ByteSlice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// <copyright file="ByteSlice.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

using System;
using System.Runtime.InteropServices;

namespace Datadog.Trace.LibDatadog;

/// <summary>
/// Represents a slice of a byte array in memory.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct ByteSlice
{
/// <summary>
/// Pointer to the start of the slice.
/// </summary>
internal IntPtr Ptr;

/// <summary>
/// Length of the slice.
/// </summary>
internal UIntPtr Len;
}
53 changes: 53 additions & 0 deletions tracer/src/Datadog.Trace/LibDatadog/CharSlice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// <copyright file="CharSlice.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

using System;
using System.Runtime.InteropServices;

namespace Datadog.Trace.LibDatadog;

/// <summary>
/// Represents a slice of a UTF-8 encoded string in memory.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct CharSlice
{
/// <summary>
/// Represents an empty slice.
/// </summary>
internal static CharSlice Empty = new(string.Empty);

/// <summary>
/// Pointer to the start of the slice.
/// </summary>
internal IntPtr Ptr;

/// <summary>
/// Length of the slice.
/// </summary>
internal UIntPtr Len;

/// <summary>
/// Initializes a new instance of the <see cref="CharSlice"/> struct.
/// This can be further optimized if we can avoid copying the string to unmanaged memory.
/// </summary>
/// <param name="str">The string to copy into memory.</param>
internal CharSlice(string str)
{
// copy over str to unmanaged memory
if (str == null)
{
Ptr = IntPtr.Zero;
Len = UIntPtr.Zero;
}
else
{
var bytes = System.Text.Encoding.UTF8.GetBytes(str);
Ptr = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, Ptr, bytes.Length);
Len = (UIntPtr)bytes.Length;
}
}
}
32 changes: 32 additions & 0 deletions tracer/src/Datadog.Trace/LibDatadog/ErrorCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// <copyright file="ErrorCode.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

namespace Datadog.Trace.LibDatadog;

/// <summary>
/// Represents error codes that can occur when exporting traces.
/// </summary>
internal enum ErrorCode
{
AddressInUse = 0,
ConnectionAborted = 1,
ConnectionRefused = 2,
ConnectionReset = 3,
HttpBodyFormat = 4,
HttpBodyTooLong = 5,
HttpClient = 6,
HttpParse = 7,
HttpServer = 8,
HttpUnknown = 9,
HttpWrongStatus = 10,
InvalidArgument = 11,
InvalidData = 12,
InvalidInput = 13,
InvalidUrl = 14,
IoError = 15,
NetworkUnknown = 16,
Serde = 17,
TimedOut = 18,
}
44 changes: 44 additions & 0 deletions tracer/src/Datadog.Trace/LibDatadog/ErrorHandle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// <copyright file="ErrorHandle.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

using System;
using System.Runtime.InteropServices;

namespace Datadog.Trace.LibDatadog;

internal class ErrorHandle : SafeHandle
{
public ErrorHandle()
: base(IntPtr.Zero, true)
{
}

public ErrorHandle(IntPtr handle)
: base(handle, true)
{
SetHandle(handle);
}

public override bool IsInvalid => handle == IntPtr.Zero;

protected override bool ReleaseHandle()
{
TraceExporterNative.ddog_trace_exporter_error_free(handle);
return true;
}

public TraceExporterException ToException()
{
return new TraceExporterException(Marshal.PtrToStructure<TraceExporterError>(handle));
}

public void ThrowIfError()
{
if (!IsInvalid)
{
throw ToException();
}
}
}
69 changes: 69 additions & 0 deletions tracer/src/Datadog.Trace/LibDatadog/TraceExporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// <copyright file="TraceExporter.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Datadog.Trace.Agent;
using Datadog.Trace.Logging;

namespace Datadog.Trace.LibDatadog;

internal class TraceExporter : SafeHandle, IApi
{
private static readonly IDatadogLogger StaticLog = DatadogLogging.GetLoggerFor<TraceExporter>();

private readonly TraceExporterConfiguration _configuration;
private readonly IDatadogLogger _log;

public TraceExporter(
TraceExporterConfiguration configuration,
IDatadogLogger log = null)
: base(IntPtr.Zero, true)
{
_log = log ?? StaticLog;
_configuration = configuration;

_log.Debug("Creating new TraceExporter");
var errPtr = TraceExporterNative.ddog_trace_exporter_new(out var ptr, _configuration);
errPtr.ThrowIfError();
SetHandle(ptr);
}

public override bool IsInvalid => handle == IntPtr.Zero;

public Task<bool> SendTracesAsync(ArraySegment<byte> traces, int numberOfTraces, bool statsComputationEnabled, long numberOfDroppedP0Traces, long numberOfDroppedP0Spans, bool appsecStandaloneEnabled)
{
_log.Debug<int>("Sending {Count} traces to the Datadog Agent.", numberOfTraces);

// Pin the array to get a pointer to the data
// This is recommended if using UnsafeAddrOfPinnedArrayElement to avoid the GC moving the array
var tracesHandle = GCHandle.Alloc(traces.Array, GCHandleType.Pinned);
var tracesSlice = new ByteSlice
{
Ptr = Marshal.UnsafeAddrOfPinnedArrayElement(traces.Array, traces.Offset),
Len = (UIntPtr)traces.Count
};

var responsePtr = IntPtr.Zero;
using var error = TraceExporterNative.ddog_trace_exporter_send(this, tracesSlice, (UIntPtr)numberOfTraces, ref responsePtr);
tracesHandle.Free();
error.ThrowIfError();

return Task.FromResult(true);
}

public Task<bool> SendStatsAsync(StatsBuffer stats, long bucketDuration)
{
_log.Debug("No-op: stats computation happens in the data pipeline.");
return Task.FromResult(true);
}

protected override bool ReleaseHandle()
{
TraceExporterNative.ddog_trace_exporter_free(handle);
return true;
}
}
Loading

0 comments on commit 067753f

Please sign in to comment.