-
Notifications
You must be signed in to change notification settings - Fork 497
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Internal] Open Telemetry: Fixes client telemetry error type that is …
…compliant with open telemetry standard (#4948) # Pull Request Template ## Description Address issue #4945 Previous error.type contained detailed error message which wasn't compliant with OpenTelemetry standard [error.type](https://opentelemetry.io/docs/specs/semconv/attributes-registry/error/). This PR generates the error type based on the exception type, status code and sub status code. An example of error.type value: ```"CosmosException_NotFound_ResourceNotFound"``` ## Type of change Please delete options that are not relevant. - [X] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update ## Closing issues #4945 To automatically close an issue: closes #IssueNumber --------- Co-authored-by: Sourabh Jain <sourabhjain@microsoft.com>
- Loading branch information
1 parent
9b2fae6
commit b6afb07
Showing
2 changed files
with
171 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
139 changes: 139 additions & 0 deletions
139
...ure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Telemetry/OpenTelemetryAttributeKeyTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
//------------------------------------------------------------ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
//------------------------------------------------------------ | ||
|
||
namespace Microsoft.Azure.Cosmos.Tests.Telemetry | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Net.Http; | ||
using Microsoft.Azure.Cosmos.Telemetry; | ||
using Microsoft.Azure.Cosmos.Tracing.TraceData; | ||
using Microsoft.Azure.Documents; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
|
||
/// <summary> | ||
/// Tests for <see cref="OpenTelemetryAttributeKeys"/>. | ||
/// </summary> | ||
[TestClass] | ||
public class OpenTelemetryAttributeKeysTests | ||
{ | ||
[TestMethod] | ||
[DataRow(false, null)] | ||
[DataRow(true, "HttpRequestException_NotFound_ResourceNotFound")] | ||
public void AppendErrorTypeForPopulateNetworkMeterDimensionsTests(bool throwException, string expectedResult) | ||
{ | ||
OpenTelemetryAttributeKeys attributePopulator = new OpenTelemetryAttributeKeys(); | ||
HttpStatusCode statusCode = throwException ? HttpStatusCode.NotFound : HttpStatusCode.OK; | ||
int subStatusCode = throwException ? (int)SubStatusCodes.ResourceNotFound : (int)SubStatusCodes.Unknown; | ||
OpenTelemetryAttributes attributes = new OpenTelemetryAttributes | ||
{ | ||
ConsistencyLevel = ConsistencyLevel.Strong.ToString(), | ||
StatusCode = statusCode, | ||
SubStatusCode = subStatusCode, | ||
}; | ||
|
||
CosmosException cosmosException = new CosmosException( | ||
message: "test", | ||
statusCode: statusCode, | ||
subStatusCode: subStatusCode, | ||
activityId: Guid.NewGuid().ToString(), | ||
requestCharge: 1.1); | ||
|
||
// Mock http response message | ||
HttpResponseMessage responseMessage = new HttpResponseMessage(statusCode); | ||
responseMessage.Headers.Add("x-ms-substatus", subStatusCode.ToString()); | ||
|
||
// Mock http exception | ||
HttpRequestException httpRequestException = new HttpRequestException("test"); | ||
|
||
ClientSideRequestStatisticsTraceDatum.HttpResponseStatistics httpStatistics = new ClientSideRequestStatisticsTraceDatum.HttpResponseStatistics( | ||
requestStartTime: DateTime.MinValue, | ||
requestEndTime: DateTime.MinValue, | ||
requestUri: new Uri("https://test.com"), | ||
httpMethod: HttpMethod.Post, | ||
resourceType: ResourceType.Database, | ||
responseMessage: responseMessage, | ||
exception: throwException ? httpRequestException : null, | ||
region: "East US"); | ||
|
||
KeyValuePair<string, object>[] dimensions = attributePopulator.PopulateNetworkMeterDimensions( | ||
operationName: "create_database_if_not_exists", | ||
accountName: new Uri("https://test.com"), | ||
"test_container", | ||
"test_database", | ||
attributes, | ||
throwException ? cosmosException : null, | ||
null, | ||
null, | ||
httpStatistics); | ||
|
||
// Check error.type value | ||
KeyValuePair<string, object> errorType = dimensions.FirstOrDefault(d => d.Key == "error.type"); | ||
Assert.IsNotNull(errorType); | ||
Assert.AreEqual(expectedResult, errorType.Value); | ||
} | ||
|
||
[TestMethod] | ||
[DataRow(false, null)] | ||
[DataRow(true, "CosmosException_NotFound_ResourceNotFound")] | ||
public void AppendErrorTypeForPopulateOperationMeterDimensionsTests(bool throwException, string expectedResult) | ||
{ | ||
OpenTelemetryAttributeKeys attributePopulator = new OpenTelemetryAttributeKeys(); | ||
OpenTelemetryAttributes attributes = new OpenTelemetryAttributes | ||
{ | ||
ConsistencyLevel = ConsistencyLevel.Strong.ToString(), | ||
StatusCode = throwException ? HttpStatusCode.NotFound : HttpStatusCode.OK, | ||
SubStatusCode = throwException ? (int)SubStatusCodes.ResourceNotFound : (int)SubStatusCodes.Unknown, | ||
}; | ||
|
||
Exception innerException = new NotFoundException("Not found"); | ||
CosmosException cosmosException = new CosmosException( | ||
statusCode: HttpStatusCode.NotFound, | ||
message: "Not found", | ||
stackTrace: null, | ||
headers: new Headers { { "x-ms-substatus", ((int)SubStatusCodes.ResourceNotFound).ToString() } }, | ||
trace: null, | ||
error: null, | ||
innerException: innerException); | ||
|
||
KeyValuePair<string, object>[] dimensions = attributePopulator.PopulateOperationMeterDimensions( | ||
operationName: "create_database_if_not_exists", | ||
containerName: "Items", | ||
databaseName: "ToDoList", | ||
accountName: new Uri("https://test.com"), | ||
attributes: attributes, | ||
ex: throwException ? cosmosException : null, | ||
optionFromRequest: null); | ||
|
||
// Check error.type value | ||
KeyValuePair<string, object> errorType = dimensions.FirstOrDefault(d => d.Key == "error.type"); | ||
Assert.IsNotNull(errorType); | ||
Assert.AreEqual(expectedResult, errorType.Value); | ||
} | ||
|
||
[TestMethod] | ||
public void AppendErrorTypeForPopulateOperationMeterDimensionsTests_AbnormalCase() | ||
{ | ||
OpenTelemetryAttributeKeys attributePopulator = new OpenTelemetryAttributeKeys(); | ||
|
||
Exception exception = new NotFoundException("Not found"); | ||
|
||
KeyValuePair<string, object>[] dimensions = attributePopulator.PopulateOperationMeterDimensions( | ||
operationName: "create_database_if_not_exists", | ||
containerName: "Items", | ||
databaseName: "ToDoList", | ||
accountName: new Uri("https://test.com"), | ||
attributes: null, | ||
ex: exception, | ||
optionFromRequest: null); | ||
|
||
// Check error.type value | ||
KeyValuePair<string, object> errorType = dimensions.FirstOrDefault(d => d.Key == "error.type"); | ||
Assert.IsNotNull(errorType); | ||
Assert.AreEqual("NotFoundException__", errorType.Value); | ||
} | ||
} | ||
} |