Skip to content

Commit 02c4a19

Browse files
authored
refactor: Move UDP Exporter to Standalone Package (#183)
1 parent 8f8ca67 commit 02c4a19

File tree

15 files changed

+762
-1
lines changed

15 files changed

+762
-1
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<Version>0.1.0</Version>
4+
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
5+
<TargetFrameworks>net6.0</TargetFrameworks>
6+
<TargetFrameworks Condition="$(OS) == 'Windows_NT'">$(TargetFrameworks);net462</TargetFrameworks>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>enable</Nullable>
9+
<SignAssembly>true</SignAssembly>
10+
<AssemblyOriginatorKeyFile>../../buildtools/awsoteldotnet.snk</AssemblyOriginatorKeyFile>
11+
</PropertyGroup>
12+
13+
<PropertyGroup Condition="'$(TargetFramework)' == 'net462'">
14+
<LangVersion>10.0</LangVersion>
15+
</PropertyGroup>
16+
17+
<ItemGroup>
18+
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
19+
<PackageReference Include="OpenTelemetry" Version="1.9.0" />
20+
<PackageReference Include="OpenTelemetry.Api" Version="1.9.0" />
21+
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
22+
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
23+
<PackageReference Include="Google.Protobuf" Version="3.28.2" />
24+
<PackageReference Include="Grpc.Tools" Version="2.65.0" PrivateAssets="all" />
25+
</ItemGroup>
26+
27+
<ItemGroup>
28+
<Protobuf Include="opentelemetry\proto\collector\trace\v1\trace_service.proto" GrpcServices="none" ProtoRoot="." />
29+
<Protobuf Include="opentelemetry\proto\trace\v1\trace.proto" GrpcServices="none" ProtoRoot="." />
30+
<Protobuf Include="opentelemetry\proto\resource\v1\resource.proto" GrpcServices="none" ProtoRoot="." />
31+
<Protobuf Include="opentelemetry\proto\common\v1\common.proto" GrpcServices="none" ProtoRoot="." />
32+
</ItemGroup>
33+
</Project>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using Microsoft.Extensions.Logging;
5+
6+
namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Logging;
7+
8+
/// <summary>
9+
/// ConsoleLogger class
10+
/// </summary>
11+
public class ConsoleLogger : ILogger
12+
{
13+
private readonly string categoryName;
14+
private readonly LogLevel minLogLevel;
15+
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="ConsoleLogger"/> class.
18+
/// </summary>
19+
/// <param name="categoryName">The class that is writing the log</param>
20+
/// <param name="minLogLevel">The log level from the log statement</param>
21+
public ConsoleLogger(string categoryName, LogLevel minLogLevel)
22+
{
23+
this.categoryName = categoryName;
24+
this.minLogLevel = minLogLevel;
25+
}
26+
27+
/// <inheritdoc/>
28+
public IDisposable? BeginScope<TState>(TState state)
29+
where TState : notnull
30+
{
31+
// Scopes are not implemented in this simple logger
32+
return NullScope.Instance;
33+
}
34+
35+
/// <inheritdoc/>
36+
public bool IsEnabled(LogLevel logLevel)
37+
{
38+
return logLevel != LogLevel.None && logLevel >= this.minLogLevel;
39+
}
40+
41+
/// <inheritdoc/>
42+
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
43+
{
44+
if (!this.IsEnabled(logLevel))
45+
{
46+
return;
47+
}
48+
49+
if (formatter == null)
50+
{
51+
throw new ArgumentNullException(nameof(formatter));
52+
}
53+
54+
string message = formatter(state, exception);
55+
56+
if (string.IsNullOrEmpty(message) && exception == null)
57+
{
58+
return;
59+
}
60+
61+
string logLevelString = this.GetLogLevelString(logLevel);
62+
63+
Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [{logLevelString}] {this.categoryName}: {message}");
64+
65+
if (exception != null)
66+
{
67+
Console.WriteLine(exception.ToString());
68+
}
69+
}
70+
71+
private string GetLogLevelString(LogLevel logLevel)
72+
{
73+
return logLevel switch
74+
{
75+
LogLevel.Trace => "Trace",
76+
LogLevel.Debug => "Debug",
77+
LogLevel.Information => "Info",
78+
LogLevel.Warning => "Warning",
79+
LogLevel.Error => "Error",
80+
LogLevel.Critical => "Critical",
81+
_ => "Unknown",
82+
};
83+
}
84+
85+
private class NullScope : IDisposable
86+
{
87+
public static NullScope Instance { get; } = new NullScope();
88+
89+
public void Dispose()
90+
{
91+
}
92+
}
93+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using Microsoft.Extensions.Logging;
5+
6+
namespace AWS.Distro.OpenTelemetry.AutoInstrumentation.Logging;
7+
8+
/// <summary>
9+
/// ConsoleLoggerProvider class
10+
/// </summary>
11+
public class ConsoleLoggerProvider : ILoggerProvider
12+
{
13+
private readonly LogLevel minLogLevel;
14+
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="ConsoleLoggerProvider"/> class.
17+
/// </summary>
18+
public ConsoleLoggerProvider()
19+
{
20+
// Read the log level from the environment variable
21+
string logLevelEnv = Environment.GetEnvironmentVariable("APPLICATION_SIGNALS_LOG_LEVEL") ?? "Information";
22+
23+
if (!Enum.TryParse<LogLevel>(logLevelEnv, true, out this.minLogLevel))
24+
{
25+
this.minLogLevel = LogLevel.Information;
26+
}
27+
}
28+
29+
/// <inheritdoc/>
30+
public ILogger CreateLogger(string categoryName)
31+
{
32+
return new ConsoleLogger(categoryName, this.minLogLevel);
33+
}
34+
35+
/// <inheritdoc/>
36+
public void Dispose()
37+
{
38+
// Dispose resources if necessary
39+
}
40+
}

src/AWS.Distro.OpenTelemetry.AutoInstrumentation/OtlpExporterUtils.cs renamed to exporters/AWS.OpenTelemetry.Exporter.Otlp.Udp/OtlpExporterUtils.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
using OpenTelemetry.Resources;
1414
using OtlpResource = OpenTelemetry.Proto.Resource.V1;
1515

16+
namespace AWS.OpenTelemetry.Exporter.Otlp.Udp;
17+
1618
public class OtlpExporterUtils
1719
{
1820
private static readonly ILoggerFactory Factory = LoggerFactory.Create(builder => builder.AddProvider(new ConsoleLoggerProvider()));

src/AWS.Distro.OpenTelemetry.AutoInstrumentation/OtlpUdpExporter.cs renamed to exporters/AWS.OpenTelemetry.Exporter.Otlp.Udp/OtlpUdpExporter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using OpenTelemetry;
1010
using OpenTelemetry.Resources;
1111

12+
namespace AWS.OpenTelemetry.Exporter.Otlp.Udp;
13+
1214
/// <summary>
1315
/// OTLP UDP Exporter class. This class is used to build an OtlpUdpExporter to registered as in exporter
1416
/// during the instrumentation initialization phase
@@ -138,4 +140,4 @@ internal void Shutdown()
138140
throw new ArgumentException($"Invalid endpoint: {endpoint}", ex);
139141
}
140142
}
141-
}
143+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# OpenTelemetry Proto
2+
3+
This package describes the OpenTelemetry protocol. This code was copied from [OpenTelemetry/Proto](https://github.com/open-telemetry/opentelemetry-proto/tree/7312bdf63218acf27fe96430b7231de37fd091f2/opentelemetry/proto). The commit ID for that is `7312bdf63218acf27fe96430b7231de37fd091f2` for reference and tracking purposes.
4+
5+
Please refer to the Upstream package [README](https://github.com/open-telemetry/opentelemetry-proto/blob/7312bdf63218acf27fe96430b7231de37fd091f2/README.md) for more details.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# OpenTelemetry Collector Proto
2+
3+
This package describes the OpenTelemetry collector protocol.
4+
5+
## Packages
6+
7+
1. `common` package contains the common messages shared between different services.
8+
2. `trace` package contains the Trace Service protos.
9+
3. `metrics` package contains the Metrics Service protos.
10+
4. `logs` package contains the Logs Service protos.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2019, OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
syntax = "proto3";
16+
17+
package opentelemetry.proto.collector.trace.v1;
18+
19+
import "opentelemetry/proto/trace/v1/trace.proto";
20+
21+
option csharp_namespace = "OpenTelemetry.Proto.Collector.Trace.V1";
22+
option java_multiple_files = true;
23+
option java_package = "io.opentelemetry.proto.collector.trace.v1";
24+
option java_outer_classname = "TraceServiceProto";
25+
option go_package = "go.opentelemetry.io/proto/otlp/collector/trace/v1";
26+
27+
// Service that can be used to push spans between one Application instrumented with
28+
// OpenTelemetry and a collector, or between a collector and a central collector (in this
29+
// case spans are sent/received to/from multiple Applications).
30+
service TraceService {
31+
// For performance reasons, it is recommended to keep this RPC
32+
// alive for the entire life of the application.
33+
rpc Export(ExportTraceServiceRequest) returns (ExportTraceServiceResponse) {}
34+
}
35+
36+
message ExportTraceServiceRequest {
37+
// An array of ResourceSpans.
38+
// For data coming from a single resource this array will typically contain one
39+
// element. Intermediary nodes (such as OpenTelemetry Collector) that receive
40+
// data from multiple origins typically batch the data before forwarding further and
41+
// in that case this array will contain multiple elements.
42+
repeated opentelemetry.proto.trace.v1.ResourceSpans resource_spans = 1;
43+
}
44+
45+
message ExportTraceServiceResponse {
46+
// The details of a partially successful export request.
47+
//
48+
// If the request is only partially accepted
49+
// (i.e. when the server accepts only parts of the data and rejects the rest)
50+
// the server MUST initialize the `partial_success` field and MUST
51+
// set the `rejected_<signal>` with the number of items it rejected.
52+
//
53+
// Servers MAY also make use of the `partial_success` field to convey
54+
// warnings/suggestions to senders even when the request was fully accepted.
55+
// In such cases, the `rejected_<signal>` MUST have a value of `0` and
56+
// the `error_message` MUST be non-empty.
57+
//
58+
// A `partial_success` message with an empty value (rejected_<signal> = 0 and
59+
// `error_message` = "") is equivalent to it not being set/present. Senders
60+
// SHOULD interpret it the same way as in the full success case.
61+
ExportTracePartialSuccess partial_success = 1;
62+
}
63+
64+
message ExportTracePartialSuccess {
65+
// The number of rejected spans.
66+
//
67+
// A `rejected_<signal>` field holding a `0` value indicates that the
68+
// request was fully accepted.
69+
int64 rejected_spans = 1;
70+
71+
// A developer-facing human-readable message in English. It should be used
72+
// either to explain why the server rejected parts of the data during a partial
73+
// success or to convey warnings/suggestions during a full success. The message
74+
// should offer guidance on how users can address such issues.
75+
//
76+
// error_message is an optional field. An error_message with an empty value
77+
// is equivalent to it not being set.
78+
string error_message = 2;
79+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# This is an API configuration to generate an HTTP/JSON -> gRPC gateway for the
2+
# OpenTelemetry service using github.com/grpc-ecosystem/grpc-gateway.
3+
type: google.api.Service
4+
config_version: 3
5+
http:
6+
rules:
7+
- selector: opentelemetry.proto.collector.trace.v1.TraceService.Export
8+
post: /v1/traces
9+
body: "*"
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2019, OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
syntax = "proto3";
16+
17+
package opentelemetry.proto.common.v1;
18+
19+
option csharp_namespace = "OpenTelemetry.Proto.Common.V1";
20+
option java_multiple_files = true;
21+
option java_package = "io.opentelemetry.proto.common.v1";
22+
option java_outer_classname = "CommonProto";
23+
option go_package = "go.opentelemetry.io/proto/otlp/common/v1";
24+
25+
// AnyValue is used to represent any type of attribute value. AnyValue may contain a
26+
// primitive value such as a string or integer or it may contain an arbitrary nested
27+
// object containing arrays, key-value lists and primitives.
28+
message AnyValue {
29+
// The value is one of the listed fields. It is valid for all values to be unspecified
30+
// in which case this AnyValue is considered to be "empty".
31+
oneof value {
32+
string string_value = 1;
33+
bool bool_value = 2;
34+
int64 int_value = 3;
35+
double double_value = 4;
36+
ArrayValue array_value = 5;
37+
KeyValueList kvlist_value = 6;
38+
bytes bytes_value = 7;
39+
}
40+
}
41+
42+
// ArrayValue is a list of AnyValue messages. We need ArrayValue as a message
43+
// since oneof in AnyValue does not allow repeated fields.
44+
message ArrayValue {
45+
// Array of values. The array may be empty (contain 0 elements).
46+
repeated AnyValue values = 1;
47+
}
48+
49+
// KeyValueList is a list of KeyValue messages. We need KeyValueList as a message
50+
// since `oneof` in AnyValue does not allow repeated fields. Everywhere else where we need
51+
// a list of KeyValue messages (e.g. in Span) we use `repeated KeyValue` directly to
52+
// avoid unnecessary extra wrapping (which slows down the protocol). The 2 approaches
53+
// are semantically equivalent.
54+
message KeyValueList {
55+
// A collection of key/value pairs of key-value pairs. The list may be empty (may
56+
// contain 0 elements).
57+
// The keys MUST be unique (it is not allowed to have more than one
58+
// value with the same key).
59+
repeated KeyValue values = 1;
60+
}
61+
62+
// KeyValue is a key-value pair that is used to store Span attributes, Link
63+
// attributes, etc.
64+
message KeyValue {
65+
string key = 1;
66+
AnyValue value = 2;
67+
}
68+
69+
// InstrumentationScope is a message representing the instrumentation scope information
70+
// such as the fully qualified name and version.
71+
message InstrumentationScope {
72+
// An empty instrumentation scope name means the name is unknown.
73+
string name = 1;
74+
string version = 2;
75+
76+
// Additional attributes that describe the scope. [Optional].
77+
// Attribute keys MUST be unique (it is not allowed to have more than one
78+
// attribute with the same key).
79+
repeated KeyValue attributes = 3;
80+
uint32 dropped_attributes_count = 4;
81+
}

0 commit comments

Comments
 (0)