Skip to content

Commit d294e07

Browse files
author
Timothy Mothra
authored
[AzureMonitorExporter] fix more nullables (#34092)
* fix more nullables * update to match spec * cleanup
1 parent 2606ffd commit d294e07

File tree

4 files changed

+44
-43
lines changed

4 files changed

+44
-43
lines changed

sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Customizations/Models/TelemetryItem.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Azure.Monitor.OpenTelemetry.Exporter.Models
1313
{
1414
internal partial class TelemetryItem
1515
{
16-
public TelemetryItem(Activity activity, ref TagEnumerationState monitorTags, AzureMonitorResource resource, string instrumentationKey) :
16+
public TelemetryItem(Activity activity, ref TagEnumerationState monitorTags, AzureMonitorResource? resource, string instrumentationKey) :
1717
this(activity.GetTelemetryType() == TelemetryType.Request ? "Request" : "RemoteDependency", FormatUtcTimestamp(activity.StartTimeUtc))
1818
{
1919
if (activity.ParentSpanId != default)
@@ -73,7 +73,7 @@ public TelemetryItem(string name, TelemetryItem telemetryItem, ActivitySpanId ac
7373
SampleRate = telemetryItem.SampleRate;
7474
}
7575

76-
public TelemetryItem (LogRecord logRecord, AzureMonitorResource resource, string instrumentationKey) :
76+
public TelemetryItem (LogRecord logRecord, AzureMonitorResource? resource, string instrumentationKey) :
7777
this(logRecord.Exception != null ? "Exception" : "Message", FormatUtcTimestamp(logRecord.Timestamp))
7878
{
7979
if (logRecord.TraceId != default)

sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/LogsHelper.cs

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
#nullable disable // TODO: remove and fix errors
5-
64
using System;
75
using System.Collections.Concurrent;
86
using System.Collections.Generic;
@@ -26,7 +24,7 @@ internal class LogsHelper
2624
private static readonly ConcurrentDictionary<int, string> s_depthCache = new ConcurrentDictionary<int, string>();
2725
private static readonly Func<int, string> s_convertDepthToStringRef = ConvertDepthToString;
2826

29-
internal static List<TelemetryItem> OtelToAzureMonitorLogs(Batch<LogRecord> batchLogRecord, AzureMonitorResource resource, string instrumentationKey)
27+
internal static List<TelemetryItem> OtelToAzureMonitorLogs(Batch<LogRecord> batchLogRecord, AzureMonitorResource? resource, string instrumentationKey)
3028
{
3129
List<TelemetryItem> telemetryItems = new List<TelemetryItem>();
3230
TelemetryItem telemetryItem;
@@ -57,15 +55,15 @@ internal static List<TelemetryItem> OtelToAzureMonitorLogs(Batch<LogRecord> batc
5755
return telemetryItems;
5856
}
5957

60-
internal static string GetMessageAndSetProperties(LogRecord logRecord, IDictionary<string, string> properties)
58+
internal static string? GetMessageAndSetProperties(LogRecord logRecord, IDictionary<string, string> properties)
6159
{
62-
string message = logRecord.FormattedMessage;
60+
string? message = logRecord.FormattedMessage;
6361

6462
// Both logRecord.State and logRecord.StateValues will not be set at the same time for LogRecord.
6563
// Either logRecord.State != null or logRecord.StateValues will be called.
6664
if (logRecord.State != null)
6765
{
68-
if (logRecord.State is IReadOnlyCollection<KeyValuePair<string, object>> stateDictionary)
66+
if (logRecord.State is IReadOnlyCollection<KeyValuePair<string, object?>> stateDictionary)
6967
{
7068
ExtractProperties(ref message, properties, stateDictionary);
7169
}
@@ -93,14 +91,14 @@ internal static string GetMessageAndSetProperties(LogRecord logRecord, IDictiona
9391

9492
internal static void WriteScopeInformation(LogRecord logRecord, IDictionary<string, string> properties)
9593
{
96-
StringBuilder builder = null;
94+
StringBuilder? builder = null;
9795
int originalScopeDepth = 1;
9896
logRecord.ForEachScope(ProcessScope, properties);
9997

10098
void ProcessScope(LogRecordScope scope, IDictionary<string, string> properties)
10199
{
102100
int valueDepth = 1;
103-
foreach (KeyValuePair<string, object> scopeItem in scope)
101+
foreach (KeyValuePair<string, object?> scopeItem in scope)
104102
{
105103
if (string.IsNullOrEmpty(scopeItem.Key))
106104
{
@@ -109,7 +107,7 @@ void ProcessScope(LogRecordScope scope, IDictionary<string, string> properties)
109107
}
110108
else if (scopeItem.Key == "{OriginalFormat}")
111109
{
112-
properties.Add($"OriginalFormatScope_{s_depthCache.GetOrAdd(originalScopeDepth, s_convertDepthToStringRef)}", Convert.ToString(scope.Scope.ToString(), CultureInfo.InvariantCulture));
110+
properties.Add($"OriginalFormatScope_{s_depthCache.GetOrAdd(originalScopeDepth, s_convertDepthToStringRef)}", Convert.ToString(scope.Scope?.ToString(), CultureInfo.InvariantCulture));
113111
}
114112
else if (!properties.TryGetValue(scopeItem.Key, out _))
115113
{
@@ -138,8 +136,8 @@ internal static string GetProblemId(Exception exception)
138136
int methodOffset = System.Diagnostics.StackFrame.OFFSET_UNKNOWN;
139137

140138
var exceptionType = exception.GetType().FullName;
141-
var strackTrace = new StackTrace(exception);
142-
var exceptionStackFrame = strackTrace.GetFrame(0);
139+
var stackTrace = new StackTrace(exception);
140+
var exceptionStackFrame = stackTrace.GetFrame(0);
143141

144142
if (exceptionStackFrame != null)
145143
{
@@ -187,27 +185,30 @@ internal static SeverityLevel GetSeverityLevel(LogLevel logLevel)
187185
}
188186
}
189187

190-
private static void ExtractProperties(ref string message, IDictionary<string, string> properties, IReadOnlyCollection<KeyValuePair<string, object>> stateDictionary)
188+
private static void ExtractProperties(ref string? message, IDictionary<string, string> properties, IReadOnlyCollection<KeyValuePair<string, object?>> stateDictionary)
191189
{
192-
foreach (KeyValuePair<string, object> item in stateDictionary)
190+
foreach (KeyValuePair<string, object?> item in stateDictionary)
193191
{
194-
if (item.Key == "{OriginalFormat}")
192+
if (item.Key.Length <= SchemaConstants.KVP_MaxKeyLength && item.Value != null)
195193
{
196-
if (message == null)
194+
// Note: if Key exceeds MaxLength, the entire KVP will be dropped.
195+
196+
if (item.Key == "{OriginalFormat}")
197197
{
198-
message = item.Value.ToString();
198+
if (message == null)
199+
{
200+
message = item.Value.ToString();
201+
}
202+
else
203+
{
204+
properties.Add("OriginalFormat", item.Value.ToString().Truncate(SchemaConstants.KVP_MaxValueLength));
205+
}
199206
}
200207
else
201208
{
202-
properties.Add("OriginalFormat", item.Value.ToString().Truncate(SchemaConstants.KVP_MaxValueLength));
209+
properties.Add(item.Key, item.Value.ToString().Truncate(SchemaConstants.KVP_MaxValueLength));
203210
}
204211
}
205-
else if (item.Key.Length <= SchemaConstants.KVP_MaxKeyLength)
206-
{
207-
// Note: if Key exceeds MaxLength, the entire KVP will be dropped.
208-
209-
properties.Add(item.Key, item.Value.ToString().Truncate(SchemaConstants.KVP_MaxValueLength));
210-
}
211212
}
212213
}
213214

sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/TagEnumerationState.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ internal struct TagEnumerationState
6969
private OperationType _tempActivityType;
7070
public OperationType activityType;
7171

72-
public void ForEach(IEnumerable<KeyValuePair<string, object>> activityTags)
72+
public void ForEach(IEnumerable<KeyValuePair<string, object?>> activityTags)
7373
{
74-
foreach (KeyValuePair<string, object> activityTag in activityTags)
74+
foreach (KeyValuePair<string, object?> activityTag in activityTags)
7575
{
7676
if (activityTag.Value == null)
7777
{

sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/TraceHelper.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
#nullable disable // TODO: remove and fix errors
5-
64
using System;
75
using System.Collections.Generic;
86
using System.Diagnostics;
@@ -21,7 +19,7 @@ internal static class TraceHelper
2119
private const int Version = 2;
2220
private const int MaxlinksAllowed = 100;
2321

24-
internal static List<TelemetryItem> OtelToAzureMonitorTrace(Batch<Activity> batchActivity, AzureMonitorResource resource, string instrumentationKey)
22+
internal static List<TelemetryItem> OtelToAzureMonitorTrace(Batch<Activity> batchActivity, AzureMonitorResource? resource, string instrumentationKey)
2523
{
2624
List<TelemetryItem> telemetryItems = new List<TelemetryItem>();
2725
TelemetryItem telemetryItem;
@@ -144,7 +142,7 @@ internal static TagEnumerationState EnumerateActivityTags(Activity activity)
144142
return monitorTags;
145143
}
146144

147-
internal static string GetLocationIp(ref AzMonList MappedTags)
145+
internal static string? GetLocationIp(ref AzMonList MappedTags)
148146
{
149147
var httpClientIp = AzMonList.GetTagValue(ref MappedTags, SemanticConventions.AttributeHttpClientIP)?.ToString();
150148
if (!string.IsNullOrWhiteSpace(httpClientIp))
@@ -161,14 +159,16 @@ internal static string GetOperationName(Activity activity, ref AzMonList MappedT
161159
if (!string.IsNullOrWhiteSpace(httpMethod))
162160
{
163161
var httpRoute = AzMonList.GetTagValue(ref MappedTags, SemanticConventions.AttributeHttpRoute)?.ToString();
162+
164163
// ASP.NET instrumentation assigns route as {controller}/{action}/{id} which would result in the same name for different operations.
165164
// To work around that we will use path from httpUrl.
166-
if (!string.IsNullOrWhiteSpace(httpRoute) && !httpRoute.Contains("{controller}"))
165+
if (!string.IsNullOrWhiteSpace(httpRoute) && !httpRoute!.Contains("{controller}"))
167166
{
168167
return $"{httpMethod} {httpRoute}";
169168
}
169+
170170
var httpUrl = AzMonList.GetTagValue(ref MappedTags, SemanticConventions.AttributeHttpUrl)?.ToString();
171-
if (!string.IsNullOrWhiteSpace(httpUrl) && Uri.TryCreate(httpUrl.ToString(), UriKind.RelativeOrAbsolute, out var uri) && uri.IsAbsoluteUri)
171+
if (!string.IsNullOrWhiteSpace(httpUrl) && Uri.TryCreate(httpUrl!.ToString(), UriKind.RelativeOrAbsolute, out var uri) && uri.IsAbsoluteUri)
172172
{
173173
return $"{httpMethod} {uri.AbsolutePath}";
174174
}
@@ -211,7 +211,7 @@ private static void AddTelemetryFromActivityEvents(Activity activity, TelemetryI
211211
}
212212
}
213213

214-
private static MonitorBase GetTraceTelemetryData(ActivityEvent activityEvent)
214+
private static MonitorBase? GetTraceTelemetryData(ActivityEvent activityEvent)
215215
{
216216
if (activityEvent.Name == null)
217217
{
@@ -228,7 +228,7 @@ private static MonitorBase GetTraceTelemetryData(ActivityEvent activityEvent)
228228
}
229229
else
230230
{
231-
messageData.Properties.Add(tag.Key, tag.Value.ToString());
231+
messageData.Properties.Add(tag.Key, tag.Value?.ToString());
232232
}
233233
}
234234

@@ -239,29 +239,29 @@ private static MonitorBase GetTraceTelemetryData(ActivityEvent activityEvent)
239239
};
240240
}
241241

242-
private static MonitorBase GetExceptionDataDetailsOnTelemetryItem(IEnumerable<KeyValuePair<string, object>> activityEventTags)
242+
private static MonitorBase? GetExceptionDataDetailsOnTelemetryItem(IEnumerable<KeyValuePair<string, object?>> activityEventTags)
243243
{
244-
string exceptionType = null;
245-
string exceptionStackTrace = null;
246-
string exceptionMessage = null;
244+
string? exceptionType = null;
245+
string? exceptionStackTrace = null;
246+
string? exceptionMessage = null;
247247

248248
// TODO: update to use perf improvements in .NET7.0
249249
foreach (var tag in activityEventTags)
250250
{
251251
// TODO: see if these can be cached
252252
if (tag.Key == SemanticConventions.AttributeExceptionType)
253253
{
254-
exceptionType = tag.Value.ToString();
254+
exceptionType = tag.Value?.ToString();
255255
continue;
256256
}
257257
if (tag.Key == SemanticConventions.AttributeExceptionMessage)
258258
{
259-
exceptionMessage = tag.Value.ToString();
259+
exceptionMessage = tag.Value?.ToString();
260260
continue;
261261
}
262262
if (tag.Key == SemanticConventions.AttributeExceptionStacktrace)
263263
{
264-
exceptionStackTrace = tag.Value.ToString();
264+
exceptionStackTrace = tag.Value?.ToString();
265265
continue;
266266
}
267267
}
@@ -275,7 +275,7 @@ private static MonitorBase GetExceptionDataDetailsOnTelemetryItem(IEnumerable<Ke
275275
{
276276
Stack = exceptionStackTrace.Truncate(SchemaConstants.ExceptionDetails_Stack_MaxLength),
277277

278-
HasFullStack = exceptionStackTrace.Length <= SchemaConstants.ExceptionDetails_Stack_MaxLength,
278+
HasFullStack = exceptionStackTrace != null && (exceptionStackTrace.Length <= SchemaConstants.ExceptionDetails_Stack_MaxLength),
279279

280280
// TODO: Update swagger schema to mandate typename.
281281
TypeName = exceptionType.Truncate(SchemaConstants.ExceptionDetails_TypeName_MaxLength),

0 commit comments

Comments
 (0)