Skip to content

Commit

Permalink
Merge from main
Browse files Browse the repository at this point in the history
  • Loading branch information
stonkie committed Dec 12, 2024
2 parents 04a3eee + a658270 commit 30dca16
Show file tree
Hide file tree
Showing 27 changed files with 659 additions and 116 deletions.
4 changes: 4 additions & 0 deletions src/OpenTelemetry.Api.ProviderBuilderExtensions/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ Notes](../../RELEASENOTES.md).

## Unreleased

## 1.11.0-rc.1

Released 2024-Dec-11

## 1.10.0

Released 2024-Nov-12
Expand Down
4 changes: 4 additions & 0 deletions src/OpenTelemetry.Api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md).

## Unreleased

## 1.11.0-rc.1

Released 2024-Dec-11

## 1.10.0

Released 2024-Nov-12
Expand Down
4 changes: 4 additions & 0 deletions src/OpenTelemetry.Exporter.Console/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md).

## Unreleased

## 1.11.0-rc.1

Released 2024-Dec-11

## 1.10.0

Released 2024-Nov-12
Expand Down
4 changes: 4 additions & 0 deletions src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Notes](../../RELEASENOTES.md).

## Unreleased

## 1.11.0-rc.1

Released 2024-Dec-11

## 1.10.0

Released 2024-Nov-12
Expand Down
30 changes: 30 additions & 0 deletions src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,36 @@ Notes](../../RELEASENOTES.md).

## Unreleased

## 1.11.0-rc.1

Released 2024-Dec-11

* Removed the following package references:

* `Google.Protobuf`
* `Grpc`
* `Grpc.Net.Client`

