Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open Telemetry: Adds open telemetry based versioning #4854

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

namespace Microsoft.Azure.Cosmos.Telemetry
{
internal sealed class AppInsightClassicAttributeKeys
using System;
using global::Azure.Core;

internal sealed class AppInsightClassicAttributeKeys : IActivityAttributePopulator
{
/// <summary>
/// Represents the diagnostic namespace for Azure Cosmos.
Expand Down Expand Up @@ -90,5 +93,72 @@ internal sealed class AppInsightClassicAttributeKeys
/// Represents the item count in the operation.
/// </summary>
public const string ItemCount = "db.cosmosdb.item_count";

/// <summary>
/// Represents the type of exception.
/// </summary>
public const string ExceptionType = "exception.type";

/// <summary>
/// Represents the message of the exception.
/// </summary>
public const string ExceptionMessage = "exception.message";

/// <summary>
/// Represents the stack trace of the exception.
/// </summary>
public const string ExceptionStacktrace = "exception.stacktrace";

public void PopulateAttributes(DiagnosticScope scope,
string operationName,
string databaseName,
string containerName,
Uri accountName,
string userAgent,
string machineId,
string clientId,
string connectionMode)
{
scope.AddAttribute(AppInsightClassicAttributeKeys.DbOperation, operationName);
scope.AddAttribute(AppInsightClassicAttributeKeys.DbName, databaseName);
scope.AddAttribute(AppInsightClassicAttributeKeys.ContainerName, containerName);
scope.AddAttribute(AppInsightClassicAttributeKeys.ServerAddress, accountName?.Host);
scope.AddAttribute(AppInsightClassicAttributeKeys.UserAgent, userAgent);
scope.AddAttribute(AppInsightClassicAttributeKeys.MachineId, machineId);
scope.AddAttribute(AppInsightClassicAttributeKeys.ClientId, clientId);
scope.AddAttribute(AppInsightClassicAttributeKeys.ConnectionMode, connectionMode);
}

public void PopulateAttributes(DiagnosticScope scope, Exception exception)
{
scope.AddAttribute(AppInsightClassicAttributeKeys.ExceptionStacktrace, exception.StackTrace);
scope.AddAttribute(AppInsightClassicAttributeKeys.ExceptionType, exception.GetType().Name);

// If Exception is not registered with open Telemetry
if (!OpenTelemetryCoreRecorder.IsExceptionRegistered(exception, scope))
{
scope.AddAttribute(AppInsightClassicAttributeKeys.ExceptionMessage, exception.Message);
}
}

public void PopulateAttributes(DiagnosticScope scope, QueryTextMode? queryTextMode, string operationType, OpenTelemetryAttributes response)
{
scope.AddAttribute(AppInsightClassicAttributeKeys.OperationType, operationType);
if (response != null)
{
scope.AddAttribute(AppInsightClassicAttributeKeys.RequestContentLength, response.RequestContentLength);
scope.AddAttribute(AppInsightClassicAttributeKeys.ResponseContentLength, response.ResponseContentLength);
scope.AddIntegerAttribute(AppInsightClassicAttributeKeys.StatusCode, Convert.ToInt32(response.StatusCode));
scope.AddIntegerAttribute(AppInsightClassicAttributeKeys.SubStatusCode, response.SubStatusCode);
scope.AddIntegerAttribute(AppInsightClassicAttributeKeys.RequestCharge, Convert.ToInt32(response.RequestCharge));
scope.AddAttribute(AppInsightClassicAttributeKeys.ItemCount, response.ItemCount);
scope.AddAttribute(AppInsightClassicAttributeKeys.ActivityId, response.ActivityId);

if (response.Diagnostics != null)
{
scope.AddAttribute(AppInsightClassicAttributeKeys.Region, ClientTelemetryHelper.GetContactedRegions(response.Diagnostics.GetContactedRegions()));
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public static void RecordDiagnosticsForRequests(
Documents.OperationType operationType,
OpenTelemetryAttributes response)
{
if (response.Diagnostics == null)
{
return;
}

if (CosmosDbEventSource.IsEnabled(EventLevel.Warning))
{
if (!DiagnosticsFilterHelper.IsSuccessfulResponse(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------

namespace Microsoft.Azure.Cosmos.Telemetry
{
using System;
using global::Azure.Core;

internal class DatabaseDupAttributeKeys : IActivityAttributePopulator
{
private readonly IActivityAttributePopulator appInsightPopulator;
private readonly IActivityAttributePopulator otelPopulator;

public DatabaseDupAttributeKeys()
{
this.otelPopulator = new OpenTelemetryAttributeKeys();
this.appInsightPopulator = new AppInsightClassicAttributeKeys();
}

public void PopulateAttributes(DiagnosticScope scope, string operationName, string databaseName, string containerName, Uri accountName, string userAgent, string machineId, string clientId, string connectionMode)
{
this.appInsightPopulator.PopulateAttributes(scope, operationName, databaseName, containerName, accountName, userAgent, machineId, clientId, connectionMode);
this.otelPopulator.PopulateAttributes(scope, operationName, databaseName, containerName, accountName, userAgent, machineId, clientId, connectionMode);
}

public void PopulateAttributes(DiagnosticScope scope, Exception exception)
{
this.appInsightPopulator.PopulateAttributes(scope, exception);
this.otelPopulator.PopulateAttributes(scope, exception);
}

public void PopulateAttributes(DiagnosticScope scope, QueryTextMode? queryTextMode, string operationType, OpenTelemetryAttributes response)
{
this.appInsightPopulator.PopulateAttributes(scope, queryTextMode, operationType, response);
this.otelPopulator.PopulateAttributes(scope, queryTextMode, operationType, response);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ------------------------------------------------------------

namespace Microsoft.Azure.Cosmos.Telemetry
{
using System;
using global::Azure.Core;

internal interface IActivityAttributePopulator
{
public void PopulateAttributes(DiagnosticScope scope,
string operationName,
string databaseName,
string containerName,
Uri accountName,
string userAgent,
string machineId,
string clientId,
string connectionMode);

public void PopulateAttributes(DiagnosticScope scope, Exception exception);

public void PopulateAttributes(DiagnosticScope scope,
QueryTextMode? queryTextMode,
string operationType,
OpenTelemetryAttributes response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@

namespace Microsoft.Azure.Cosmos.Telemetry
{
using System;
using global::Azure.Core;

/// <summary>
/// Contains constant string values representing OpenTelemetry attribute keys for monitoring and tracing Cosmos DB operations.
/// These keys follow the OpenTelemetry conventions and the Cosmos DB semantic conventions as outlined in the OpenTelemetry specification.
/// </summary>
/// <remarks>
/// For more details on the semantic conventions, refer to the OpenTelemetry documentation at:
/// <see href="https://opentelemetry.io/docs/specs/semconv/database/cosmosdb/"/>
/// <see href="https://opentelemetry.io/docs/specs/semconv/database/cosmosdb/"/> OpenTelemetry Semantic Conventions 1.28.0 conventions are followed.
/// </remarks>
internal sealed class OpenTelemetryAttributeKeys
internal sealed class OpenTelemetryAttributeKeys : IActivityAttributePopulator
{
// Azure defaults

Expand Down Expand Up @@ -58,6 +61,11 @@ internal sealed class OpenTelemetryAttributeKeys
/// </summary>
public const string ServerAddress = "server.address";

/// <summary>
/// Represents the server address.
/// </summary>
public const string ServerPort = "server.port";

// Cosmos DB specific attributes

/// <summary>
Expand Down Expand Up @@ -115,7 +123,7 @@ internal sealed class OpenTelemetryAttributeKeys
/// <summary>
/// Represents the item count in the operation.
/// </summary>
public const string ItemCount = "db.cosmosdb.item_count";
public const string ItemCount = "db.cosmosdb.row_count";

/// <summary>
/// Represents the activity ID for the operation.
Expand All @@ -135,7 +143,7 @@ internal sealed class OpenTelemetryAttributeKeys
/// <summary>
/// Represents the size of the batch operation.
/// </summary>
public const string BatchSize = "db.operation.batch_size";
public const string BatchSize = "db.operation.batch.size";

/// <summary>
/// Consistency Level
Expand All @@ -158,5 +166,78 @@ internal sealed class OpenTelemetryAttributeKeys
/// Represents the stack trace of the exception.
/// </summary>
public const string ExceptionStacktrace = "exception.stacktrace";

public void PopulateAttributes(DiagnosticScope scope,
string operationName,
string databaseName,
string containerName,
Uri accountName,
string userAgent,
string machineId,
string clientId,
string connectionMode)
{
scope.AddAttribute(OpenTelemetryAttributeKeys.DbOperation, operationName);
scope.AddAttribute(OpenTelemetryAttributeKeys.DbName, databaseName);
scope.AddAttribute(OpenTelemetryAttributeKeys.ContainerName, containerName);
if (accountName != null)
{
scope.AddAttribute(OpenTelemetryAttributeKeys.ServerAddress, accountName.Host);
scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.ServerPort, accountName.Port);
}
scope.AddAttribute(OpenTelemetryAttributeKeys.UserAgent, userAgent);
scope.AddAttribute(OpenTelemetryAttributeKeys.ClientId, clientId);
scope.AddAttribute(OpenTelemetryAttributeKeys.ConnectionMode, connectionMode);
}

public void PopulateAttributes(DiagnosticScope scope, Exception exception)
{
scope.AddAttribute(OpenTelemetryAttributeKeys.ExceptionStacktrace, exception.StackTrace);
scope.AddAttribute(OpenTelemetryAttributeKeys.ExceptionType, exception.GetType().Name);

// If Exception is not registered with open Telemetry
if (!OpenTelemetryCoreRecorder.IsExceptionRegistered(exception, scope))
{
scope.AddAttribute(OpenTelemetryAttributeKeys.ExceptionMessage, exception.Message);
}
}

public void PopulateAttributes(DiagnosticScope scope, QueryTextMode? queryTextMode, string operationType, OpenTelemetryAttributes response)
{
if (response == null)
{
return;
}

if (response.BatchSize is not null)
{
scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.BatchSize, Convert.ToInt32(response.BatchSize));
}

scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.StatusCode, Convert.ToInt32(response.StatusCode));
scope.AddAttribute(OpenTelemetryAttributeKeys.RequestContentLength, response.RequestContentLength);
scope.AddAttribute(OpenTelemetryAttributeKeys.ResponseContentLength, response.ResponseContentLength);
scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.SubStatusCode, response.SubStatusCode);
scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.RequestCharge, Convert.ToInt32(response.RequestCharge));
scope.AddAttribute(OpenTelemetryAttributeKeys.ItemCount, response.ItemCount);
scope.AddAttribute(OpenTelemetryAttributeKeys.ActivityId, response.ActivityId);
scope.AddAttribute(OpenTelemetryAttributeKeys.CorrelatedActivityId, response.CorrelatedActivityId);
scope.AddAttribute(OpenTelemetryAttributeKeys.ConsistencyLevel, response.ConsistencyLevel);

if (response.QuerySpec is not null)
{
if (queryTextMode == QueryTextMode.All ||
(queryTextMode == QueryTextMode.ParameterizedOnly && response.QuerySpec.ShouldSerializeParameters()))
{
scope.AddAttribute(OpenTelemetryAttributeKeys.QueryText, response.QuerySpec?.QueryText);
}
}

if (response.Diagnostics != null)
{
scope.AddAttribute(OpenTelemetryAttributeKeys.Region, ClientTelemetryHelper.GetContactedRegions(response.Diagnostics.GetContactedRegions()));
}

}
}
}
Loading
Loading