Skip to content

Commit b6fab7a

Browse files
TelemetryExceptionData tests (Azure#27221)
* TelemetryExceptionData tests * avoid net461 and netcore differences * add comments * add clarification * resolve pr comments
1 parent 567f0b1 commit b6fab7a

File tree

2 files changed

+160
-4
lines changed

2 files changed

+160
-4
lines changed

sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/TelemetryExceptionData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public TelemetryExceptionData(int version, LogRecord logRecord) : base(version)
4444
exceptions.Count - MaxExceptionCountToSave);
4545

4646
// we'll add our new exception and parent it to the root exception (first one in the list)
47-
exceptions.Add(new TelemetryExceptionDetails(countExceededException, null, exceptions[0]));
47+
exceptions.Add(new TelemetryExceptionDetails(countExceededException, countExceededException.Message, exceptions[0]));
4848
}
4949

5050
Exceptions = exceptions;

sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/tests/Azure.Monitor.OpenTelemetry.Exporter.Tests/TelemetryExceptionDataTests.cs

Lines changed: 159 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
// Licensed under the MIT License.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.Diagnostics;
7+
using System.Globalization;
8+
using System.Linq;
69
using System.Reflection;
710
using System.Runtime.CompilerServices;
811
using Azure.Monitor.OpenTelemetry.Exporter.Models;
12+
using Microsoft.Extensions.Logging;
913
using Moq;
14+
using OpenTelemetry.Logs;
1015
using Xunit;
1116

1217
namespace Azure.Monitor.OpenTelemetry.Exporter.Tests
@@ -104,8 +109,18 @@ public void CheckThatFileNameAndLineAreCorrectIfAvailable()
104109
var exceptionDetails = new TelemetryExceptionDetails(exception, exception.Message, null);
105110
var stack = exceptionDetails.ParsedStack;
106111

107-
Assert.Equal(line, stack[0].Line);
108-
Assert.Equal(fileName, stack[0].FileName);
112+
// Behavior may vary in some cases and line may return 0
113+
// In this case Line will be null
114+
if (line != 0)
115+
{
116+
Assert.Equal(line, stack[0].Line);
117+
Assert.Equal(fileName, stack[0].FileName);
118+
}
119+
else
120+
{
121+
Assert.Null(stack[0].Line);
122+
Assert.Null(stack[0].FileName);
123+
}
109124
}
110125

111126
[Fact]
@@ -149,7 +164,7 @@ public void SizeOfParsedStackFrameIsLessThanMaxAllowedValue()
149164
}
150165

151166
[Fact]
152-
public void ParentIdISetAsOuterId()
167+
public void ParentIdIsSetAsOuterId()
153168
{
154169
var parentException = new Exception("Parent Exception");
155170
var parentExceptionDetails = new TelemetryExceptionDetails(parentException, parentException.Message, null);
@@ -159,6 +174,147 @@ public void ParentIdISetAsOuterId()
159174
Assert.Equal(parentExceptionDetails.Id, exceptionDetails.OuterId);
160175
}
161176

