Skip to content

Commit

Permalink
[Exporter.Instana] nullable support (#1928)
Browse files Browse the repository at this point in the history
Co-authored-by: Piotr Kiełkowicz <[email protected]>
  • Loading branch information
zivaninstana and Kielek authored Jun 26, 2024
1 parent b842339 commit 39526e6
Show file tree
Hide file tree
Showing 14 changed files with 352 additions and 86 deletions.
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#nullable enable
OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions
static OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions.AddInstanaExporter(this OpenTelemetry.Trace.TracerProviderBuilder options) -> OpenTelemetry.Trace.TracerProviderBuilder
static OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions.AddInstanaExporter(this OpenTelemetry.Trace.TracerProviderBuilder! options) -> OpenTelemetry.Trace.TracerProviderBuilder!
221 changes: 203 additions & 18 deletions src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using OpenTelemetry.Internal;

namespace OpenTelemetry.Exporter.Instana.Implementation;

internal enum SpanKind
Expand All @@ -21,62 +23,245 @@ internal enum SpanKind

internal class InstanaSpan
{
public InstanaSpanTransformInfo TransformInfo { get; set; }
private InstanaSpanTransformInfo transformInfo = new InstanaSpanTransformInfo();
private string n = string.Empty;
private string t = string.Empty;
private string lt = string.Empty;
private From f = new From();
private string p = string.Empty;
private string s = string.Empty;
private SpanKind k = SpanKind.NOT_SET;
private long ts;
private long d;
private bool tp;
private int ec;
private Data data = new Data()
{
data = new Dictionary<string, object>(8),
Events = new List<SpanEvent>(8),
Tags = new Dictionary<string, string>(2),
};

public string N { get; internal set; }
public InstanaSpanTransformInfo TransformInfo
{
get => this.transformInfo;
set
{
Guard.ThrowIfNull(value);
this.transformInfo = value;
}
}

public string T { get; internal set; }
public string N
{
get => this.n;
internal set
{
Guard.ThrowIfNull(value);
this.n = value;
}
}

public string Lt { get; internal set; }
public string T
{
get => this.t;
internal set
{
Guard.ThrowIfNull(value);
this.t = value;
}
}

public From F { get; internal set; }
public string Lt
{
get => this.lt;
internal set
{
Guard.ThrowIfNull(value);
this.lt = value;
}
}

public string P { get; internal set; }
public From F
{
get => this.f;
set
{
Guard.ThrowIfNull(value);
this.f = value;
}
}

public string S { get; internal set; }
public string P
{
get => this.p;
internal set
{
Guard.ThrowIfNull(value);
this.p = value;
}
}

public SpanKind K { get; internal set; }
public string S
{
get => this.s;
internal set
{
Guard.ThrowIfNull(value);
this.s = value;
}
}

public Data Data { get; internal set; }
public SpanKind K
{
get => this.k;
internal set
{
Guard.ThrowIfNull(value);
this.k = value;
}
}

public long Ts { get; internal set; }
public Data Data
{
get => this.data;
internal set
{
Guard.ThrowIfNull(value);
this.data = value;
}
}

public long Ts
{
get => this.ts;
internal set
{
Guard.ThrowIfNull(value);
this.ts = value;
}
}

public long D { get; internal set; }
public long D
{
get => this.d;
internal set
{
Guard.ThrowIfNull(value);
this.d = value;
}
}

public bool Tp { get; internal set; }
public bool Tp
{
get => this.tp;
internal set
{
Guard.ThrowIfNull(value);
this.tp = value;
}
}

public int Ec { get; internal set; }
public int Ec
{
get => this.ec;
internal set
{
Guard.ThrowIfNull(value);
this.ec = value;
}
}
}

#pragma warning disable SA1402 // File may only contain a single type
internal class From
#pragma warning restore SA1402 // File may only contain a single type
{
internal From()
{
this.E = string.Empty;
this.H = string.Empty;
}

public string E { get; internal set; }

public string H { get; internal set; }

internal bool IsEmpty()
{
return string.IsNullOrEmpty(this.E) && string.IsNullOrEmpty(this.H);
}
}

#pragma warning disable SA1402 // File may only contain a single type
internal class Data
#pragma warning restore SA1402 // File may only contain a single type
{
private List<SpanEvent> events = new List<SpanEvent>(8);
private Dictionary<string, object> dataField = new Dictionary<string, object>(8);
private Dictionary<string, string> tags = new Dictionary<string, string>(2);

#pragma warning disable SA1300 // Element should begin with upper-case letter
public Dictionary<string, object> data { get; internal set; }

public Dictionary<string, object> data
{
get => this.dataField;
internal set
{
Guard.ThrowIfNull(value);
this.dataField = value;
}
}

#pragma warning restore SA1300 // Element should begin with upper-case letter
public Dictionary<string, string> Tags { get; internal set; }

public List<SpanEvent> Events { get; internal set; }
public Dictionary<string, string> Tags
{
get => this.tags;
internal set
{
Guard.ThrowIfNull(value);
this.tags = value;
}
}

public List<SpanEvent> Events
{
get => this.events;
internal set
{
Guard.ThrowIfNull(value);
this.events = value;
}
}
}

#pragma warning disable SA1402 // File may only contain a single type
internal class SpanEvent
#pragma warning restore SA1402 // File may only contain a single type
{
public string Name { get; internal set; }
private string name = string.Empty;
private Dictionary<string, string> tags = new Dictionary<string, string>();

public string Name
{
get => this.name;
internal set
{
Guard.ThrowIfNull(value);
this.name = value;
}
}

public long Ts { get; internal set; }

public Dictionary<string, string> Tags { get; internal set; }
public Dictionary<string, string> Tags
{
get => this.tags;
internal set
{
Guard.ThrowIfNull(value);
this.tags = value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ internal static class InstanaSpanSerializer
#pragma warning restore SA1310 // Field names should not contain underscore
private static readonly long UnixZeroTime = new DateTime(1970, 1, 1, 0, 0, 0, 0).Ticks;

internal static IEnumerator GetSpanTagsEnumerator(InstanaSpan instanaSpan)
internal static IEnumerator? GetSpanTagsEnumerator(InstanaSpan instanaSpan)
{
return instanaSpan.Data.Tags.GetEnumerator();
}

internal static IEnumerator GetSpanEventsEnumerator(InstanaSpan instanaSpan)
internal static IEnumerator? GetSpanEventsEnumerator(InstanaSpan instanaSpan)
{
return instanaSpan.Data.Events.GetEnumerator();
}
Expand Down Expand Up @@ -95,9 +95,14 @@ private static async Task SerializeTagsAsync(InstanaSpan instanaSpan, StreamWrit
await SerializeTagsLogicAsync(instanaSpan.Data.Tags, writer).ConfigureAwait(false);
}

private static async Task SerializeTagsLogicAsync(Dictionary<string, string> tags, StreamWriter writer)
private static async Task SerializeTagsLogicAsync(Dictionary<string, string>? tags, StreamWriter writer)
{
await writer.WriteAsync(OPEN_BRACE).ConfigureAwait(false);
if (tags == null)
{
return;
}

using (var enumerator = tags.GetEnumerator())
{
byte i = 0;
Expand Down Expand Up @@ -132,7 +137,7 @@ private static async Task SerializeTagsLogicAsync(Dictionary<string, string> tag
await writer.WriteAsync(CLOSE_BRACE).ConfigureAwait(false);
}

private static async Task AppendProperty(string value, string name, StreamWriter json)
private static async Task AppendProperty(string? value, string? name, StreamWriter json)
{
await json.WriteAsync(QUOTE).ConfigureAwait(false);
await json.WriteAsync(name).ConfigureAwait(false);
Expand Down Expand Up @@ -160,6 +165,11 @@ private static async Task AppendObjectAsync(Func<InstanaSpan, StreamWriter, Task
private static async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWriter writer)
{
await writer.WriteAsync(OPEN_BRACE).ConfigureAwait(false);
if (instanaSpan.Data.data == null)
{
return;
}

using (var enumerator = instanaSpan.Data.data.GetEnumerator())
{
byte i = 0;
Expand Down Expand Up @@ -191,15 +201,15 @@ private static async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWrit
}
}

if (instanaSpan.Data.Tags?.Count > 0)
if (instanaSpan.Data.Tags.Count > 0)
{
await writer.WriteAsync(COMMA).ConfigureAwait(false);

// serialize tags
await AppendObjectAsync(SerializeTagsAsync, InstanaExporterConstants.TAGS_FIELD, instanaSpan, writer).ConfigureAwait(false);
}

if (instanaSpan.Data.Events?.Count > 0)
if (instanaSpan.Data.Events.Count > 0)
{
await writer.WriteAsync(COMMA).ConfigureAwait(false);

Expand All @@ -212,6 +222,11 @@ private static async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWrit

private static async Task SerializeEventsAsync(InstanaSpan instanaSpan, StreamWriter writer)
{
if (instanaSpan.Data.Events == null)
{
return;
}

using (var enumerator = instanaSpan.Data.Events.GetEnumerator())
{
byte i = 0;
Expand Down Expand Up @@ -240,7 +255,7 @@ private static async Task SerializeEventsAsync(InstanaSpan instanaSpan, StreamWr
await writer.WriteAsync(DateToUnixMillis(enumerator.Current.Ts).ToString(CultureInfo.InvariantCulture)).ConfigureAwait(false);
await writer.WriteAsync(QUOTE).ConfigureAwait(false);

if (enumerator.Current.Tags?.Count > 0)
if (enumerator.Current.Tags.Count > 0)
{
await writer.WriteAsync(COMMA).ConfigureAwait(false);
await writer.WriteAsync(QUOTE).ConfigureAwait(false);
Expand Down
Loading

0 comments on commit 39526e6

Please sign in to comment.