Skip to content

Commit

Permalink
Open Telemetry: Adds Batchsize and Rename Batch Operation name in Ope…
Browse files Browse the repository at this point in the history
…ration Trace (#4622)

* Added batchsize and batchioperation name info
t p

* updated contracts

* checks

* changed logic

* cosmetic changes

* updated bacthc logic
  • Loading branch information
sourabh1007 committed Aug 6, 2024
1 parent bdc4082 commit 9deb6e5
Show file tree
Hide file tree
Showing 21 changed files with 1,022 additions and 606 deletions.
27 changes: 13 additions & 14 deletions Microsoft.Azure.Cosmos/src/Batch/BatchCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ internal class BatchCore : TransactionalBatchInternal

private readonly ContainerInternal container;

private List<ItemBatchOperation> operations;

/// <summary>
/// Initializes a new instance of the <see cref="BatchCore"/> class.
/// </summary>
Expand All @@ -31,7 +29,6 @@ internal BatchCore(
{
this.container = container;
this.partitionKey = partitionKey;
this.operations = new List<ItemBatchOperation>();
}

public override TransactionalBatch CreateItem<T>(
Expand All @@ -43,7 +40,7 @@ public override TransactionalBatch CreateItem<T>(
throw new ArgumentNullException(nameof(item));
}

this.operations.Add(new ItemBatchOperation<T>(
this.AddOperation(new ItemBatchOperation<T>(
operationType: OperationType.Create,
operationIndex: this.operations.Count,
resource: item,
Expand All @@ -62,7 +59,7 @@ public override TransactionalBatch CreateItemStream(
throw new ArgumentNullException(nameof(streamPayload));
}

this.operations.Add(new ItemBatchOperation(
this.AddOperation(new ItemBatchOperation(
operationType: OperationType.Create,
operationIndex: this.operations.Count,
resourceStream: streamPayload,
Expand All @@ -81,7 +78,7 @@ public override TransactionalBatch ReadItem(
throw new ArgumentNullException(nameof(id));
}

this.operations.Add(new ItemBatchOperation(
this.AddOperation(new ItemBatchOperation(
operationType: OperationType.Read,
operationIndex: this.operations.Count,
id: id,
Expand All @@ -100,7 +97,7 @@ public override TransactionalBatch UpsertItem<T>(
throw new ArgumentNullException(nameof(item));
}

this.operations.Add(new ItemBatchOperation<T>(
this.AddOperation(new ItemBatchOperation<T>(
operationType: OperationType.Upsert,
operationIndex: this.operations.Count,
resource: item,
Expand All @@ -119,7 +116,7 @@ public override TransactionalBatch UpsertItemStream(
throw new ArgumentNullException(nameof(streamPayload));
}

this.operations.Add(new ItemBatchOperation(
this.AddOperation(new ItemBatchOperation(
operationType: OperationType.Upsert,
operationIndex: this.operations.Count,
resourceStream: streamPayload,
Expand All @@ -144,7 +141,7 @@ public override TransactionalBatch ReplaceItem<T>(
throw new ArgumentNullException(nameof(item));
}

this.operations.Add(new ItemBatchOperation<T>(
this.AddOperation(new ItemBatchOperation<T>(
operationType: OperationType.Replace,
operationIndex: this.operations.Count,
id: id,
Expand All @@ -170,7 +167,7 @@ public override TransactionalBatch ReplaceItemStream(
throw new ArgumentNullException(nameof(streamPayload));
}

this.operations.Add(new ItemBatchOperation(
this.AddOperation(new ItemBatchOperation(
operationType: OperationType.Replace,
operationIndex: this.operations.Count,
id: id,
Expand All @@ -190,7 +187,7 @@ public override TransactionalBatch DeleteItem(
throw new ArgumentNullException(nameof(id));
}

this.operations.Add(new ItemBatchOperation(
this.AddOperation(new ItemBatchOperation(
operationType: OperationType.Delete,
operationIndex: this.operations.Count,
id: id,
Expand Down Expand Up @@ -236,7 +233,9 @@ public override Task<TransactionalBatchResponse> ExecuteAsync(
return executor.ExecuteAsync(trace, cancellationToken);
},
openTelemetry: (response) => new OpenTelemetryResponse(
responseMessage: response));
responseMessage: response,
isHomogenousOperations: this.isHomogenousOperations,
batchOperation: this.homogenousOperation));
}

/// <summary>
Expand All @@ -251,7 +250,7 @@ public virtual TransactionalBatch PatchItemStream(
Stream patchStream,
TransactionalBatchPatchItemRequestOptions requestOptions = null)
{
this.operations.Add(new ItemBatchOperation(
this.AddOperation(new ItemBatchOperation(
operationType: OperationType.Patch,
operationIndex: this.operations.Count,
id: id,
Expand Down Expand Up @@ -287,7 +286,7 @@ public override TransactionalBatch PatchItem(

PatchSpec patchSpec = new PatchSpec(patchOperations, requestOptions);

this.operations.Add(new ItemBatchOperation<PatchSpec>(
this.AddOperation(new ItemBatchOperation<PatchSpec>(
operationType: OperationType.Patch,
operationIndex: this.operations.Count,
id: id,
Expand Down
54 changes: 50 additions & 4 deletions Microsoft.Azure.Cosmos/src/Batch/TransactionalBatchInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,58 @@

namespace Microsoft.Azure.Cosmos
{
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Azure.Documents;

/// <summary>
/// Represents an internal abstract class for handling transactional batches of operations.
/// This class is intended to be used as a base class for creating batches of operations
/// that can be executed transactionally in Azure Cosmos DB.
/// </summary>
internal abstract class TransactionalBatchInternal : TransactionalBatch
{
/// <summary>
/// The list of operations in the batch.
/// </summary>
protected List<ItemBatchOperation> operations;

/// <summary>
/// Initializes a new instance of the <see cref="TransactionalBatchInternal"/> class.
/// </summary>
public TransactionalBatchInternal()
{
this.operations = new List<ItemBatchOperation>();
}

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

/// <summary>
/// Stores the operation type if all operations in the batch are of the same type; otherwise, null.
/// </summary>
internal OperationType? homogenousOperation = null;

/// <summary>
/// Adds an operation to the batch.
/// </summary>
/// <param name="itemBatchOperation">The operation to add to the batch.</param>
/// <remarks>
/// This method performs the following actions:
/// 1. Checks if the batch is homogeneous (all operations of the same type) and if the new operation's type matches the type of the existing operations.
/// 2. Updates the <see cref="isHomogenousOperations"/> flag and the <see cref="homogenousOperation"/> property based on the check.
/// 3. Adds the operation to the list of operations.
/// </remarks>
protected void AddOperation(ItemBatchOperation itemBatchOperation)
{
if (this.isHomogenousOperations && this.operations.Count > 0)
{
this.isHomogenousOperations = this.operations.First().OperationType == itemBatchOperation.OperationType;
this.homogenousOperation = this.isHomogenousOperations ? itemBatchOperation.OperationType : null;
}
this.operations.Add(itemBatchOperation);
}
}
}
20 changes: 20 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,26 @@ 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)
{
return 0;
}
return this.Operations.Count;
}

/// <summary>
/// Disposes the disposable members held by this class.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +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";

/// <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";
}
}
Loading

0 comments on commit 9deb6e5

Please sign in to comment.