Skip to content

Commit

Permalink
cosmetic changes
Browse files Browse the repository at this point in the history
  • Loading branch information
sourabh1007 committed Aug 5, 2024
1 parent 740e6c0 commit 1bdad8b
Show file tree
Hide file tree
Showing 20 changed files with 962 additions and 596 deletions.
4 changes: 2 additions & 2 deletions Microsoft.Azure.Cosmos/src/Batch/BatchCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,8 @@ public override Task<TransactionalBatchResponse> ExecuteAsync(
},
openTelemetry: (response) => new OpenTelemetryResponse(
responseMessage: response,
operationFlag: this.isHomogenousOperations,
operationName: this.lastItemBatchOperation.OperationType));
isHomogenousOperations: this.isHomogenousOperations,
batchOperation: this.lastItemBatchOperation.OperationType));
}

/// <summary>
Expand Down
45 changes: 41 additions & 4 deletions Microsoft.Azure.Cosmos/src/Batch/TransactionalBatchInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,62 @@ namespace Microsoft.Azure.Cosmos
using System.Threading.Tasks;
using Microsoft.Azure.Documents;

/// <summary>
/// Represents an internal abstract class for handling transactional batches of operations.
/// </summary>
internal abstract class TransactionalBatchInternal : TransactionalBatch
{
/// <summary>
/// The list of operations in the batch.
/// </summary>
protected List<ItemBatchOperation> operations;

internal bool isHomogenousOperations = false;
/// <summary>
/// Indicates whether all operations in the batch are of the same type.
/// </summary>
internal bool isHomogenousOperations = true;

/// <summary>
/// The last operation added to the batch.
/// </summary>
internal ItemBatchOperation lastItemBatchOperation = null;

/// <summary>
/// Adds a new operation to the batch of operations and updates the homogeneity status of the operations.
/// </summary>
/// <param name="itemBatchOperation">The operation to be added to the batch.</param>
/// <remarks>
/// This method performs the following actions:
/// <list type="number">
/// <item>
/// <description>Adds the given <paramref name="itemBatchOperation"/> to the operations list.</description>
/// </item>
/// <item>
/// <description>If the added operation is the first operation in the batch, it sets this operation as the <see cref="lastItemBatchOperation"/>.</description>
/// </item>
/// <item>
/// <description>If there are existing operations in the batch and the operations are currently homogeneous, it checks if the last added operation's type matches the new operation's type:
/// <list type="bullet">
/// <item><description>If they match, the batch remains homogeneous.</description></item>
/// <item><description>If they do not match, the batch is no longer considered homogeneous.</description></item>
/// </list>
/// </description>
/// </item>
/// <item>
/// <description>Updates the <see cref="lastItemBatchOperation"/> to the newly added operation.</description>
/// </item>
/// </list>
/// </remarks>
protected void AddOperation(ItemBatchOperation itemBatchOperation)
{
this.operations.Add(itemBatchOperation);
if (this.operations.Count == 1)
{
this.lastItemBatchOperation = itemBatchOperation;
}
else
else if (this.isHomogenousOperations)
{
this.isHomogenousOperations = this.isHomogenousOperations
&& this.lastItemBatchOperation.OperationType == itemBatchOperation.OperationType;
this.isHomogenousOperations = this.lastItemBatchOperation.OperationType == itemBatchOperation.OperationType;
this.lastItemBatchOperation = itemBatchOperation;
}
}
Expand Down
11 changes: 11 additions & 0 deletions Microsoft.Azure.Cosmos/src/Batch/TransactionalBatchResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,17 @@ private static async Task<TransactionalBatchResponse> PopulateFromContentAsync(
return response;
}

/// <summary>
/// Retrieves the size of the transactional batch.
/// </summary>
/// <returns>
/// An integer representing the number of operations in the batch.
/// Returns 0 if there are no operations.
/// </returns>
/// <remarks>
/// This method checks the <see cref="Operations"/> property to determine the number of operations in the current transactional batch.
/// If the <see cref="Operations"/> property is null, it returns 0, indicating that there are no operations in the batch.
/// </remarks>
internal int GetBatchSize()
{
if (this.Operations == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,159 @@

namespace Microsoft.Azure.Cosmos.Telemetry
{
/// <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/"/>
/// </remarks>
internal sealed class OpenTelemetryAttributeKeys
{
// Azure defaults

/// <summary>
/// Represents the diagnostic namespace for Azure Cosmos.
/// </summary>
public const string DiagnosticNamespace = "Azure.Cosmos";

/// <summary>
/// Represents the resource provider namespace for Azure Cosmos.
/// </summary>
public const string ResourceProviderNamespace = "Microsoft.DocumentDB";

/// <summary>
/// Represents the prefix for operation names.
/// </summary>
public const string OperationPrefix = "Operation";

/// <summary>
/// Represents the prefix for network-level operations.
/// </summary>
public const string NetworkLevelPrefix = "Request";

// Common database attributes

/// <summary>
/// Represents the name of the database system.
/// </summary>
public const string DbSystemName = "db.system";
public const string DbName = "db.name";
public const string DbOperation = "db.operation";

/// <summary>
/// Represents the namespace of the database.
/// </summary>
public const string DbName = "db.namespace";

/// <summary>
/// Represents the name of the database operation.
/// </summary>
public const string DbOperation = "db.operation.name";

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

// Cosmos Db Specific
// Cosmos DB specific attributes

/// <summary>
/// Represents the client ID for Cosmos DB.
/// </summary>
public const string ClientId = "db.cosmosdb.client_id";

/// <summary>
/// Represents the machine ID for Cosmos DB.
/// </summary>
public const string MachineId = "db.cosmosdb.machine_id";
public const string UserAgent = "user_agent.original"; // Compliant with open telemetry conventions

/// <summary>
/// Represents the user agent, compliant with OpenTelemetry conventions.
/// </summary>
public const string UserAgent = "user_agent.original";

/// <summary>
/// Represents the connection mode for Cosmos DB.
/// </summary>
public const string ConnectionMode = "db.cosmosdb.connection_mode";

/// <summary>
/// Represents the type of operation for Cosmos DB.
/// </summary>
public const string OperationType = "db.cosmosdb.operation_type";

// Request/Response Specifics
public const string ContainerName = "db.cosmosdb.container";
public const string RequestContentLength = "db.cosmosdb.request_content_length_bytes";
public const string ResponseContentLength = "db.cosmosdb.response_content_length_bytes";
// Request/Response specifics

/// <summary>
/// Represents the name of the container in Cosmos DB.
/// </summary>
public const string ContainerName = "db.collection.name";

/// <summary>
/// Represents the content length of the request.
/// </summary>
public const string RequestContentLength = "db.cosmosdb.request_content_length";

/// <summary>
/// Represents the content length of the response.
/// </summary>
public const string ResponseContentLength = "db.cosmosdb.response_content_length";

/// <summary>
/// Represents the status code of the response.
/// </summary>
public const string StatusCode = "db.cosmosdb.status_code";

/// <summary>
/// Represents the sub-status code of the response.
/// </summary>
public const string SubStatusCode = "db.cosmosdb.sub_status_code";

/// <summary>
/// Represents the request charge for the operation.
/// </summary>
public const string RequestCharge = "db.cosmosdb.request_charge";

/// <summary>
/// Represents the regions contacted for the operation.
/// </summary>
public const string Region = "db.cosmosdb.regions_contacted";

/// <summary>
/// Represents the item count in the operation.
/// </summary>
public const string ItemCount = "db.cosmosdb.item_count";

/// <summary>
/// Represents the activity ID for the operation.
/// </summary>
public const string ActivityId = "db.cosmosdb.activity_id";

/// <summary>
/// Represents the correlated activity ID for the operation.
/// </summary>
public const string CorrelatedActivityId = "db.cosmosdb.correlated_activity_id";
public const string BatchSize = "db.cosmosdb.batch_size";

/// <summary>
/// Represents the size of the batch operation.
/// </summary>
public const string BatchSize = "db.operation.batch.size";

// Exceptions

/// <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";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,26 @@ internal OpenTelemetryAttributes(RequestMessage requestMessage)
internal int? BatchSize { get; set; }

/// <summary>
/// Will have value for homogeneous batch operation and will be null for heterogeneous batch operation
/// Gets or sets the operation type for batch operations.
/// Will have a value for homogeneous batch operations and will be null for heterogeneous batch operations.
///
/// Operation name should be prepended with BATCH for homogeneous operations, or be just BATCH for heterogeneous operations.
/// </summary>
/// <example>
/// For example, if you have a batch of homogeneous operations like Read:
/// <code>
/// var recorder = new OpenTelemetryCoreRecorder();
/// recorder.BatchOperationName = Documents.OperationType.Read; // Homogeneous batch
/// string operationName = "BATCH." + recorder.BatchOperationName; // Results in "BATCH.Read"
/// </code>
///
/// For a batch of heterogeneous operations:
/// <code>
/// var recorder = new OpenTelemetryCoreRecorder();
/// recorder.BatchOperationName = null; // Heterogeneous batch
/// string operationName = "BATCH"; // No specific operation type
/// </code>
/// </example>
internal Documents.OperationType? BatchOperationName { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ namespace Microsoft.Azure.Cosmos.Telemetry
using Microsoft.Azure.Documents;

/// <summary>
/// This class is used to add information in an Activity tags ref. https://github.com/Azure/azure-cosmos-dotnet-v3/issues/3058
/// This class is used to add information in an Activity tags for OpenTelemetry.
/// Refer to <see href="https://github.com/Azure/azure-cosmos-dotnet-v3/issues/3058"/> for more details.
/// </summary>
internal struct OpenTelemetryCoreRecorder : IDisposable
{
Expand All @@ -27,6 +28,9 @@ internal struct OpenTelemetryCoreRecorder : IDisposable

private OpenTelemetryAttributes response = null;

/// <summary>
/// Maps exception types to actions that record their OpenTelemetry attributes.
/// </summary>
internal static IDictionary<Type, Action<Exception, DiagnosticScope>> OTelCompatibleExceptions = new Dictionary<Type, Action<Exception, DiagnosticScope>>()
{
{ typeof(CosmosNullReferenceException), (exception, scope) => CosmosNullReferenceException.RecordOtelAttributes((CosmosNullReferenceException)exception, scope)},
Expand Down Expand Up @@ -76,9 +80,10 @@ private OpenTelemetryCoreRecorder(
}

/// <summary>
/// Used for creating parent activity in scenario where there are no listeners at operation level
/// but they are present at network level
/// Creates a parent activity for scenarios where there are no listeners at the operation level but are present at the network level.
/// </summary>
/// <param name="networkScope">The network-level diagnostic scope.</param>
/// <returns>An instance of <see cref="OpenTelemetryCoreRecorder"/>.</returns>
public static OpenTelemetryCoreRecorder CreateNetworkLevelParentActivity(DiagnosticScope networkScope)
{
return new OpenTelemetryCoreRecorder(networkScope);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Microsoft.Azure.Cosmos

internal sealed class OpenTelemetryResponse : OpenTelemetryAttributes
{
internal OpenTelemetryResponse(TransactionalBatchResponse responseMessage, bool operationFlag, OperationType? operationName)
internal OpenTelemetryResponse(TransactionalBatchResponse responseMessage, bool isHomogenousOperations, OperationType? batchOperation)
: this(
statusCode: responseMessage.StatusCode,
requestCharge: OpenTelemetryResponse.GetHeader(responseMessage)?.RequestCharge,
Expand All @@ -25,7 +25,7 @@ internal OpenTelemetryResponse(TransactionalBatchResponse responseMessage, bool
activityId: OpenTelemetryResponse.GetHeader(responseMessage)?.ActivityId,
correlationId: OpenTelemetryResponse.GetHeader(responseMessage)?.CorrelatedActivityId,
batchSize: responseMessage.GetBatchSize(),
batchOperationName: operationFlag ? operationName : null )
batchOperationName: isHomogenousOperations ? batchOperation : null )
{
}

Expand Down
Loading

0 comments on commit 1bdad8b

Please sign in to comment.