Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sourabh1007 committed Oct 25, 2024
1 parent 4a70bc3 commit 987f979
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

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

internal sealed class AppInsightClassicAttributeKeys
{
/// <summary>
Expand Down Expand Up @@ -90,5 +93,71 @@ 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 static void PopulateAttributes(DiagnosticScope scope,
string operationName,
string databaseName,
string containerName,
string 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);
scope.AddAttribute(AppInsightClassicAttributeKeys.UserAgent, userAgent);
scope.AddAttribute(AppInsightClassicAttributeKeys.MachineId, machineId);
scope.AddAttribute(AppInsightClassicAttributeKeys.ClientId, clientId);
scope.AddAttribute(AppInsightClassicAttributeKeys.ConnectionMode, connectionMode);
}

public static 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 static void PopulateAttributes(DiagnosticScope scope, 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, (int)response.StatusCode);
scope.AddIntegerAttribute(AppInsightClassicAttributeKeys.SubStatusCode, response.SubStatusCode);
scope.AddIntegerAttribute(AppInsightClassicAttributeKeys.RequestCharge, (int)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
Expand Up @@ -4,6 +4,9 @@

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.
Expand Down Expand Up @@ -115,7 +118,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 Down Expand Up @@ -158,5 +161,73 @@ internal sealed class OpenTelemetryAttributeKeys
/// Represents the stack trace of the exception.
/// </summary>
public const string ExceptionStacktrace = "exception.stacktrace";

public static void PopulateAttributes(DiagnosticScope scope,
string operationName,
string databaseName,
string containerName,
string accountName,
string userAgent,
string clientId,
string connectionMode)
{
scope.AddAttribute(OpenTelemetryAttributeKeys.DbOperation, operationName);
scope.AddAttribute(OpenTelemetryAttributeKeys.DbName, databaseName);
scope.AddAttribute(OpenTelemetryAttributeKeys.ContainerName, containerName);
scope.AddAttribute(OpenTelemetryAttributeKeys.ServerAddress, accountName);
scope.AddAttribute(OpenTelemetryAttributeKeys.UserAgent, userAgent);
scope.AddAttribute(OpenTelemetryAttributeKeys.ClientId, clientId);
scope.AddAttribute(OpenTelemetryAttributeKeys.ConnectionMode, connectionMode);
}

public static 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 static void PopulateAttributes(DiagnosticScope scope, QueryTextMode? queryTextMode, OpenTelemetryAttributes response)
{
if (response == null)
{
return;
}

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

scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.StatusCode, (int)response.StatusCode);
scope.AddAttribute(OpenTelemetryAttributeKeys.RequestContentLength, response.RequestContentLength);
scope.AddAttribute(OpenTelemetryAttributeKeys.ResponseContentLength, response.ResponseContentLength);
scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.SubStatusCode, response.SubStatusCode);
scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.RequestCharge, (int)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()));
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Microsoft.Azure.Cosmos.Telemetry
using System.Diagnostics;
using global::Azure.Core;
using Microsoft.Azure.Cosmos.Telemetry.Diagnostics;
using Microsoft.Azure.Cosmos.Telemetry.OpenTelemetry;
using Microsoft.Azure.Documents;

/// <summary>
Expand All @@ -19,8 +20,6 @@ internal struct OpenTelemetryCoreRecorder : IDisposable
{
private const string CosmosDb = "cosmosdb";

private static readonly string otelStabilityMode = Environment.GetEnvironmentVariable("OTEL_SEMCONV_STABILITY_OPT_IN");

private readonly DiagnosticScope scope = default;
private readonly CosmosThresholdOptions config = null;
private readonly Activity activity = null;
Expand Down Expand Up @@ -69,13 +68,21 @@ private OpenTelemetryCoreRecorder(
this.config = config;

this.operationType = operationType;
this.connectionModeCache = Enum.GetName(typeof(ConnectionMode), clientContext.ClientOptions.ConnectionMode);
this.connectionModeCache = clientContext.ClientOptions.ConnectionMode switch
{
ConnectionMode.Direct => "direct",
ConnectionMode.Gateway => "gateway",
_ => throw new NotImplementedException()
};

this.queryTextMode = queryTextMode;

if (scope.IsEnabled)
{
this.scope.Start();

this.scope.AddAttribute(OpenTelemetryAttributeKeys.DbSystemName, OpenTelemetryCoreRecorder.CosmosDb);

this.Record(
operationName: operationName,
containerName: containerName,
Expand Down Expand Up @@ -151,28 +158,15 @@ public void Record(
{
if (this.IsEnabled)
{
if (otelStabilityMode == OpenTelemetryStablityModes.DatabaseDupe)
{
this.scope.AddAttribute(OpenTelemetryAttributeKeys.DbOperation, operationName);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.DbName, databaseName);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.ContainerName, containerName);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.ServerAddress, clientContext.Client?.Endpoint?.Host);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.UserAgent, clientContext.UserAgent);
}
else
{
// Classic Appinsights Support
this.scope.AddAttribute(AppInsightClassicAttributeKeys.DbOperation, operationName);
this.scope.AddAttribute(AppInsightClassicAttributeKeys.DbName, databaseName);
this.scope.AddAttribute(AppInsightClassicAttributeKeys.ContainerName, containerName);
this.scope.AddAttribute(AppInsightClassicAttributeKeys.ServerAddress, clientContext.Client?.Endpoint?.Host);
this.scope.AddAttribute(AppInsightClassicAttributeKeys.UserAgent, clientContext.UserAgent);
this.scope.AddAttribute(AppInsightClassicAttributeKeys.MachineId, VmMetadataApiHandler.GetMachineId());
}

this.scope.AddAttribute(OpenTelemetryAttributeKeys.DbSystemName, OpenTelemetryCoreRecorder.CosmosDb);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.ClientId, clientContext?.Client?.Id);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.ConnectionMode, this.connectionModeCache);
TracesStabilityFactory.SetAttributes(this.scope,
operationName,
databaseName,
containerName,
clientContext.Client?.Endpoint?.Host,
clientContext.UserAgent,
VmMetadataApiHandler.GetMachineId(),
clientContext?.Client?.Id,
this.connectionModeCache);
}
}