These changes were made to streamline dependencies and reduce the footprint of
the exporter.
([#6005](https://github.com/open-telemetry/opentelemetry-dotnet/pull/6005))

* Switched from using the `Google.Protobuf` library for serialization to a
custom manual implementation of protobuf serialization.
([#6005](https://github.com/open-telemetry/opentelemetry-dotnet/pull/6005))

* Fixed an issue where a `service.name` was added to the resource if it was
missing. The exporter now respects the resource data provided by the SDK
without modifications.
([#6015](https://github.com/open-telemetry/opentelemetry-dotnet/pull/6015))

* Removed the peer service resolver, which was based on earlier experimental
semantic conventions that are not part of the stable specification. This
change ensures that the exporter no longer modifies or assumes the value of
peer service attributes, aligning it more closely with OpenTelemetry protocol
specifications.
([#6005](https://github.com/open-telemetry/opentelemetry-dotnet/pull/6005))

## 1.10.0

Released 2024-Nov-12
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,12 @@ public void GrpcRetryDelayParsingFailed(string grpcStatusDetailsHeader, string e
this.WriteEvent(24, grpcStatusDetailsHeader, exception);
}

[Event(25, Message = "The array tag buffer exceeded the maximum allowed size. The array tag value was replaced with 'TRUNCATED'", Level = EventLevel.Warning)]
public void ArrayBufferExceededMaxSize()
{
this.WriteEvent(25);
}

void IConfigurationExtensionsLogger.LogInvalidConfigurationValue(string key, string value)
{
this.InvalidConfigurationValue(key, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,26 @@ internal static class ProtobufOtlpLogSerializer
private const int TraceIdSize = 16;
private const int SpanIdSize = 8;

private static readonly Stack<List<LogRecord>> LogsListPool = [];
private static readonly Dictionary<string, List<LogRecord>> ScopeLogsList = [];
[ThreadStatic]
private static Stack<List<LogRecord>>? logsListPool;
[ThreadStatic]
private static Dictionary<string, List<LogRecord>>? scopeLogsList;

[ThreadStatic]
private static SerializationState? threadSerializationState;

internal static int WriteLogsData(byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, ExperimentalOptions experimentalOptions, Resources.Resource? resource, in Batch<LogRecord> logRecordBatch)
internal static int WriteLogsData(ref byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, ExperimentalOptions experimentalOptions, Resources.Resource? resource, in Batch<LogRecord> logRecordBatch)
{
writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpLogFieldNumberConstants.LogsData_Resource_Logs, ProtobufWireType.LEN);
int logsDataLengthPosition = writePosition;
writePosition += ReserveSizeForLength;
logsListPool ??= [];
scopeLogsList ??= [];

foreach (var logRecord in logRecordBatch)
{
var scopeName = logRecord.Logger.Name;
if (!ScopeLogsList.TryGetValue(scopeName, out var logRecords))
if (!scopeLogsList.TryGetValue(scopeName, out var logRecords))
{
logRecords = LogsListPool.Count > 0 ? LogsListPool.Pop() : [];
ScopeLogsList[scopeName] = logRecords;
logRecords = logsListPool.Count > 0 ? logsListPool.Pop() : [];
scopeLogsList[scopeName] = logRecords;
}

if (logRecord.Source == LogRecord.LogRecordSource.FromSharedPool)
Expand All @@ -47,37 +48,45 @@ internal static int WriteLogsData(byte[] buffer, int writePosition, SdkLimitOpti
logRecords.Add(logRecord);
}

writePosition = TryWriteResourceLogs(buffer, writePosition, sdkLimitOptions, experimentalOptions, resource, ScopeLogsList);
ProtobufSerializer.WriteReservedLength(buffer, logsDataLengthPosition, writePosition - (logsDataLengthPosition + ReserveSizeForLength));
writePosition = TryWriteResourceLogs(ref buffer, writePosition, sdkLimitOptions, experimentalOptions, resource, scopeLogsList);
ReturnLogRecordListToPool();

return writePosition;
}

internal static int TryWriteResourceLogs(byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, ExperimentalOptions experimentalOptions, Resources.Resource? resource, Dictionary<string, List<LogRecord>> scopeLogs)
internal static int TryWriteResourceLogs(ref byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, ExperimentalOptions experimentalOptions, Resources.Resource? resource, Dictionary<string, List<LogRecord>> scopeLogs)
{
int entryWritePosition = writePosition;

try
{
writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpLogFieldNumberConstants.LogsData_Resource_Logs, ProtobufWireType.LEN);
int logsDataLengthPosition = writePosition;
writePosition += ReserveSizeForLength;

writePosition = WriteResourceLogs(buffer, writePosition, sdkLimitOptions, experimentalOptions, resource, scopeLogs);

ProtobufSerializer.WriteReservedLength(buffer, logsDataLengthPosition, writePosition - (logsDataLengthPosition + ReserveSizeForLength));
}
catch (IndexOutOfRangeException)
catch (Exception ex) when (ex is IndexOutOfRangeException || ex is ArgumentException)
{
writePosition = entryWritePosition;
if (!ProtobufSerializer.IncreaseBufferSize(ref buffer, OtlpSignalType.Logs))
{
throw;
}

return TryWriteResourceLogs(buffer, writePosition, sdkLimitOptions, experimentalOptions, resource, scopeLogs);
return TryWriteResourceLogs(ref buffer, writePosition, sdkLimitOptions, experimentalOptions, resource, scopeLogs);
}

return writePosition;
}

internal static void ReturnLogRecordListToPool()
{
if (ScopeLogsList.Count != 0)
if (scopeLogsList?.Count != 0)
{
foreach (var entry in ScopeLogsList)
foreach (var entry in scopeLogsList!)
{
foreach (var logRecord in entry.Value)
{
Expand All @@ -92,10 +101,10 @@ internal static void ReturnLogRecordListToPool()
}

entry.Value.Clear();
LogsListPool.Push(entry.Value);
logsListPool?.Push(entry.Value);
}

ScopeLogsList.Clear();
scopeLogsList.Clear();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,71 +13,75 @@ internal static class ProtobufOtlpMetricSerializer
private const int TraceIdSize = 16;
private const int SpanIdSize = 8;

private static readonly Stack<List<Metric>> MetricListPool = [];
private static readonly Dictionary<string, List<Metric>> ScopeMetricsList = [];
[ThreadStatic]
private static Stack<List<Metric>>? metricListPool;
[ThreadStatic]
private static Dictionary<string, List<Metric>>? scopeMetricsList;

private delegate int WriteExemplarFunc(byte[] buffer, int writePosition, in Exemplar exemplar);

internal static int WriteMetricsData(
byte[] buffer,
int writePosition,
Resource? resource,
in Batch<Metric> batch,
bool emitNoRecordedValueNeededDataPoints)
internal static int WriteMetricsData(ref byte[] buffer, int writePosition, Resources.Resource? resource, in Batch<Metric> batch, bool emitNoRecordedValueNeededDataPoints)
{
writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.MetricsData_Resource_Metrics, ProtobufWireType.LEN);
int mericsDataLengthPosition = writePosition;
writePosition += ReserveSizeForLength;
metricListPool ??= [];
scopeMetricsList ??= [];

foreach (var metric in batch)
{
var metricName = metric.MeterName;
if (!ScopeMetricsList.TryGetValue(metricName, out var metrics))
if (!scopeMetricsList.TryGetValue(metricName, out var metrics))
{
metrics = MetricListPool.Count > 0 ? MetricListPool.Pop() : new List<Metric>();
ScopeMetricsList[metricName] = metrics;
metrics = metricListPool.Count > 0 ? metricListPool.Pop() : new List<Metric>();
scopeMetricsList[metricName] = metrics;
}

metrics.Add(metric);
}

writePosition = TryWriteResourceMetrics(buffer, writePosition, resource, ScopeMetricsList, emitNoRecordedValueNeededDataPoints);
ProtobufSerializer.WriteReservedLength(buffer, mericsDataLengthPosition, writePosition - (mericsDataLengthPosition + ReserveSizeForLength));
writePosition = TryWriteResourceMetrics(ref buffer, writePosition, resource, scopeMetricsList, emitNoRecordedValueNeededDataPoints);
ReturnMetricListToPool();

return writePosition;
}

internal static int TryWriteResourceMetrics(byte[] buffer, int writePosition, Resources.Resource? resource, Dictionary<string, List<Metric>> scopeMetrics, bool emitNoRecordedValueNeededDataPoints)
internal static int TryWriteResourceMetrics(ref byte[] buffer, int writePosition, Resources.Resource? resource, Dictionary<string, List<Metric>> scopeMetrics, bool emitNoRecordedValueNeededDataPoints)
{
int entryWritePosition = writePosition;

try
{
writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.MetricsData_Resource_Metrics, ProtobufWireType.LEN);
int mericsDataLengthPosition = writePosition;
writePosition += ReserveSizeForLength;

writePosition = WriteResourceMetrics(buffer, writePosition, resource, scopeMetrics, emitNoRecordedValueNeededDataPoints);

ProtobufSerializer.WriteReservedLength(buffer, mericsDataLengthPosition, writePosition - (mericsDataLengthPosition + ReserveSizeForLength));
}
catch (IndexOutOfRangeException)
catch (Exception ex) when (ex is IndexOutOfRangeException || ex is ArgumentException)
{
writePosition = entryWritePosition;
if (!ProtobufSerializer.IncreaseBufferSize(ref buffer, OtlpSignalType.Metrics))
{
throw;
}

return TryWriteResourceMetrics(buffer, writePosition, resource, scopeMetrics, emitNoRecordedValueNeededDataPoints);
return TryWriteResourceMetrics(ref buffer, writePosition, resource, scopeMetrics, emitNoRecordedValueNeededDataPoints);
}

return writePosition;
}

private static void ReturnMetricListToPool()
{
if (ScopeMetricsList.Count != 0)
if (scopeMetricsList?.Count != 0)
{
foreach (var entry in ScopeMetricsList)
foreach (var entry in scopeMetricsList!)
{
entry.Value.Clear();
MetricListPool.Push(entry.Value);
metricListPool?.Push(entry.Value);
}

ScopeMetricsList.Clear();
scopeMetricsList.Clear();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ internal static class ProtobufOtlpResourceSerializer
{
private const int ReserveSizeForLength = 4;

private static readonly string DefaultServiceName = ResourceBuilder.CreateDefault().Build().Attributes.FirstOrDefault(
kvp => kvp.Key == ResourceSemanticConventions.AttributeServiceName).Value as string ?? "unknown_service";

internal static int WriteResource(byte[] buffer, int writePosition, Resource? resource)
{
ProtobufOtlpTagWriter.OtlpTagWriterState otlpTagWriterState = new ProtobufOtlpTagWriter.OtlpTagWriterState
Expand All @@ -24,41 +21,24 @@ internal static int WriteResource(byte[] buffer, int writePosition, Resource? re
int resourceLengthPosition = otlpTagWriterState.WritePosition;
otlpTagWriterState.WritePosition += ReserveSizeForLength;

bool isServiceNamePresent = false;
if (resource != null && resource != Resource.Empty)
{
if (resource.Attributes is IReadOnlyList<KeyValuePair<string, object>> resourceAttributesList)
{
for (int i = 0; i < resourceAttributesList.Count; i++)
{
var attribute = resourceAttributesList[i];
if (attribute.Key == ResourceSemanticConventions.AttributeServiceName)
{
isServiceNamePresent = true;
}

ProcessResourceAttribute(ref otlpTagWriterState, attribute);
ProcessResourceAttribute(ref otlpTagWriterState, resourceAttributesList[i]);
}
}
else
{
foreach (var attribute in resource.Attributes)
{
if (attribute.Key == ResourceSemanticConventions.AttributeServiceName)
{
isServiceNamePresent = true;
}

ProcessResourceAttribute(ref otlpTagWriterState, attribute);
}
}
}

if (!isServiceNamePresent)
{
ProcessResourceAttribute(ref otlpTagWriterState, new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeServiceName, DefaultServiceName));
}

var resourceLength = otlpTagWriterState.WritePosition - (resourceLengthPosition + ReserveSizeForLength);
ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer, resourceLengthPosition, resourceLength);

Expand Down
Loading

0 comments on commit 30dca16

Please sign in to comment.