Skip to content

Commit c96faed

Browse files
xiang17rajkumar-rangarajTimothy Mothra
authored
[Exporter.Geneva] Adding user_events support for logs on Linux - log exporter (open-telemetry#2575)
Co-authored-by: Rajkumar Rangaraj <[email protected]> Co-authored-by: Timothy Mothra <[email protected]>
1 parent 2da7195 commit c96faed

File tree

11 files changed

+1027
-207
lines changed

11 files changed

+1027
-207
lines changed

src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
using System.Runtime.InteropServices;
5+
#if NET
6+
using OpenTelemetry.Exporter.Geneva.EventHeader;
7+
#endif
58
using OpenTelemetry.Exporter.Geneva.MsgPack;
69
using OpenTelemetry.Exporter.Geneva.Tld;
710
using OpenTelemetry.Internal;
@@ -31,6 +34,25 @@ public GenevaLogExporter(GenevaExporterOptions options)
3134

3235
bool useMsgPackExporter;
3336
var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString);
37+
38+
if (connectionStringBuilder.PrivatePreviewEnableUserEvents)
39+
{
40+
#if NET
41+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
42+
{
43+
throw new ArgumentException("Exporting data in user_events is only supported for .NET 8 or later on Linux.");
44+
}
45+
46+
var eventHeaderLogExporter = new EventHeaderLogExporter(options);
47+
this.IsUsingUnixDomainSocket = false;
48+
this.exportLogRecord = eventHeaderLogExporter.Export;
49+
this.exporter = eventHeaderLogExporter;
50+
return;
51+
#else
52+
throw new ArgumentException("Exporting data in user_events is only supported for .NET 8 or later on Linux.");
53+
#endif
54+
}
55+
3456
switch (connectionStringBuilder.Protocol)
3557
{
3658
case TransportProtocol.Etw:

src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ public string EtwSession
7575
public bool PrivatePreviewEnableOtlpProtobufEncoding => this.parts.TryGetValue(nameof(this.PrivatePreviewEnableOtlpProtobufEncoding), out var value)
7676
&& bool.TrueString.Equals(value, StringComparison.OrdinalIgnoreCase);
7777

78+
public bool PrivatePreviewEnableUserEvents => this.parts.TryGetValue(nameof(this.PrivatePreviewEnableUserEvents), out var value)
79+
&& bool.TrueString.Equals(value, StringComparison.OrdinalIgnoreCase);
80+
7881
public string Endpoint
7982
{
8083
get => this.ThrowIfNotExists<string>(nameof(this.Endpoint));
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#if NET
5+
6+
using System.Diagnostics;
7+
using System.Globalization;
8+
using System.Runtime.CompilerServices;
9+
using Microsoft.LinuxTracepoints;
10+
using Microsoft.LinuxTracepoints.Provider;
11+
12+
namespace OpenTelemetry.Exporter.Geneva.EventHeader;
13+
14+
internal static class EventHeaderExporter
15+
{
16+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
17+
public static void Serialize(EventHeaderDynamicBuilder eb, string key, object value)
18+
{
19+
Debug.Assert(value != null, "value was null");
20+
21+
switch (value)
22+
{
23+
// TODO: what are all types that needs to be supported?
24+
case bool vb:
25+
eb.AddUInt8(key, (byte)(vb ? 1 : 0), EventHeaderFieldFormat.Boolean);
26+
break;
27+
case byte vui8:
28+
eb.AddUInt8(key, vui8);
29+
break;
30+
case sbyte vi8:
31+
eb.AddInt8(key, vi8);
32+
break;
33+
case short vi16:
34+
eb.AddInt16(key, vi16);
35+
break;
36+
case ushort vui16:
37+
eb.AddUInt16(key, vui16);
38+
break;
39+
case int vi32:
40+
eb.AddInt32(key, vi32);
41+
break;
42+
case uint vui32:
43+
eb.AddUInt32(key, vui32);
44+
break;
45+
case long vi64:
46+
eb.AddInt64(key, vi64);
47+
break;
48+
case ulong vui64:
49+
eb.AddUInt64(key, vui64);
50+
break;
51+
case float vf:
52+
eb.AddFloat32(key, vf);
53+
break;
54+
case double vd:
55+
eb.AddFloat64(key, vd);
56+
break;
57+
case string vs: // TODO: which type to use? does StringLimit also apply like TldExporter.StringLengthLimit?
58+
eb.AddString16(key, vs);
59+
break;
60+
case DateTime vdt:
61+
// TODO: what format to use? an integer or a string?
62+
string rfc3339String = vdt.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFZ", CultureInfo.InvariantCulture);
63+
eb.AddString16(key, rfc3339String);
64+
break;
65+
66+
case byte[] vui8array:
67+
eb.AddUInt8Array(key, vui8array);
68+
break;
69+
case sbyte[] vi8array:
70+
eb.AddInt8Array(key, vi8array);
71+
break;
72+
case short[] vi16array:
73+
eb.AddInt16Array(key, vi16array);
74+
break;
75+
case ushort[] vui16array:
76+
eb.AddUInt16Array(key, vui16array);
77+
break;
78+
case int[] vi32array:
79+
eb.AddInt32Array(key, vi32array);
80+
break;
81+
case uint[] vui32array:
82+
eb.AddUInt32Array(key, vui32array);
83+
break;
84+
case long[] vi64array:
85+
eb.AddInt64Array(key, vi64array);
86+
break;
87+
case ulong[] vui64array:
88+
eb.AddUInt64Array(key, vui64array);
89+
break;
90+
case float[] vfarray:
91+
eb.AddFloat32Array(key, vfarray);
92+
break;
93+
case double[] vdarray:
94+
eb.AddFloat64Array(key, vdarray);
95+
break;
96+
case string[] vsarray:
97+
eb.AddString16Array(key, vsarray);
98+
break;
99+
case DateTime[] vdtarray:
100+
// TODO: is this ever called?
101+
string[] rfc3339Strings = new string[vdtarray.Length];
102+
for (var i = 0; i < vdtarray.Length; ++i)
103+
{
104+
rfc3339Strings[i] = vdtarray[i].ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFZ", CultureInfo.InvariantCulture);
105+
}
106+
107+
eb.AddString16Array(key, rfc3339Strings);
108+
break;
109+
110+
default:
111+
string repr;
112+
try
113+
{
114+
repr = Convert.ToString(value, CultureInfo.InvariantCulture) ?? string.Empty;
115+
}
116+
catch
117+
{
118+
repr = $"ERROR: type {value!.GetType().FullName} is not supported";
119+
}
120+
121+
eb.AddString16(key, repr);
122+
break;
123+
}
124+
}
125+
}
126+
127+
#endif

0 commit comments

Comments
 (0)