Expand All @@ -196,14 +190,7 @@ public void MarkFailed(Exception exception)
{
if (this.IsEnabled)
{
this.scope.AddAttribute(OpenTelemetryAttributeKeys.ExceptionStacktrace, exception.StackTrace);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.ExceptionType, exception.GetType().Name);

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

if (exception is not CosmosException || (exception is CosmosException cosmosException
&& !DiagnosticsFilterHelper
Expand Down Expand Up @@ -242,58 +229,15 @@ public void Dispose()
{
OperationType operationType
= (this.response == null || this.response?.OperationType == OperationType.Invalid) ? this.operationType : this.response.OperationType;
if (otelStabilityMode != OpenTelemetryStablityModes.DatabaseDupe)
{
string operationName = Enum.GetName(typeof(OperationType), operationType);
this.scope.AddAttribute(AppInsightClassicAttributeKeys.OperationType, operationName);
}

if (this.response != null)
{
if (this.response.BatchSize is not null)
{
this.scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.BatchSize, (int)this.response.BatchSize);
}
string operationTypeName = Enum.GetName(typeof(OperationType), operationType);

if (otelStabilityMode == OpenTelemetryStablityModes.DatabaseDupe)
{
this.scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.StatusCode, (int)this.response.StatusCode);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.RequestContentLength, this.response.RequestContentLength);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.ResponseContentLength, this.response.ResponseContentLength);
}
else
{
this.scope.AddAttribute(AppInsightClassicAttributeKeys.RequestContentLength, this.response.RequestContentLength);
this.scope.AddAttribute(AppInsightClassicAttributeKeys.ResponseContentLength, this.response.ResponseContentLength);
this.scope.AddIntegerAttribute(AppInsightClassicAttributeKeys.StatusCode, (int)this.response.StatusCode);
}
TracesStabilityFactory.SetAttributes(this.scope, operationTypeName, this.queryTextMode, this.response);

this.scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.SubStatusCode, this.response.SubStatusCode);
this.scope.AddIntegerAttribute(OpenTelemetryAttributeKeys.RequestCharge, (int)this.response.RequestCharge);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.ItemCount, this.response.ItemCount);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.ActivityId, this.response.ActivityId);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.CorrelatedActivityId, this.response.CorrelatedActivityId);
this.scope.AddAttribute(OpenTelemetryAttributeKeys.ConsistencyLevel, this.response.ConsistencyLevel);
CosmosDbEventSource.RecordDiagnosticsForRequests(this.config, operationType, this.response);

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

if (this.response.Diagnostics != null)
{
this.scope.AddAttribute(OpenTelemetryAttributeKeys.Region, ClientTelemetryHelper.GetContactedRegions(this.response.Diagnostics.GetContactedRegions()));
CosmosDbEventSource.RecordDiagnosticsForRequests(this.config, operationType, this.response);
}

if (!DiagnosticsFilterHelper.IsSuccessfulResponse(this.response.StatusCode, this.response.SubStatusCode))
{
this.scope.Failed($"{(int)this.response.StatusCode}/{this.response.SubStatusCode}");
}
if (!DiagnosticsFilterHelper.IsSuccessfulResponse(this.response.StatusCode, this.response.SubStatusCode))
{
this.scope.Failed($"{(int)this.response.StatusCode}/{this.response.SubStatusCode}");
}

this.scope.Dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,10 @@ internal sealed class OpenTelemetryStablityModes
/// emit both the old and the stable database conventions, allowing for a seamless transition.
/// </summary>
public const string DatabaseDupe = "database/dup";

/// <summary>
/// Environment Variable to support the classic AppInsight conventions
/// </summary>
public const string ClassicAppInsights = "appinsightssdk";
}
}
Loading

0 comments on commit 987f979

Please sign in to comment.