177+
[Fact]
178+
public void ExceptionDataContainsExceptionDetails()
179+
{
180+
var logRecords = new List<LogRecord>();
181+
using var loggerFactory = LoggerFactory.Create(builder =>
182+
{
183+
builder.AddOpenTelemetry(options =>
184+
{
185+
options.AddInMemoryExporter(logRecords);
186+
});
187+
builder.AddFilter(typeof(LogsHelperTests).FullName, LogLevel.Trace);
188+
});
189+
190+
var logger = loggerFactory.CreateLogger<LogsHelperTests>();
191+
192+
var exception = CreateException(1);
193+
logger.LogWarning(exception, exception.Message);
194+
195+
var exceptionData = new TelemetryExceptionData(2, logRecords[0]);
196+
197+
Assert.Equal(1, exceptionData.Exceptions.Count);
198+
}
199+
200+
[Fact]
201+
public void ExceptionDataContainsExceptionDetailsofAllInnerExceptionsOfAggregateException()
202+
{
203+
var logRecords = new List<LogRecord>();
204+
using var loggerFactory = LoggerFactory.Create(builder =>
205+
{
206+
builder.AddOpenTelemetry(options =>
207+
{
208+
options.AddInMemoryExporter(logRecords);
209+
});
210+
builder.AddFilter(typeof(LogsHelperTests).FullName, LogLevel.Trace);
211+
});
212+
213+
var logger = loggerFactory.CreateLogger<LogsHelperTests>();
214+
215+
Exception innerException1 = new ArgumentException("Inner1");
216+
Exception innerException2 = new ArgumentException("Inner2");
217+
218+
AggregateException aggregateException = new AggregateException("AggregateException", new[] { innerException1, innerException2 });
219+
220+
// Passing "AggregateException" explicitly here instead of using aggregateException.Message
221+
// aggregateException.Message will return different value in case of net461 compared to netcore
222+
logger.LogWarning(aggregateException, "AggregateException");
223+
224+
var exceptionData = new TelemetryExceptionData(2, logRecords[0]);
225+
226+
Assert.Equal(3, exceptionData.Exceptions.Count);
227+
Assert.Equal("AggregateException", exceptionData.Exceptions[0].Message);
228+
Assert.Equal("Inner1", exceptionData.Exceptions[1].Message);
229+
Assert.Equal("Inner2", exceptionData.Exceptions[2].Message);
230+
}
231+
232+
[Fact]
233+
public void ExceptionDataContainsExceptionDetailsWithAllInnerExceptions()
234+
{
235+
var logRecords = new List<LogRecord>();
236+
using var loggerFactory = LoggerFactory.Create(builder =>
237+
{
238+
builder.AddOpenTelemetry(options =>
239+
{
240+
options.AddInMemoryExporter(logRecords);
241+
});
242+
builder.AddFilter(typeof(LogsHelperTests).FullName, LogLevel.Trace);
243+
});
244+
245+
var logger = loggerFactory.CreateLogger<LogsHelperTests>();
246+
247+
var innerException1 = new Exception("Inner1");
248+
249+
var innerexception2 = new Exception("Inner2", innerException1);
250+
251+
var exception = new Exception("Exception", innerexception2);
252+
253+
// Passing "Exception" explicitly here instead of using exception.Message
254+
// exception.Message will return different value in case of net461 compared to netcore
255+
logger.LogWarning(exception, "Exception");
256+
257+
var exceptionData = new TelemetryExceptionData(2, logRecords[0]);
258+
259+
Assert.Equal(3, exceptionData.Exceptions.Count);
260+
Assert.Equal("Exception", exceptionData.Exceptions[0].Message);
261+
Assert.Equal("Inner2", exceptionData.Exceptions[1].Message);
262+
Assert.Equal("Inner1", exceptionData.Exceptions[2].Message);
263+
}
264+
265+
[Fact]
266+
public void AggregateExceptionsWithMultipleNestedExceptionsAreTrimmedAfterReachingMaxCount()
267+
{
268+
var logRecords = new List<LogRecord>();
269+
using var loggerFactory = LoggerFactory.Create(builder =>
270+
{
271+
builder.AddOpenTelemetry(options =>
272+
{
273+
options.AddInMemoryExporter(logRecords);
274+
});
275+
builder.AddFilter(typeof(LogsHelperTests).FullName, LogLevel.Trace);
276+
});
277+
278+
var logger = loggerFactory.CreateLogger<LogsHelperTests>();
279+
280+
int numberOfExceptions = 15;
281+
int maxNumberOfExceptionsAllowed = 10;
282+
List<Exception> innerExceptions = new List<Exception>();
283+
for (int i = 0; i < numberOfExceptions; i++)
284+
{
285+
innerExceptions.Add(new Exception((i + 1).ToString(CultureInfo.InvariantCulture)));
286+
}
287+
288+
AggregateException rootLevelException = new AggregateException("0", innerExceptions);
289+
290+
// Passing "0" explicitly here instead of using rootLevelException.Message
291+
// rootLevelException.Message will return different value in case of net461 compared to netcore
292+
logger.LogWarning(rootLevelException, "0");
293+
294+
var exceptionData = new TelemetryExceptionData(2, logRecords[0]);
295+
296+
Assert.Equal(maxNumberOfExceptionsAllowed + 1, exceptionData.Exceptions.Count);
297+
298+
for (int counter = 0; counter < maxNumberOfExceptionsAllowed; counter++)
299+
{
300+
var details = exceptionData.Exceptions[counter];
301+
302+
Assert.Equal(counter.ToString(CultureInfo.InvariantCulture), details.Message);
303+
}
304+
305+
var firstExceptionInList = exceptionData.Exceptions.First();
306+
var lastExceptionInList = exceptionData.Exceptions.Last();
307+
Assert.Equal(firstExceptionInList.Id, lastExceptionInList.OuterId);
308+
Assert.Equal(typeof(InnerExceptionCountExceededException).FullName, lastExceptionInList.TypeName);
309+
Assert.Equal(
310+
string.Format(
311+
CultureInfo.InvariantCulture,
312+
"The number of inner exceptions was {0} which is larger than {1}, the maximum number allowed during transmission. All but the first {1} have been dropped.",
313+
numberOfExceptions+1,
314+
maxNumberOfExceptionsAllowed),
315+
lastExceptionInList.Message);
316+
}
317+
162318
[MethodImpl(MethodImplOptions.NoInlining)]
163319
private Exception CreateException(int stackDepth)
164320
{

0 commit comments

Comments
 (0)