Skip to content

Commit 3c18156

Browse files
authored
Query : Adds Request Charge to Query Metrics (#4252)
* initial commit * Initial commit * Revert "initial commit" This reverts commit 8393599. * contract updates * support gateway * PR comments * add totalrequestcharge * API update * new trace class * Class cleanup * Move request charge to serversidemetrics - optional * Revert "Move request charge to serversidemetrics - optional" This reverts commit 2999084. * nit fixes
1 parent 4d9b7bd commit 3c18156

File tree

10 files changed

+120
-66
lines changed

10 files changed

+120
-66
lines changed

Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ private ReadOnlyMemory<byte> WriteTraceToJsonWriter(JsonSerializationFormat json
111111
private static ServerSideCumulativeMetrics PopulateServerSideCumulativeMetrics(ITrace trace)
112112
{
113113
ServerSideMetricsInternalAccumulator accumulator = new ServerSideMetricsInternalAccumulator();
114-
ServerSideMetricsInternalAccumulator.WalkTraceTreeForQueryMetrics(trace, accumulator);
114+
ServerSideMetricsTraceExtractor.WalkTraceTreeForQueryMetrics(trace, accumulator);
115115

116116
IReadOnlyList<ServerSidePartitionedMetricsInternal> serverSideMetricsList = accumulator.GetPartitionedServerSideMetrics().Select(metrics => new ServerSidePartitionedMetricsInternal(metrics)).ToList();
117117

Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetrics.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ public abstract class ServerSideCumulativeMetrics
1515
/// </summary>
1616
public abstract ServerSideMetrics CumulativeMetrics { get; }
1717

18+
/// <summary>
19+
/// Gets the total request charge for all partitions.
20+
/// </summary>
21+
public abstract double TotalRequestCharge { get; }
22+
1823
/// <summary>
1924
/// Gets the list of ServerSideMetrics, one for for each partition.
2025
/// </summary>

Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetricsInternal.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ internal ServerSideCumulativeMetricsInternal(IEnumerable<ServerSidePartitionedMe
2020
{
2121
this.PartitionedMetrics = serverSideMetricsList.ToList();
2222
this.CumulativeMetrics = ServerSideMetricsInternal.Create(serverSideMetricsList.Select(partitionedMetrics => partitionedMetrics.ServerSideMetricsInternal));
23+
this.TotalRequestCharge = serverSideMetricsList.Sum(partitionedMetrics => partitionedMetrics.RequestCharge);
2324
}
2425

2526
public override ServerSideMetrics CumulativeMetrics { get; }
2627

2728
public override IReadOnlyList<ServerSidePartitionedMetrics> PartitionedMetrics { get; }
29+
30+
public override double TotalRequestCharge { get; }
2831
}
2932
}

Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternal.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ public ServerSideMetricsInternal(
124124

125125
public int? PartitionKeyRangeId { get; set; }
126126

127+
public double RequestCharge { get; set; }
128+
127129
public static ServerSideMetricsInternal Create(IEnumerable<ServerSideMetricsInternal> serverSideMetricsEnumerable)
128130
{
129131
ServerSideMetricsInternalAccumulator accumulator = new ServerSideMetricsInternalAccumulator();

Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternalAccumulator.cs

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -80,67 +80,5 @@ public List<ServerSideMetricsInternal> GetPartitionedServerSideMetrics()
8080
{
8181
return this.serverSideMetricsList;
8282
}
83-
84-
public static void WalkTraceTreeForQueryMetrics(ITrace currentTrace, ServerSideMetricsInternalAccumulator accumulator)
85-
{
86-
if (currentTrace == null)
87-
{
88-
return;
89-
}
90-
91-
foreach (object datum in currentTrace.Data.Values)
92-
{
93-
if (datum is QueryMetricsTraceDatum queryMetricsTraceDatum)
94-
{
95-
queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.FeedRange = currentTrace.Name;
96-
queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.PartitionKeyRangeId = WalkTraceTreeForPartitionKeyRangeId(currentTrace);
97-
accumulator.Accumulate(queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics);
98-
return;
99-
}
100-
}
101-
102-
foreach (ITrace childTrace in currentTrace.Children)
103-
{
104-
WalkTraceTreeForQueryMetrics(childTrace, accumulator);
105-
}
106-
107-
return;
108-
}
109-
110-
private static int? WalkTraceTreeForPartitionKeyRangeId(ITrace currentTrace)
111-
{
112-
if (currentTrace == null)
113-
{
114-
return null;
115-
}
116-
117-
foreach (Object datum in currentTrace.Data.Values)
118-
{
119-
if (datum is ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum)
120-
{
121-
if (clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList.Count > 0)
122-
{
123-
return int.TryParse(clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList[0].StoreResult.PartitionKeyRangeId, out int pKRangeId)
124-
? pKRangeId
125-
: null;
126-
}
127-
else
128-
{
129-
return null;
130-
}
131-
}
132-
}
133-
134-
foreach (ITrace childTrace in currentTrace.Children)
135-
{
136-
int? partitionKeyRangeId = WalkTraceTreeForPartitionKeyRangeId(childTrace);
137-
if (partitionKeyRangeId != null)
138-
{
139-
return partitionKeyRangeId;
140-
}
141-
}
142-
143-
return null;
144-
}
14583
}
14684
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
//------------------------------------------------------------
4+
5+
namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
6+
{
7+
using System;
8+
using Microsoft.Azure.Cosmos.Tracing;
9+
using Microsoft.Azure.Cosmos.Tracing.TraceData;
10+
11+
internal static class ServerSideMetricsTraceExtractor
12+
{
13+
public static void WalkTraceTreeForQueryMetrics(ITrace currentTrace, ServerSideMetricsInternalAccumulator accumulator)
14+
{
15+
if (currentTrace == null)
16+
{
17+
return;
18+
}
19+
20+
foreach (object datum in currentTrace.Data.Values)
21+
{
22+
if (datum is QueryMetricsTraceDatum queryMetricsTraceDatum)
23+
{
24+
ServerSideMetricsInternal serverSideMetrics = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics;
25+
serverSideMetrics.FeedRange = currentTrace.Name;
26+
ServerSideMetricsTraceExtractor.WalkTraceTreeForPartitionInfo(currentTrace, serverSideMetrics);
27+
accumulator.Accumulate(serverSideMetrics);
28+
}
29+
}
30+
31+
foreach (ITrace childTrace in currentTrace.Children)
32+
{
33+
ServerSideMetricsTraceExtractor.WalkTraceTreeForQueryMetrics(childTrace, accumulator);
34+
}
35+
}
36+
37+
private static void WalkTraceTreeForPartitionInfo(ITrace currentTrace, ServerSideMetricsInternal serverSideMetrics)
38+
{
39+
if (currentTrace == null)
40+
{
41+
return;
42+
}
43+
44+
foreach (Object datum in currentTrace.Data.Values)
45+
{
46+
if (datum is ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum)
47+
{
48+
if (clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList.Count > 0)
49+
{
50+
if (int.TryParse(clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList[0].StoreResult.PartitionKeyRangeId, out int pKRangeId))
51+
{
52+
serverSideMetrics.PartitionKeyRangeId = pKRangeId;
53+
}
54+
55+
serverSideMetrics.RequestCharge = clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList[0].StoreResult.RequestCharge;
56+
}
57+
}
58+
else if (datum is PointOperationStatisticsTraceDatum pointOperationStatisticsTraceDatum)
59+
{
60+
serverSideMetrics.RequestCharge = pointOperationStatisticsTraceDatum.RequestCharge;
61+
}
62+
}
63+
64+
foreach (ITrace childTrace in currentTrace.Children)
65+
{
66+
ServerSideMetricsTraceExtractor.WalkTraceTreeForPartitionInfo(childTrace, serverSideMetrics);
67+
}
68+
}
69+
}
70+
}

Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetrics.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,10 @@ public abstract class ServerSidePartitionedMetrics
2626
/// Only has a value in direct mode. When using gateway mode, this is null.
2727
/// </remarks>
2828
public abstract int? PartitionKeyRangeId { get; }
29+
30+
/// <summary>
31+
/// Gets the request charge for the operation on this partition.
32+
/// </summary>
33+
public abstract double RequestCharge { get; }
2934
}
3035
}

Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetricsInternal.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Microsoft.Azure.Cosmos
1212
internal class ServerSidePartitionedMetricsInternal : ServerSidePartitionedMetrics
1313
{
1414
internal ServerSidePartitionedMetricsInternal(ServerSideMetricsInternal serverSideMetricsInternal)
15-
: this(serverSideMetricsInternal, serverSideMetricsInternal.FeedRange, serverSideMetricsInternal.PartitionKeyRangeId)
15+
: this(serverSideMetricsInternal, serverSideMetricsInternal.FeedRange, serverSideMetricsInternal.PartitionKeyRangeId, serverSideMetricsInternal.RequestCharge)
1616
{
1717
}
1818

@@ -22,11 +22,13 @@ internal ServerSidePartitionedMetricsInternal(ServerSideMetricsInternal serverSi
2222
/// <param name="serverSideMetricsInternal"></param>
2323
/// <param name="feedRange"></param>
2424
/// <param name="partitionKeyRangeId"></param>
25-
internal ServerSidePartitionedMetricsInternal(ServerSideMetricsInternal serverSideMetricsInternal, string feedRange, int? partitionKeyRangeId)
25+
/// <param name="requestCharge"></param>
26+
internal ServerSidePartitionedMetricsInternal(ServerSideMetricsInternal serverSideMetricsInternal, string feedRange, int? partitionKeyRangeId, double requestCharge)
2627
{
2728
this.ServerSideMetricsInternal = serverSideMetricsInternal;
2829
this.FeedRange = feedRange;
2930
this.PartitionKeyRangeId = partitionKeyRangeId;
31+
this.RequestCharge = requestCharge;
3032
}
3133

3234
public ServerSideMetricsInternal ServerSideMetricsInternal { get; }
@@ -36,5 +38,7 @@ internal ServerSidePartitionedMetricsInternal(ServerSideMetricsInternal serverSi
3638
public override string FeedRange { get; }
3739

3840
public override int? PartitionKeyRangeId { get; }
41+
42+
public override double RequestCharge { get; }
3943
}
4044
}

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
3333
using System.Reflection;
3434
using System.Text.RegularExpressions;
3535
using Microsoft.Azure.Cosmos.Diagnostics;
36-
using Microsoft.Azure.Cosmos.Query.Core.Metrics;
3736

3837
[TestClass]
3938
public class CosmosItemTests : BaseCosmosClientHelper
@@ -1287,8 +1286,10 @@ public async Task QuerySinglePartitionItemStreamTest(int perPKItemCount, int max
12871286

12881287
ServerSideCumulativeMetrics metrics = response.Diagnostics.GetQueryMetrics();
12891288
Assert.IsTrue(metrics.PartitionedMetrics.Count > 0);
1289+
Assert.IsTrue(metrics.PartitionedMetrics[0].RequestCharge > 0);
12901290
Assert.IsTrue(metrics.CumulativeMetrics.TotalTime > TimeSpan.Zero);
12911291
Assert.IsTrue(metrics.CumulativeMetrics.QueryPreparationTime > TimeSpan.Zero);
1292+
Assert.IsTrue(metrics.TotalRequestCharge > 0);
12921293

12931294
if (metrics.CumulativeMetrics.RetrievedDocumentCount >= 1)
12941295
{
@@ -1376,11 +1377,14 @@ public async Task ItemMultiplePartitionQuery()
13761377
Assert.IsTrue(metrics.PartitionedMetrics.Count == 3);
13771378
Assert.IsTrue(metrics.CumulativeMetrics.TotalTime > TimeSpan.Zero);
13781379
Assert.IsTrue(metrics.CumulativeMetrics.QueryPreparationTime > TimeSpan.Zero);
1380+
Assert.IsTrue(metrics.TotalRequestCharge > 0);
13791381

13801382
foreach (ServerSidePartitionedMetrics partitionedMetrics in metrics.PartitionedMetrics)
13811383
{
13821384
Assert.IsNotNull(partitionedMetrics);
1385+
Assert.IsNotNull(partitionedMetrics.FeedRange);
13831386
Assert.IsNotNull(partitionedMetrics.PartitionKeyRangeId);
1387+
Assert.IsTrue(partitionedMetrics.RequestCharge > 0);
13841388
}
13851389

13861390
if (metrics.CumulativeMetrics.RetrievedDocumentCount >= 1)
@@ -1455,11 +1459,14 @@ public async Task ItemSinglePartitionQueryGateway()
14551459
Assert.IsTrue(metrics.PartitionedMetrics.Count == 1);
14561460
Assert.IsTrue(metrics.CumulativeMetrics.TotalTime > TimeSpan.Zero);
14571461
Assert.IsTrue(metrics.CumulativeMetrics.QueryPreparationTime > TimeSpan.Zero);
1462+
Assert.IsTrue(metrics.TotalRequestCharge > 0);
14581463

14591464
foreach (ServerSidePartitionedMetrics partitionedMetrics in metrics.PartitionedMetrics)
14601465
{
14611466
Assert.IsNotNull(partitionedMetrics);
1467+
Assert.IsNotNull(partitionedMetrics.FeedRange);
14621468
Assert.IsNull(partitionedMetrics.PartitionKeyRangeId);
1469+
Assert.IsTrue(partitionedMetrics.RequestCharge > 0);
14631470
}
14641471

14651472
if (metrics.CumulativeMetrics.RetrievedDocumentCount >= 1)

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9235,6 +9235,16 @@
92359235
"Microsoft.Azure.Cosmos.ServerSideCumulativeMetrics;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
92369236
"Subclasses": {},
92379237
"Members": {
9238+
"Double get_TotalRequestCharge()": {
9239+
"Type": "Method",
9240+
"Attributes": [],
9241+
"MethodInfo": "Double get_TotalRequestCharge();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9242+
},
9243+
"Double TotalRequestCharge": {
9244+
"Type": "Property",
9245+
"Attributes": [],
9246+
"MethodInfo": "Double TotalRequestCharge;CanRead:True;CanWrite:False;Double get_TotalRequestCharge();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9247+
},
92389248
"Microsoft.Azure.Cosmos.ServerSideMetrics CumulativeMetrics": {
92399249
"Type": "Property",
92409250
"Attributes": [],
@@ -9387,6 +9397,16 @@
93879397
"Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
93889398
"Subclasses": {},
93899399
"Members": {
9400+
"Double get_RequestCharge()": {
9401+
"Type": "Method",
9402+
"Attributes": [],
9403+
"MethodInfo": "Double get_RequestCharge();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9404+
},
9405+
"Double RequestCharge": {
9406+
"Type": "Property",
9407+
"Attributes": [],
9408+
"MethodInfo": "Double RequestCharge;CanRead:True;CanWrite:False;Double get_RequestCharge();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
9409+
},
93909410
"Microsoft.Azure.Cosmos.ServerSideMetrics get_ServerSideMetrics()": {
93919411
"Type": "Method",
93929412
"Attributes": [],

0 commit comments

Comments
 (0)