Skip to content

Commit 9deb6e5

Browse files
authored
Open Telemetry: Adds Batchsize and Rename Batch Operation name in Operation Trace (#4622)
* Added batchsize and batchioperation name info t p * updated contracts * checks * changed logic * cosmetic changes * updated bacthc logic
1 parent bdc4082 commit 9deb6e5

21 files changed

+1022
-606
lines changed

Microsoft.Azure.Cosmos/src/Batch/BatchCore.cs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ internal class BatchCore : TransactionalBatchInternal
1818

1919
private readonly ContainerInternal container;
2020

21-
private List<ItemBatchOperation> operations;
22-
2321
/// <summary>
2422
/// Initializes a new instance of the <see cref="BatchCore"/> class.
2523
/// </summary>
@@ -31,7 +29,6 @@ internal BatchCore(
3129
{
3230
this.container = container;
3331
this.partitionKey = partitionKey;
34-
this.operations = new List<ItemBatchOperation>();
3532
}
3633

3734
public override TransactionalBatch CreateItem<T>(
@@ -43,7 +40,7 @@ public override TransactionalBatch CreateItem<T>(
4340
throw new ArgumentNullException(nameof(item));
4441
}
4542

46-
this.operations.Add(new ItemBatchOperation<T>(
43+
this.AddOperation(new ItemBatchOperation<T>(
4744
operationType: OperationType.Create,
4845
operationIndex: this.operations.Count,
4946
resource: item,
@@ -62,7 +59,7 @@ public override TransactionalBatch CreateItemStream(
6259
throw new ArgumentNullException(nameof(streamPayload));
6360
}
6461

65-
this.operations.Add(new ItemBatchOperation(
62+
this.AddOperation(new ItemBatchOperation(
6663
operationType: OperationType.Create,
6764
operationIndex: this.operations.Count,
6865
resourceStream: streamPayload,
@@ -81,7 +78,7 @@ public override TransactionalBatch ReadItem(
8178
throw new ArgumentNullException(nameof(id));
8279
}
8380

84-
this.operations.Add(new ItemBatchOperation(
81+
this.AddOperation(new ItemBatchOperation(
8582
operationType: OperationType.Read,
8683
operationIndex: this.operations.Count,
8784
id: id,
@@ -100,7 +97,7 @@ public override TransactionalBatch UpsertItem<T>(
10097
throw new ArgumentNullException(nameof(item));
10198
}
10299

103-
this.operations.Add(new ItemBatchOperation<T>(
100+
this.AddOperation(new ItemBatchOperation<T>(
104101
operationType: OperationType.Upsert,
105102
operationIndex: this.operations.Count,
106103
resource: item,
@@ -119,7 +116,7 @@ public override TransactionalBatch UpsertItemStream(
119116
throw new ArgumentNullException(nameof(streamPayload));
120117
}
121118

122-
this.operations.Add(new ItemBatchOperation(
119+
this.AddOperation(new ItemBatchOperation(
123120
operationType: OperationType.Upsert,
124121
operationIndex: this.operations.Count,
125122
resourceStream: streamPayload,
@@ -144,7 +141,7 @@ public override TransactionalBatch ReplaceItem<T>(
144141
throw new ArgumentNullException(nameof(item));
145142
}
146143

147-
this.operations.Add(new ItemBatchOperation<T>(
144+
this.AddOperation(new ItemBatchOperation<T>(
148145
operationType: OperationType.Replace,
149146
operationIndex: this.operations.Count,
150147
id: id,
@@ -170,7 +167,7 @@ public override TransactionalBatch ReplaceItemStream(
170167
throw new ArgumentNullException(nameof(streamPayload));
171168
}
172169

173-
this.operations.Add(new ItemBatchOperation(
170+
this.AddOperation(new ItemBatchOperation(
174171
operationType: OperationType.Replace,
175172
operationIndex: this.operations.Count,
176173
id: id,
@@ -190,7 +187,7 @@ public override TransactionalBatch DeleteItem(
190187
throw new ArgumentNullException(nameof(id));
191188
}
192189

193-
this.operations.Add(new ItemBatchOperation(
190+
this.AddOperation(new ItemBatchOperation(
194191
operationType: OperationType.Delete,
195192
operationIndex: this.operations.Count,
196193
id: id,
@@ -236,7 +233,9 @@ public override Task<TransactionalBatchResponse> ExecuteAsync(
236233
return executor.ExecuteAsync(trace, cancellationToken);
237234
},
238235
openTelemetry: (response) => new OpenTelemetryResponse(
239-
responseMessage: response));
236+
responseMessage: response,
237+
isHomogenousOperations: this.isHomogenousOperations,
238+
batchOperation: this.homogenousOperation));
240239
}
241240

242241
/// <summary>
@@ -251,7 +250,7 @@ public virtual TransactionalBatch PatchItemStream(
251250
Stream patchStream,
252251
TransactionalBatchPatchItemRequestOptions requestOptions = null)
253252
{
254-
this.operations.Add(new ItemBatchOperation(
253+
this.AddOperation(new ItemBatchOperation(
255254
operationType: OperationType.Patch,
256255
operationIndex: this.operations.Count,
257256
id: id,
@@ -287,7 +286,7 @@ public override TransactionalBatch PatchItem(
287286

288287
PatchSpec patchSpec = new PatchSpec(patchOperations, requestOptions);
289288

290-
this.operations.Add(new ItemBatchOperation<PatchSpec>(
289+
this.AddOperation(new ItemBatchOperation<PatchSpec>(
291290
operationType: OperationType.Patch,
292291
operationIndex: this.operations.Count,
293292
id: id,

Microsoft.Azure.Cosmos/src/Batch/TransactionalBatchInternal.cs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,58 @@
44

55
namespace Microsoft.Azure.Cosmos
66
{
7-
using System.IO;
8-
using System.Net;
9-
using System.Threading;
10-
using System.Threading.Tasks;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using Microsoft.Azure.Documents;
1110

11+
/// <summary>
12+
/// Represents an internal abstract class for handling transactional batches of operations.
13+
/// This class is intended to be used as a base class for creating batches of operations
14+
/// that can be executed transactionally in Azure Cosmos DB.
15+
/// </summary>
1216
internal abstract class TransactionalBatchInternal : TransactionalBatch
1317
{
18+
/// <summary>
19+
/// The list of operations in the batch.
20+
/// </summary>
21+
protected List<ItemBatchOperation> operations;
22+
23+
/// <summary>
24+
/// Initializes a new instance of the <see cref="TransactionalBatchInternal"/> class.
25+
/// </summary>
26+
public TransactionalBatchInternal()
27+
{
28+
this.operations = new List<ItemBatchOperation>();
29+
}
30+
31+
/// <summary>
32+
/// Indicates whether all operations in the batch are of the same type.
33+
/// </summary>
34+
internal bool isHomogenousOperations = true;
35+
36+
/// <summary>
37+
/// Stores the operation type if all operations in the batch are of the same type; otherwise, null.
38+
/// </summary>
39+
internal OperationType? homogenousOperation = null;
40+
41+
/// <summary>
42+
/// Adds an operation to the batch.
43+
/// </summary>
44+
/// <param name="itemBatchOperation">The operation to add to the batch.</param>
45+
/// <remarks>
46+
/// This method performs the following actions:
47+
/// 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.
48+
/// 2. Updates the <see cref="isHomogenousOperations"/> flag and the <see cref="homogenousOperation"/> property based on the check.
49+
/// 3. Adds the operation to the list of operations.
50+
/// </remarks>
51+
protected void AddOperation(ItemBatchOperation itemBatchOperation)
52+
{
53+
if (this.isHomogenousOperations && this.operations.Count > 0)
54+
{
55+
this.isHomogenousOperations = this.operations.First().OperationType == itemBatchOperation.OperationType;
56+
this.homogenousOperation = this.isHomogenousOperations ? itemBatchOperation.OperationType : null;
57+
}
58+
this.operations.Add(itemBatchOperation);
59+
}
1460
}
1561
}

Microsoft.Azure.Cosmos/src/Batch/TransactionalBatchResponse.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,26 @@ private static async Task<TransactionalBatchResponse> PopulateFromContentAsync(
392392
return response;
393393
}
394394

395+
/// <summary>
396+
/// Retrieves the size of the transactional batch.
397+
/// </summary>
398+
/// <returns>
399+
/// An integer representing the number of operations in the batch.
400+
/// Returns 0 if there are no operations.
401+
/// </returns>
402+
/// <remarks>
403+
/// This method checks the <see cref="Operations"/> property to determine the number of operations in the current transactional batch.
404+
/// If the <see cref="Operations"/> property is null, it returns 0, indicating that there are no operations in the batch.
405+
/// </remarks>
406+
internal int GetBatchSize()
407+
{
408+
if (this.Operations == null)
409+
{
410+
return 0;
411+
}
412+
return this.Operations.Count;
413+
}
414+
395415
/// <summary>
396416
/// Disposes the disposable members held by this class.
397417
/// </summary>

Microsoft.Azure.Cosmos/src/Telemetry/OpenTelemetry/OpenTelemetryAttributeKeys.cs

Lines changed: 125 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,159 @@
44

55
namespace Microsoft.Azure.Cosmos.Telemetry
66
{
7+
/// <summary>
8+
/// Contains constant string values representing OpenTelemetry attribute keys for monitoring and tracing Cosmos DB operations.
9+
/// These keys follow the OpenTelemetry conventions and the Cosmos DB semantic conventions as outlined in the OpenTelemetry specification.
10+
/// </summary>
11+
/// <remarks>
12+
/// For more details on the semantic conventions, refer to the OpenTelemetry documentation at:
13+
/// <see href="https://opentelemetry.io/docs/specs/semconv/database/cosmosdb/"/>
14+
/// </remarks>
715
internal sealed class OpenTelemetryAttributeKeys
816
{
917
// Azure defaults
18+
19+
/// <summary>
20+
/// Represents the diagnostic namespace for Azure Cosmos.
21+
/// </summary>
1022
public const string DiagnosticNamespace = "Azure.Cosmos";
23+
24+
/// <summary>
25+
/// Represents the resource provider namespace for Azure Cosmos.
26+
/// </summary>
1127
public const string ResourceProviderNamespace = "Microsoft.DocumentDB";
28+
29+
/// <summary>
30+
/// Represents the prefix for operation names.
31+
/// </summary>
1232
public const string OperationPrefix = "Operation";
33+
34+
/// <summary>
35+
/// Represents the prefix for network-level operations.
36+
/// </summary>
1337
public const string NetworkLevelPrefix = "Request";
1438

1539
// Common database attributes
40+
41+
/// <summary>
42+
/// Represents the name of the database system.
43+
/// </summary>
1644
public const string DbSystemName = "db.system";
17-
public const string DbName = "db.name";
18-
public const string DbOperation = "db.operation";
45+
46+
/// <summary>
47+
/// Represents the namespace of the database.
48+
/// </summary>
49+
public const string DbName = "db.namespace";
50+
51+
/// <summary>
52+
/// Represents the name of the database operation.
53+
/// </summary>
54+
public const string DbOperation = "db.operation.name";
55+
56+
/// <summary>
57+
/// Represents the server address.
58+
/// </summary>
1959
public const string ServerAddress = "server.address";
2060

21-
// Cosmos Db Specific
61+
// Cosmos DB specific attributes
62+
63+
/// <summary>
64+
/// Represents the client ID for Cosmos DB.
65+
/// </summary>
2266
public const string ClientId = "db.cosmosdb.client_id";
67+
68+
/// <summary>
69+
/// Represents the machine ID for Cosmos DB.
70+
/// </summary>
2371
public const string MachineId = "db.cosmosdb.machine_id";
24-
public const string UserAgent = "user_agent.original"; // Compliant with open telemetry conventions
72+
73+
/// <summary>
74+
/// Represents the user agent, compliant with OpenTelemetry conventions.
75+
/// </summary>
76+
public const string UserAgent = "user_agent.original";
77+
78+
/// <summary>
79+
/// Represents the connection mode for Cosmos DB.
80+
/// </summary>
2581
public const string ConnectionMode = "db.cosmosdb.connection_mode";
82+
83+
/// <summary>
84+
/// Represents the type of operation for Cosmos DB.
85+
/// </summary>
2686
public const string OperationType = "db.cosmosdb.operation_type";
2787

28-
// Request/Response Specifics
29-
public const string ContainerName = "db.cosmosdb.container";
30-
public const string RequestContentLength = "db.cosmosdb.request_content_length_bytes";
31-
public const string ResponseContentLength = "db.cosmosdb.response_content_length_bytes";
88+
// Request/Response specifics
89+
90+
/// <summary>
91+
/// Represents the name of the container in Cosmos DB.
92+
/// </summary>
93+
public const string ContainerName = "db.collection.name";
94+
95+
/// <summary>
96+
/// Represents the content length of the request.
97+
/// </summary>
98+
public const string RequestContentLength = "db.cosmosdb.request_content_length";
99+
100+
/// <summary>
101+
/// Represents the content length of the response.
102+
/// </summary>
103+
public const string ResponseContentLength = "db.cosmosdb.response_content_length";
104+
105+
/// <summary>
106+
/// Represents the status code of the response.
107+
/// </summary>
32108
public const string StatusCode = "db.cosmosdb.status_code";
109+
110+
/// <summary>
111+
/// Represents the sub-status code of the response.
112+
/// </summary>
33113
public const string SubStatusCode = "db.cosmosdb.sub_status_code";
114+
115+
/// <summary>
116+
/// Represents the request charge for the operation.
117+
/// </summary>
34118
public const string RequestCharge = "db.cosmosdb.request_charge";
119+
120+
/// <summary>
121+
/// Represents the regions contacted for the operation.
122+
/// </summary>
35123
public const string Region = "db.cosmosdb.regions_contacted";
124+
125+
/// <summary>
126+
/// Represents the item count in the operation.
127+
/// </summary>
36128
public const string ItemCount = "db.cosmosdb.item_count";
129+
130+
/// <summary>
131+
/// Represents the activity ID for the operation.
132+
/// </summary>
37133
public const string ActivityId = "db.cosmosdb.activity_id";
134+
135+
/// <summary>
136+
/// Represents the correlated activity ID for the operation.
137+
/// </summary>
38138
public const string CorrelatedActivityId = "db.cosmosdb.correlated_activity_id";
39139

140+
/// <summary>
141+
/// Represents the size of the batch operation.
142+
/// </summary>
143+
public const string BatchSize = "db.operation.batch.size";
144+
40145
// Exceptions
146+
147+
/// <summary>
148+
/// Represents the type of exception.
149+
/// </summary>
41150
public const string ExceptionType = "exception.type";
151+
152+
/// <summary>
153+
/// Represents the message of the exception.
154+
/// </summary>
42155
public const string ExceptionMessage = "exception.message";
156+
157+
/// <summary>
158+
/// Represents the stack trace of the exception.
159+
/// </summary>
43160
public const string ExceptionStacktrace = "exception.stacktrace";
44161
}
45162
}

0 commit comments

Comments
 (0)