From b7b1064ab7e8bb0d90825c95125c5e1e2d74cb50 Mon Sep 17 00:00:00 2001
From: Maya-Painter <130110800+Maya-Painter@users.noreply.github.com>
Date: Fri, 8 Sep 2023 12:39:48 -0700
Subject: [PATCH] [Query] Adds public backend metrics property to Diagnostics
(#4001)
* initial commit
* some pr comments, WIP
* Refactor
* more
* Public constructors and modify accumulators
* accumulator updates and undo test changes
* add test
* PR comments
* bug fix
* ToString() refactor
* contract updates
* test updates
* small fixes
* text fix
* Update accumulators
* fix
* PR comments
* small fix
* Rename BE -> ServerSide
* more renaming
* Update API and tests
* separate public and internal classes
* API update
* change namespace
* Pr comments
* public constructors and bug fix
* API updates
* renaming and test updates
* PR comments
* more PR comments
* PR comments, test additions
* API updates and more tests
* tests and pkrangeid update
* PR comments
* more PR comments
* smol test fix
* PR comments - renaming properties and constructor rehash
* contract update
* seal classes and private fields.
* update indexHitRatio calc
* mocking refactor to abstract classes
* contract updates
* PR comments - Update documentation
---
.../src/Diagnostics/CosmosDiagnostics.cs | 13 +
.../src/Diagnostics/CosmosTraceDiagnostics.cs | 24 +-
.../src/Query/Core/Metrics/BackendMetrics.cs | 237 ------------------
.../Query/Core/Metrics/ClientSideMetrics.cs | 38 ---
.../Metrics/ClientSideMetricsAccumulator.cs | 47 ++++
.../Core/Metrics/IndexUtilizationInfo.cs | 38 ---
.../IndexUtilizationInfoAccumulator.cs | 51 ++++
.../src/Query/Core/Metrics/QueryMetrics.cs | 70 ++----
.../Core/Metrics/QueryMetricsAccumulator.cs | 48 ++++
.../Core/Metrics/QueryMetricsTextWriter.cs | 4 +-
.../Query/Core/Metrics/QueryMetricsWriter.cs | 28 +--
.../Core/Metrics/QueryPreparationTimes.cs | 104 --------
.../QueryPreparationTimesAccumulator.cs | 51 ++++
.../Metrics/QueryPreparationTimesInternal.cs | 65 +++++
.../Core/Metrics/RuntimeExecutionTimes.cs | 91 -------
.../RuntimeExecutionTimesAccumulator.cs | 48 ++++
.../Metrics/RuntimeExecutionTimesInternal.cs | 56 +++++
.../Metrics/ServerSideCumulativeMetrics.cs | 23 ++
.../ServerSideCumulativeMetricsInternal.cs | 29 +++
.../Query/Core/Metrics/ServerSideMetrics.cs | 74 ++++++
.../Core/Metrics/ServerSideMetricsInternal.cs | 153 +++++++++++
.../ServerSideMetricsInternalAccumulator.cs | 146 +++++++++++
...csParser.cs => ServerSideMetricsParser.cs} | 164 ++++++------
...nizer.cs => ServerSideMetricsTokenizer.cs} | 4 +-
.../Core/Metrics/ServerSideMetricsUtils.cs | 13 +
.../Metrics/ServerSidePartitionedMetrics.cs | 27 ++
.../ServerSidePartitionedMetricsInternal.cs | 40 +++
.../CosmosItemTests.cs | 134 +++++++++-
.../QueryStatisticsDatumVisitor.cs | 14 +-
.../QueryTests.cs | 26 +-
.../Query/Metrics/Performance.cs | 2 +-
.../TraceWriterBaselineTests.TraceData.xml | 2 +-
.../Contracts/DotNetSDKAPI.json | 193 ++++++++++++++
.../Query/Metrics/ClientSideMetricsTests.cs | 8 +-
.../Metrics/IndexUtilizationInfoTests.cs | 9 +-
.../Query/Metrics/QueryMetricsTests.cs | 16 +-
...ricsTests.cs => ServerSideMetricsTests.cs} | 68 ++---
.../Tracing/TraceWriterBaselineTests.cs | 4 +-
38 files changed, 1420 insertions(+), 742 deletions(-)
delete mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetrics.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetricsAccumulator.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfoAccumulator.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsAccumulator.cs
delete mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimes.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesAccumulator.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesInternal.cs
delete mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimes.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesAccumulator.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesInternal.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetrics.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetricsInternal.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetrics.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternal.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternalAccumulator.cs
rename Microsoft.Azure.Cosmos/src/Query/Core/Metrics/{BackendMetricsParser.cs => ServerSideMetricsParser.cs} (53%)
rename Microsoft.Azure.Cosmos/src/Query/Core/Metrics/{BackendMetricsTokenizer.cs => ServerSideMetricsTokenizer.cs} (98%)
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsUtils.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetrics.cs
create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetricsInternal.cs
rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/{BackendMetricsTests.cs => ServerSideMetricsTests.cs} (78%)
diff --git a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs
index a82ef2ecc2..b88eaa8efe 100644
--- a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs
+++ b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs
@@ -43,6 +43,19 @@ public virtual int GetFailedRequestCount()
throw new NotImplementedException($"{nameof(CosmosDiagnostics)}.{nameof(GetFailedRequestCount)}");
}
+ ///
+ /// This represents the backend query metrics for the request.
+ ///
+ ///
+ /// This is only applicable for query operations. For all other operations this will return null.
+ ///
+ /// The accumulated backend metrics for the request.
+ public virtual ServerSideCumulativeMetrics GetQueryMetrics()
+ {
+ // Default implementation avoids breaking change for users upgrading.
+ throw new NotImplementedException($"{nameof(CosmosDiagnostics)}.{nameof(GetQueryMetrics)}");
+ }
+
///
/// Gets the string field instance in the Azure Cosmos DB database service.
///
diff --git a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs
index 07e340f0ac..2d92a2cfb7 100644
--- a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs
+++ b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs
@@ -9,12 +9,15 @@ namespace Microsoft.Azure.Cosmos.Diagnostics
using System.Linq;
using System.Text;
using Microsoft.Azure.Cosmos.Json;
+ using Microsoft.Azure.Cosmos.Query.Core.Metrics;
using Microsoft.Azure.Cosmos.Tracing;
using Microsoft.Azure.Cosmos.Tracing.TraceData;
using static Microsoft.Azure.Cosmos.Tracing.TraceData.ClientSideRequestStatisticsTraceDatum;
internal sealed class CosmosTraceDiagnostics : CosmosDiagnostics
{
+ private readonly Lazy accumulatedMetrics;
+
public CosmosTraceDiagnostics(ITrace trace)
{
if (trace == null)
@@ -30,6 +33,7 @@ public CosmosTraceDiagnostics(ITrace trace)
}
this.Value = rootTrace;
+ this.accumulatedMetrics = new Lazy(() => PopulateServerSideCumulativeMetrics(this.Value));
}
public ITrace Value { get; }
@@ -49,6 +53,11 @@ public override TimeSpan GetClientElapsedTime()
return this.Value?.Summary?.RegionsContacted;
}
+ public override ServerSideCumulativeMetrics GetQueryMetrics()
+ {
+ return this.accumulatedMetrics.Value;
+ }
+
internal bool IsGoneExceptionHit()
{
return this.WalkTraceTreeForGoneException(this.Value);
@@ -61,9 +70,9 @@ private bool WalkTraceTreeForGoneException(ITrace currentTrace)
return false;
}
- foreach (object datums in currentTrace.Data.Values)
+ foreach (object datum in currentTrace.Data.Values)
{
- if (datums is ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum)
+ if (datum is ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum)
{
foreach (StoreResponseStatistics responseStatistics in clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList)
{
@@ -99,6 +108,17 @@ private ReadOnlyMemory WriteTraceToJsonWriter(JsonSerializationFormat json
return jsonTextWriter.GetResult();
}
+ private static ServerSideCumulativeMetrics PopulateServerSideCumulativeMetrics(ITrace trace)
+ {
+ ServerSideMetricsInternalAccumulator accumulator = new ServerSideMetricsInternalAccumulator();
+ ServerSideMetricsInternalAccumulator.WalkTraceTreeForQueryMetrics(trace, accumulator);
+
+ IReadOnlyList serverSideMetricsList = accumulator.GetPartitionedServerSideMetrics().Select(metrics => new ServerSidePartitionedMetricsInternal(metrics)).ToList();
+
+ ServerSideCumulativeMetrics accumulatedMetrics = new ServerSideCumulativeMetricsInternal(serverSideMetricsList);
+ return accumulatedMetrics.PartitionedMetrics.Count != 0 ? accumulatedMetrics : null;
+ }
+
public override DateTime? GetStartTimeUtc()
{
if (this.Value == null || this.Value.StartTime == null)
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetrics.cs
deleted file mode 100644
index e958aee949..0000000000
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetrics.cs
+++ /dev/null
@@ -1,237 +0,0 @@
-//------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------
-
-namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
-{
- using System;
- using System.Collections.Generic;
-
- ///
- /// Metrics received for queries from the backend.
- ///
-#if INTERNAL
-#pragma warning disable SA1600
-#pragma warning disable CS1591
- public
-#else
- internal
-#endif
- sealed class BackendMetrics
- {
- ///
- /// QueryMetrics that with all members having default (but not null) members.
- ///
- public static readonly BackendMetrics Empty = new BackendMetrics(
- retrievedDocumentCount: default,
- retrievedDocumentSize: default,
- outputDocumentCount: default,
- outputDocumentSize: default,
- indexHitRatio: default,
- totalQueryExecutionTime: default,
- queryPreparationTimes: QueryPreparationTimes.Zero,
- indexLookupTime: default,
- documentLoadTime: default,
- vmExecutionTime: default,
- runtimeExecutionTimes: RuntimeExecutionTimes.Empty,
- documentWriteTime: default);
-
- public BackendMetrics(
- long retrievedDocumentCount,
- long retrievedDocumentSize,
- long outputDocumentCount,
- long outputDocumentSize,
- double indexHitRatio,
- TimeSpan totalQueryExecutionTime,
- QueryPreparationTimes queryPreparationTimes,
- TimeSpan indexLookupTime,
- TimeSpan documentLoadTime,
- TimeSpan vmExecutionTime,
- RuntimeExecutionTimes runtimeExecutionTimes,
- TimeSpan documentWriteTime)
- {
- this.RetrievedDocumentCount = retrievedDocumentCount;
- this.RetrievedDocumentSize = retrievedDocumentSize;
- this.OutputDocumentCount = outputDocumentCount;
- this.OutputDocumentSize = outputDocumentSize;
- this.IndexHitRatio = indexHitRatio;
- this.TotalTime = totalQueryExecutionTime;
- this.QueryPreparationTimes = queryPreparationTimes ?? throw new ArgumentNullException($"{nameof(queryPreparationTimes)} can not be null.");
- this.IndexLookupTime = indexLookupTime;
- this.DocumentLoadTime = documentLoadTime;
- this.VMExecutionTime = vmExecutionTime;
- this.RuntimeExecutionTimes = runtimeExecutionTimes ?? throw new ArgumentNullException($"{nameof(runtimeExecutionTimes)} can not be null.");
- this.DocumentWriteTime = documentWriteTime;
- }
-
- ///
- /// Gets the total query time in the Azure Cosmos database service.
- ///
- public TimeSpan TotalTime { get; }
-
- ///
- /// Gets the number of documents retrieved during query in the Azure Cosmos database service.
- ///
- public long RetrievedDocumentCount { get; }
-
- ///
- /// Gets the size of documents retrieved in bytes during query in the Azure Cosmos DB service.
- ///
- public long RetrievedDocumentSize { get; }
-
- ///
- /// Gets the number of documents returned by query in the Azure Cosmos DB service.
- ///
- public long OutputDocumentCount { get; }
-
- ///
- /// Gets the size of documents outputted in bytes during query in the Azure Cosmos database service.
- ///
- public long OutputDocumentSize { get; }
-
- ///
- /// Gets the query QueryPreparationTimes in the Azure Cosmos database service.
- ///
- public QueryPreparationTimes QueryPreparationTimes { get; }
-
- ///
- /// Gets the query index lookup time in the Azure Cosmos database service.
- ///
- public TimeSpan IndexLookupTime { get; }
-
- ///
- /// Gets the document loading time during query in the Azure Cosmos database service.
- ///
- public TimeSpan DocumentLoadTime { get; }
-
- ///
- /// Gets the query runtime execution times during query in the Azure Cosmos database service.
- ///
- public RuntimeExecutionTimes RuntimeExecutionTimes { get; }
-
- ///
- /// Gets the output writing/serializing time during query in the Azure Cosmos database service.
- ///
- public TimeSpan DocumentWriteTime { get; }
-
- ///
- /// Gets the index hit ratio by query in the Azure Cosmos database service.
- ///
- public double IndexHitRatio { get; }
-
- ///
- /// Gets the VMExecution Time.
- ///
- public TimeSpan VMExecutionTime { get; }
-
- public override string ToString()
- {
- return $"totalExecutionTimeInMs={this.TotalTime.TotalMilliseconds};queryCompileTimeInMs={this.QueryPreparationTimes.QueryCompilationTime.TotalMilliseconds};queryLogicalPlanBuildTimeInMs={this.QueryPreparationTimes.LogicalPlanBuildTime.TotalMilliseconds};queryPhysicalPlanBuildTimeInMs={this.QueryPreparationTimes.PhysicalPlanBuildTime.TotalMilliseconds};queryOptimizationTimeInMs={this.QueryPreparationTimes.QueryOptimizationTime.TotalMilliseconds};indexLookupTimeInMs={this.IndexLookupTime.TotalMilliseconds};documentLoadTimeInMs={this.DocumentLoadTime.TotalMilliseconds};systemFunctionExecuteTimeInMs={this.RuntimeExecutionTimes.SystemFunctionExecutionTime.TotalMilliseconds};userFunctionExecuteTimeInMs={this.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime.TotalMilliseconds};retrievedDocumentCount={this.RetrievedDocumentCount};retrievedDocumentSize={this.RetrievedDocumentSize};outputDocumentCount={this.OutputDocumentCount};outputDocumentSize={this.OutputDocumentSize};writeOutputTimeInMs={this.DocumentWriteTime.TotalMilliseconds};indexUtilizationRatio={this.IndexHitRatio}";
- }
-
- public static BackendMetrics CreateFromIEnumerable(IEnumerable backendMetricsEnumerable)
- {
- BackendMetrics.Accumulator accumulator = default;
- foreach (BackendMetrics backendMetrics in backendMetricsEnumerable)
- {
- accumulator = accumulator.Accumulate(backendMetrics);
- }
-
- return BackendMetrics.Accumulator.ToBackendMetrics(accumulator);
- }
-
- public static bool TryParseFromDelimitedString(string delimitedString, out BackendMetrics backendMetrics)
- {
- return BackendMetricsParser.TryParse(delimitedString, out backendMetrics);
- }
-
- public static BackendMetrics ParseFromDelimitedString(string delimitedString)
- {
- if (!BackendMetricsParser.TryParse(delimitedString, out BackendMetrics backendMetrics))
- {
- throw new FormatException();
- }
-
- return backendMetrics;
- }
-
- public ref struct Accumulator
- {
- public Accumulator(
- TimeSpan totalTime,
- long retrievedDocumentCount,
- long retrievedDocumentSize,
- long outputDocumentCount,
- long outputDocumentSize,
- double indexHitRatio,
- QueryPreparationTimes.Accumulator queryPreparationTimesAccumulator,
- TimeSpan indexLookupTime,
- TimeSpan documentLoadTime,
- RuntimeExecutionTimes.Accumulator runtimeExecutionTimesAccumulator,
- TimeSpan documentWriteTime,
- TimeSpan vmExecutionTime)
- {
- this.TotalTime = totalTime;
- this.RetrievedDocumentCount = retrievedDocumentCount;
- this.RetrievedDocumentSize = retrievedDocumentSize;
- this.OutputDocumentCount = outputDocumentCount;
- this.OutputDocumentSize = outputDocumentSize;
- this.IndexHitRatio = indexHitRatio;
- this.QueryPreparationTimesAccumulator = queryPreparationTimesAccumulator;
- this.IndexLookupTime = indexLookupTime;
- this.DocumentLoadTime = documentLoadTime;
- this.RuntimeExecutionTimesAccumulator = runtimeExecutionTimesAccumulator;
- this.DocumentWriteTime = documentWriteTime;
- this.VMExecutionTime = vmExecutionTime;
- }
-
- public TimeSpan TotalTime { get; }
- public long RetrievedDocumentCount { get; }
- public long RetrievedDocumentSize { get; }
- public long OutputDocumentCount { get; }
- public long OutputDocumentSize { get; }
- public double IndexHitRatio { get; }
- public QueryPreparationTimes.Accumulator QueryPreparationTimesAccumulator { get; }
- public TimeSpan IndexLookupTime { get; }
- public TimeSpan DocumentLoadTime { get; }
- public RuntimeExecutionTimes.Accumulator RuntimeExecutionTimesAccumulator { get; }
- public TimeSpan DocumentWriteTime { get; }
- public TimeSpan VMExecutionTime { get; }
-
- public Accumulator Accumulate(BackendMetrics backendMetrics)
- {
- return new Accumulator(
- totalTime: this.TotalTime + backendMetrics.TotalTime,
- retrievedDocumentCount: this.RetrievedDocumentCount + backendMetrics.RetrievedDocumentCount,
- retrievedDocumentSize: this.RetrievedDocumentSize + backendMetrics.RetrievedDocumentSize,
- outputDocumentCount: this.OutputDocumentCount + backendMetrics.OutputDocumentCount,
- outputDocumentSize: this.OutputDocumentSize + backendMetrics.OutputDocumentSize,
- indexHitRatio: ((this.OutputDocumentCount * this.IndexHitRatio) + (backendMetrics.OutputDocumentCount * backendMetrics.IndexHitRatio)) / (this.RetrievedDocumentCount + backendMetrics.RetrievedDocumentCount),
- queryPreparationTimesAccumulator: this.QueryPreparationTimesAccumulator.Accumulate(backendMetrics.QueryPreparationTimes),
- indexLookupTime: this.IndexLookupTime + backendMetrics.IndexLookupTime,
- documentLoadTime: this.DocumentLoadTime + backendMetrics.DocumentLoadTime,
- runtimeExecutionTimesAccumulator: this.RuntimeExecutionTimesAccumulator.Accumulate(backendMetrics.RuntimeExecutionTimes),
- documentWriteTime: this.DocumentWriteTime + backendMetrics.DocumentWriteTime,
- vmExecutionTime: this.VMExecutionTime + backendMetrics.VMExecutionTime);
-
- }
-
- public static BackendMetrics ToBackendMetrics(BackendMetrics.Accumulator accumulator)
- {
- return new BackendMetrics(
- retrievedDocumentCount: accumulator.RetrievedDocumentCount,
- retrievedDocumentSize: accumulator.RetrievedDocumentSize,
- outputDocumentCount: accumulator.OutputDocumentCount,
- outputDocumentSize: accumulator.OutputDocumentSize,
- indexHitRatio: accumulator.IndexHitRatio,
- totalQueryExecutionTime: accumulator.TotalTime,
- queryPreparationTimes: QueryPreparationTimes.Accumulator.ToQueryPreparationTimes(accumulator.QueryPreparationTimesAccumulator),
- indexLookupTime: accumulator.IndexLookupTime,
- documentLoadTime: accumulator.DocumentLoadTime,
- vmExecutionTime: accumulator.VMExecutionTime,
- runtimeExecutionTimes: RuntimeExecutionTimes.Accumulator.ToRuntimeExecutionTimes(accumulator.RuntimeExecutionTimesAccumulator),
- documentWriteTime: accumulator.DocumentWriteTime);
- }
- }
- }
-}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetrics.cs
index e69f4c5808..ff68271a69 100644
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetrics.cs
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetrics.cs
@@ -5,7 +5,6 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
{
using System;
using System.Collections.Generic;
- using System.Linq;
///
/// Stores client side QueryMetrics.
@@ -54,42 +53,5 @@ public ClientSideMetrics(
/// Gets the Fetch Execution Ranges for this continuation of the query.
///
public IEnumerable FetchExecutionRanges { get; }
-
- public ref struct Accumulator
- {
- public Accumulator(long retries, double requestCharge, IEnumerable fetchExecutionRanges)
- {
- this.Retries = retries;
- this.RequestCharge = requestCharge;
- this.FetchExecutionRanges = fetchExecutionRanges;
- }
-
- public long Retries { get; }
-
- public double RequestCharge { get; }
-
- public IEnumerable FetchExecutionRanges { get; }
-
- public Accumulator Accumulate(ClientSideMetrics clientSideMetrics)
- {
- if (clientSideMetrics == null)
- {
- throw new ArgumentNullException(nameof(clientSideMetrics));
- }
-
- return new Accumulator(
- retries: this.Retries + clientSideMetrics.Retries,
- requestCharge: this.RequestCharge + clientSideMetrics.RequestCharge,
- fetchExecutionRanges: (this.FetchExecutionRanges ?? Enumerable.Empty()).Concat(clientSideMetrics.FetchExecutionRanges));
- }
-
- public static ClientSideMetrics ToClientSideMetrics(Accumulator accumulator)
- {
- return new ClientSideMetrics(
- retries: accumulator.Retries,
- requestCharge: accumulator.RequestCharge,
- fetchExecutionRanges: accumulator.FetchExecutionRanges);
- }
- }
}
}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetricsAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetricsAccumulator.cs
new file mode 100644
index 0000000000..57816580b6
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ClientSideMetricsAccumulator.cs
@@ -0,0 +1,47 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
+{
+ using System;
+ using System.Collections.Generic;
+
+ internal sealed class ClientSideMetricsAccumulator
+ {
+ private readonly List clientSideMetricsList;
+
+ public ClientSideMetricsAccumulator()
+ {
+ this.clientSideMetricsList = new List();
+ }
+
+ public void Accumulate(ClientSideMetrics clientSideMetrics)
+ {
+ if (clientSideMetrics == null)
+ {
+ throw new ArgumentNullException(nameof(clientSideMetrics));
+ }
+
+ this.clientSideMetricsList.Add(clientSideMetrics);
+ }
+
+ public ClientSideMetrics GetClientSideMetrics()
+ {
+ long retries = 0;
+ double requestCharge = 0;
+ List fetchExecutionRanges = new List();
+
+ foreach (ClientSideMetrics clientSideMetrics in this.clientSideMetricsList)
+ {
+ retries += clientSideMetrics.Retries;
+ requestCharge += clientSideMetrics.RequestCharge;
+ fetchExecutionRanges.AddRange(clientSideMetrics.FetchExecutionRanges);
+ }
+
+ return new ClientSideMetrics(
+ retries: retries,
+ requestCharge: requestCharge,
+ fetchExecutionRanges: fetchExecutionRanges);
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfo.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfo.cs
index 2dba73132e..e34a7902ad 100644
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfo.cs
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfo.cs
@@ -125,43 +125,5 @@ public static IndexUtilizationInfo CreateFromString(string delimitedString, bool
return indexUtilizationInfo;
}
-
- public ref struct Accumulator
- {
- public Accumulator(
- IEnumerable utilizedSingleIndexes,
- IEnumerable potentialSingleIndexes,
- IEnumerable utilizedCompositeIndexes,
- IEnumerable potentialCompositeIndexes)
- {
- this.UtilizedSingleIndexes = utilizedSingleIndexes;
- this.PotentialSingleIndexes = potentialSingleIndexes;
- this.UtilizedCompositeIndexes = utilizedCompositeIndexes;
- this.PotentialCompositeIndexes = potentialCompositeIndexes;
- }
-
- public IEnumerable UtilizedSingleIndexes { get; }
- public IEnumerable PotentialSingleIndexes { get; }
- public IEnumerable UtilizedCompositeIndexes { get; }
- public IEnumerable PotentialCompositeIndexes { get; }
-
- public Accumulator Accumulate(IndexUtilizationInfo indexUtilizationInfo)
- {
- return new Accumulator(
- utilizedSingleIndexes: (this.UtilizedSingleIndexes ?? Enumerable.Empty()).Concat(indexUtilizationInfo.UtilizedSingleIndexes),
- potentialSingleIndexes: (this.PotentialSingleIndexes ?? Enumerable.Empty()).Concat(indexUtilizationInfo.PotentialSingleIndexes),
- utilizedCompositeIndexes: (this.UtilizedCompositeIndexes ?? Enumerable.Empty()).Concat(indexUtilizationInfo.UtilizedCompositeIndexes),
- potentialCompositeIndexes: (this.PotentialCompositeIndexes ?? Enumerable.Empty()).Concat(indexUtilizationInfo.PotentialCompositeIndexes));
- }
-
- public static IndexUtilizationInfo ToIndexUtilizationInfo(Accumulator accumulator)
- {
- return new IndexUtilizationInfo(
- utilizedSingleIndexes: accumulator.UtilizedSingleIndexes.ToList(),
- potentialSingleIndexes: accumulator.PotentialSingleIndexes.ToList(),
- utilizedCompositeIndexes: accumulator.UtilizedCompositeIndexes.ToList(),
- potentialCompositeIndexes: accumulator.PotentialCompositeIndexes.ToList());
- }
- }
}
}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfoAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfoAccumulator.cs
new file mode 100644
index 0000000000..978abba77a
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/IndexUtilizationInfoAccumulator.cs
@@ -0,0 +1,51 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
+{
+ using System;
+ using System.Collections.Generic;
+
+ internal sealed class IndexUtilizationInfoAccumulator
+ {
+ private readonly List indexUtilizationInfoList;
+
+ public IndexUtilizationInfoAccumulator()
+ {
+ this.indexUtilizationInfoList = new List();
+ }
+
+ public void Accumulate(IndexUtilizationInfo indexUtilizationInfo)
+ {
+ if (indexUtilizationInfo == null)
+ {
+ throw new ArgumentNullException(nameof(indexUtilizationInfo));
+ }
+
+ this.indexUtilizationInfoList.Add(indexUtilizationInfo);
+ }
+
+ public IndexUtilizationInfo GetIndexUtilizationInfo()
+ {
+ List utilizedSingleIndexes = new List();
+ List potentialSingleIndexes = new List();
+ List utilizedCompositeIndexes = new List();
+ List potentialCompositeIndexes = new List();
+
+ foreach (IndexUtilizationInfo indexUtilizationInfo in this.indexUtilizationInfoList)
+ {
+ utilizedSingleIndexes.AddRange(indexUtilizationInfo.UtilizedSingleIndexes);
+ potentialSingleIndexes.AddRange(indexUtilizationInfo.PotentialSingleIndexes);
+ utilizedCompositeIndexes.AddRange(indexUtilizationInfo.UtilizedCompositeIndexes);
+ potentialCompositeIndexes.AddRange(indexUtilizationInfo.PotentialCompositeIndexes);
+ }
+
+ return new IndexUtilizationInfo(
+ utilizedSingleIndexes: utilizedSingleIndexes,
+ potentialSingleIndexes: potentialSingleIndexes,
+ utilizedCompositeIndexes: utilizedCompositeIndexes,
+ potentialCompositeIndexes: potentialCompositeIndexes);
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetrics.cs
index 5a7e9377ed..ed3993d47e 100644
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetrics.cs
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetrics.cs
@@ -29,11 +29,11 @@ sealed class QueryMetrics
clientSideMetrics: ClientSideMetrics.Empty);
public QueryMetrics(
- BackendMetrics backendMetrics,
- IndexUtilizationInfo indexUtilizationInfo,
- ClientSideMetrics clientSideMetrics)
+ ServerSideMetricsInternal serverSideMetrics,
+ IndexUtilizationInfo indexUtilizationInfo,
+ ClientSideMetrics clientSideMetrics)
{
- this.BackendMetrics = backendMetrics ?? throw new ArgumentNullException(nameof(backendMetrics));
+ this.ServerSideMetrics = serverSideMetrics ?? throw new ArgumentNullException(nameof(serverSideMetrics));
this.IndexUtilizationInfo = indexUtilizationInfo ?? throw new ArgumentNullException(nameof(indexUtilizationInfo));
this.ClientSideMetrics = clientSideMetrics ?? throw new ArgumentNullException(nameof(clientSideMetrics));
}
@@ -43,13 +43,13 @@ public QueryMetrics(
IndexUtilizationInfo indexUtilizationInfo,
ClientSideMetrics clientSideMetrics)
: this(!String.IsNullOrWhiteSpace(deliminatedString) &&
- BackendMetricsParser.TryParse(deliminatedString, out BackendMetrics backendMetrics)
- ? backendMetrics
- : BackendMetrics.Empty, indexUtilizationInfo, clientSideMetrics)
+ ServerSideMetricsParser.TryParse(deliminatedString, out ServerSideMetricsInternal serverSideMetrics)
+ ? serverSideMetrics
+ : ServerSideMetricsInternal.Empty, indexUtilizationInfo, clientSideMetrics)
{
}
- public BackendMetrics BackendMetrics { get; }
+ public ServerSideMetricsInternal ServerSideMetrics { get; }
public IndexUtilizationInfo IndexUtilizationInfo { get; }
@@ -63,11 +63,11 @@ public QueryMetrics(
/// A new instance that is the sum of two instances
public static QueryMetrics operator +(QueryMetrics queryMetrics1, QueryMetrics queryMetrics2)
{
- QueryMetrics.Accumulator queryMetricsAccumulator = new QueryMetrics.Accumulator();
- queryMetricsAccumulator = queryMetricsAccumulator.Accumulate(queryMetrics1);
- queryMetricsAccumulator = queryMetricsAccumulator.Accumulate(queryMetrics2);
+ QueryMetricsAccumulator queryMetricsAccumulator = new QueryMetricsAccumulator();
+ queryMetricsAccumulator.Accumulate(queryMetrics1);
+ queryMetricsAccumulator.Accumulate(queryMetrics2);
- return QueryMetrics.Accumulator.ToQueryMetrics(queryMetricsAccumulator);
+ return queryMetricsAccumulator.GetQueryMetrics();
}
///
@@ -94,53 +94,13 @@ public static QueryMetrics CreateFromIEnumerable(IEnumerable query
throw new ArgumentNullException(nameof(queryMetricsList));
}
- QueryMetrics.Accumulator queryMetricsAccumulator = new QueryMetrics.Accumulator();
+ QueryMetricsAccumulator queryMetricsAccumulator = new QueryMetricsAccumulator();
foreach (QueryMetrics queryMetrics in queryMetricsList)
{
- queryMetricsAccumulator = queryMetricsAccumulator.Accumulate(queryMetrics);
+ queryMetricsAccumulator.Accumulate(queryMetrics);
}
- return QueryMetrics.Accumulator.ToQueryMetrics(queryMetricsAccumulator);
- }
-
- public ref struct Accumulator
- {
- public Accumulator(
- BackendMetrics.Accumulator backendMetricsAccumulator,
- IndexUtilizationInfo.Accumulator indexUtilizationInfoAccumulator,
- ClientSideMetrics.Accumulator clientSideMetricsAccumulator)
- {
- this.BackendMetricsAccumulator = backendMetricsAccumulator;
- this.IndexUtilizationInfoAccumulator = indexUtilizationInfoAccumulator;
- this.ClientSideMetricsAccumulator = clientSideMetricsAccumulator;
- }
-
- public BackendMetrics.Accumulator BackendMetricsAccumulator { get; }
-
- public IndexUtilizationInfo.Accumulator IndexUtilizationInfoAccumulator { get; }
-
- public ClientSideMetrics.Accumulator ClientSideMetricsAccumulator { get; }
-
- public Accumulator Accumulate(QueryMetrics queryMetrics)
- {
- if (queryMetrics == null)
- {
- throw new ArgumentNullException(nameof(queryMetrics));
- }
-
- return new Accumulator(
- backendMetricsAccumulator: this.BackendMetricsAccumulator.Accumulate(queryMetrics.BackendMetrics),
- indexUtilizationInfoAccumulator: this.IndexUtilizationInfoAccumulator.Accumulate(queryMetrics.IndexUtilizationInfo),
- clientSideMetricsAccumulator: this.ClientSideMetricsAccumulator.Accumulate(queryMetrics.ClientSideMetrics));
- }
-
- public static QueryMetrics ToQueryMetrics(Accumulator accumulator)
- {
- return new QueryMetrics(
- BackendMetrics.Accumulator.ToBackendMetrics(accumulator.BackendMetricsAccumulator),
- IndexUtilizationInfo.Accumulator.ToIndexUtilizationInfo(accumulator.IndexUtilizationInfoAccumulator),
- ClientSideMetrics.Accumulator.ToClientSideMetrics(accumulator.ClientSideMetricsAccumulator));
- }
+ return queryMetricsAccumulator.GetQueryMetrics();
}
}
}
\ No newline at end of file
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsAccumulator.cs
new file mode 100644
index 0000000000..b6b817e95d
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsAccumulator.cs
@@ -0,0 +1,48 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
+{
+ using System;
+ using System.Collections.Generic;
+
+ internal sealed class QueryMetricsAccumulator
+ {
+ private readonly List queryMetricsList;
+
+ public QueryMetricsAccumulator()
+ {
+ this.queryMetricsList = new List();
+ }
+
+ public void Accumulate(QueryMetrics queryMetrics)
+ {
+ if (queryMetrics == null)
+ {
+ throw new ArgumentNullException(nameof(queryMetrics));
+ }
+
+ this.queryMetricsList.Add(queryMetrics);
+ }
+
+ public QueryMetrics GetQueryMetrics()
+ {
+ ServerSideMetricsInternalAccumulator serverSideMetricsAccumulator = new ServerSideMetricsInternalAccumulator();
+ IndexUtilizationInfoAccumulator indexUtilizationInfoAccumulator = new IndexUtilizationInfoAccumulator();
+ ClientSideMetricsAccumulator clientSideMetricsAccumulator = new ClientSideMetricsAccumulator();
+
+ foreach (QueryMetrics queryMetrics in this.queryMetricsList)
+ {
+ serverSideMetricsAccumulator.Accumulate(queryMetrics.ServerSideMetrics);
+ indexUtilizationInfoAccumulator.Accumulate(queryMetrics.IndexUtilizationInfo);
+ clientSideMetricsAccumulator.Accumulate(queryMetrics.ClientSideMetrics);
+ }
+
+ return new QueryMetrics(
+ serverSideMetricsAccumulator.GetServerSideMetrics(),
+ indexUtilizationInfoAccumulator.GetIndexUtilizationInfo(),
+ clientSideMetricsAccumulator.GetClientSideMetrics());
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsTextWriter.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsTextWriter.cs
index bd634815e9..1802e60e28 100644
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsTextWriter.cs
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsTextWriter.cs
@@ -215,7 +215,7 @@ protected override void WriteTotalQueryExecutionTime(TimeSpan totalQueryExecutio
indentLevel: 0);
}
- protected override void WriteQueryPreparationTime(QueryPreparationTimes queryPreparationTimes)
+ protected override void WriteQueryPreparationTime(QueryPreparationTimesInternal queryPreparationTimes)
{
QueryMetricsTextWriter.AppendTimeSpanToStringBuilder(
this.stringBuilder,
@@ -250,7 +250,7 @@ protected override void WriteVMExecutionTime(TimeSpan vmExecutionTime)
// Do Nothing
}
- protected override void WriteRuntimeExecutionTime(RuntimeExecutionTimes runtimeExecutionTimes)
+ protected override void WriteRuntimeExecutionTime(RuntimeExecutionTimesInternal runtimeExecutionTimes)
{
QueryMetricsTextWriter.AppendTimeSpanToStringBuilder(
this.stringBuilder,
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsWriter.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsWriter.cs
index 2fbb455152..f0d6f7b0fa 100644
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsWriter.cs
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryMetricsWriter.cs
@@ -23,25 +23,25 @@ public void WriteQueryMetrics(QueryMetrics queryMetrics)
this.WriteBeforeQueryMetrics();
// Top Level Properties
- this.WriteRetrievedDocumentCount(queryMetrics.BackendMetrics.RetrievedDocumentCount);
- this.WriteRetrievedDocumentSize(queryMetrics.BackendMetrics.RetrievedDocumentSize);
- this.WriteOutputDocumentCount(queryMetrics.BackendMetrics.OutputDocumentCount);
- this.WriteOutputDocumentSize(queryMetrics.BackendMetrics.OutputDocumentSize);
- this.WriteIndexHitRatio(queryMetrics.BackendMetrics.IndexHitRatio);
+ this.WriteRetrievedDocumentCount(queryMetrics.ServerSideMetrics.RetrievedDocumentCount);
+ this.WriteRetrievedDocumentSize(queryMetrics.ServerSideMetrics.RetrievedDocumentSize);
+ this.WriteOutputDocumentCount(queryMetrics.ServerSideMetrics.OutputDocumentCount);
+ this.WriteOutputDocumentSize(queryMetrics.ServerSideMetrics.OutputDocumentSize);
+ this.WriteIndexHitRatio(queryMetrics.ServerSideMetrics.IndexHitRatio);
- this.WriteTotalQueryExecutionTime(queryMetrics.BackendMetrics.TotalTime);
+ this.WriteTotalQueryExecutionTime(queryMetrics.ServerSideMetrics.TotalTime);
// QueryPreparationTimes
- this.WriteQueryPreparationTime(queryMetrics.BackendMetrics.QueryPreparationTimes);
+ this.WriteQueryPreparationTime(queryMetrics.ServerSideMetrics.QueryPreparationTimes);
- this.WriteIndexLookupTime(queryMetrics.BackendMetrics.IndexLookupTime);
- this.WriteDocumentLoadTime(queryMetrics.BackendMetrics.DocumentLoadTime);
- this.WriteVMExecutionTime(queryMetrics.BackendMetrics.VMExecutionTime);
+ this.WriteIndexLookupTime(queryMetrics.ServerSideMetrics.IndexLookupTime);
+ this.WriteDocumentLoadTime(queryMetrics.ServerSideMetrics.DocumentLoadTime);
+ this.WriteVMExecutionTime(queryMetrics.ServerSideMetrics.VMExecutionTime);
// RuntimesExecutionTimes
- this.WriteRuntimeExecutionTime(queryMetrics.BackendMetrics.RuntimeExecutionTimes);
+ this.WriteRuntimeExecutionTime(queryMetrics.ServerSideMetrics.RuntimeExecutionTimes);
- this.WriteDocumentWriteTime(queryMetrics.BackendMetrics.DocumentWriteTime);
+ this.WriteDocumentWriteTime(queryMetrics.ServerSideMetrics.DocumentWriteTime);
#if false
// ClientSideMetrics
this.WriteClientSideMetrics(queryMetrics.ClientSideMetrics);
@@ -70,7 +70,7 @@ public void WriteQueryMetrics(QueryMetrics queryMetrics)
protected abstract void WriteTotalQueryExecutionTime(TimeSpan totalQueryExecutionTime);
- protected abstract void WriteQueryPreparationTime(QueryPreparationTimes queryPreparationTimes);
+ protected abstract void WriteQueryPreparationTime(QueryPreparationTimesInternal queryPreparationTimes);
protected abstract void WriteIndexLookupTime(TimeSpan indexLookupTime);
@@ -78,7 +78,7 @@ public void WriteQueryMetrics(QueryMetrics queryMetrics)
protected abstract void WriteVMExecutionTime(TimeSpan vMExecutionTime);
- protected abstract void WriteRuntimeExecutionTime(RuntimeExecutionTimes runtimeExecutionTimes);
+ protected abstract void WriteRuntimeExecutionTime(RuntimeExecutionTimesInternal runtimeExecutionTimes);
protected abstract void WriteDocumentWriteTime(TimeSpan documentWriteTime);
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimes.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimes.cs
deleted file mode 100644
index 4b2d3b1b20..0000000000
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimes.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-//------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------
-namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
-{
- using System;
-
- ///
- /// Query preparation metrics in the Azure DocumentDB database service.
- ///
-#if INTERNAL
-#pragma warning disable SA1600
-#pragma warning disable CS1591
- public
-#else
- internal
-#endif
- sealed class QueryPreparationTimes
- {
- public static readonly QueryPreparationTimes Zero = new QueryPreparationTimes(
- queryCompilationTime: default,
- logicalPlanBuildTime: default,
- physicalPlanBuildTime: default,
- queryOptimizationTime: default);
-
- ///
- /// Initializes a new instance of the QueryPreparationTimes class.
- ///
- /// Query compile and optimization time
- /// Query logical plan build time
- /// Query physical plan build time
- /// Query optimization time
- public QueryPreparationTimes(
- TimeSpan queryCompilationTime,
- TimeSpan logicalPlanBuildTime,
- TimeSpan physicalPlanBuildTime,
- TimeSpan queryOptimizationTime)
- {
- this.QueryCompilationTime = queryCompilationTime;
- this.LogicalPlanBuildTime = logicalPlanBuildTime;
- this.PhysicalPlanBuildTime = physicalPlanBuildTime;
- this.QueryOptimizationTime = queryOptimizationTime;
- }
-
- ///
- /// Gets the query compile time in the Azure DocumentDB database service.
- ///
- public TimeSpan QueryCompilationTime { get; }
-
- ///
- /// Gets the query logical plan build time in the Azure DocumentDB database service.
- ///
- public TimeSpan LogicalPlanBuildTime { get; }
-
- ///
- /// Gets the query physical plan build time in the Azure DocumentDB database service.
- ///
- public TimeSpan PhysicalPlanBuildTime { get; }
-
- ///
- /// Gets the query optimization time in the Azure DocumentDB database service.
- ///
- public TimeSpan QueryOptimizationTime { get; }
-
- public ref struct Accumulator
- {
- public Accumulator(TimeSpan queryCompliationTime, TimeSpan logicalPlanBuildTime, TimeSpan physicalPlanBuildTime, TimeSpan queryOptimizationTime)
- {
- this.QueryCompilationTime = queryCompliationTime;
- this.LogicalPlanBuildTime = logicalPlanBuildTime;
- this.PhysicalPlanBuildTime = physicalPlanBuildTime;
- this.QueryOptimizationTime = queryOptimizationTime;
- }
-
- public TimeSpan QueryCompilationTime { get; }
- public TimeSpan LogicalPlanBuildTime { get; }
- public TimeSpan PhysicalPlanBuildTime { get; }
- public TimeSpan QueryOptimizationTime { get; }
-
- public Accumulator Accumulate(QueryPreparationTimes queryPreparationTimes)
- {
- if (queryPreparationTimes == null)
- {
- throw new ArgumentNullException(nameof(queryPreparationTimes));
- }
-
- return new Accumulator(
- queryCompliationTime: this.QueryCompilationTime + queryPreparationTimes.QueryCompilationTime,
- logicalPlanBuildTime: this.LogicalPlanBuildTime + queryPreparationTimes.LogicalPlanBuildTime,
- physicalPlanBuildTime: this.PhysicalPlanBuildTime + queryPreparationTimes.PhysicalPlanBuildTime,
- queryOptimizationTime: this.QueryOptimizationTime + queryPreparationTimes.QueryOptimizationTime);
- }
-
- public static QueryPreparationTimes ToQueryPreparationTimes(QueryPreparationTimes.Accumulator accumulator)
- {
- return new QueryPreparationTimes(
- queryCompilationTime: accumulator.QueryCompilationTime,
- logicalPlanBuildTime: accumulator.LogicalPlanBuildTime,
- physicalPlanBuildTime: accumulator.PhysicalPlanBuildTime,
- queryOptimizationTime: accumulator.QueryOptimizationTime);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesAccumulator.cs
new file mode 100644
index 0000000000..6b79e8c1f8
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesAccumulator.cs
@@ -0,0 +1,51 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
+{
+ using System;
+ using System.Collections.Generic;
+
+ internal sealed class QueryPreparationTimesAccumulator
+ {
+ private readonly List queryPreparationTimesList;
+
+ public QueryPreparationTimesAccumulator()
+ {
+ this.queryPreparationTimesList = new List();
+ }
+
+ public void Accumulate(QueryPreparationTimesInternal queryPreparationTimes)
+ {
+ if (queryPreparationTimes == null)
+ {
+ throw new ArgumentNullException(nameof(queryPreparationTimes));
+ }
+
+ this.queryPreparationTimesList.Add(queryPreparationTimes);
+ }
+
+ public QueryPreparationTimesInternal GetQueryPreparationTimes()
+ {
+ TimeSpan queryCompilationTime = TimeSpan.Zero;
+ TimeSpan logicalPlanBuildTime = TimeSpan.Zero;
+ TimeSpan physicalPlanBuildTime = TimeSpan.Zero;
+ TimeSpan queryOptimizationTime = TimeSpan.Zero;
+
+ foreach (QueryPreparationTimesInternal queryPreparationTimes in this.queryPreparationTimesList)
+ {
+ queryCompilationTime += queryPreparationTimes.QueryCompilationTime;
+ logicalPlanBuildTime += queryPreparationTimes.LogicalPlanBuildTime;
+ physicalPlanBuildTime += queryPreparationTimes.PhysicalPlanBuildTime;
+ queryOptimizationTime += queryPreparationTimes.QueryOptimizationTime;
+ }
+
+ return new QueryPreparationTimesInternal(
+ queryCompilationTime: queryCompilationTime,
+ logicalPlanBuildTime: logicalPlanBuildTime,
+ physicalPlanBuildTime: physicalPlanBuildTime,
+ queryOptimizationTime: queryOptimizationTime);
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesInternal.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesInternal.cs
new file mode 100644
index 0000000000..4e8ee38276
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/QueryPreparationTimesInternal.cs
@@ -0,0 +1,65 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
+{
+ using System;
+
+ ///
+ /// Query preparation metrics in the Azure DocumentDB database service.
+ ///
+#if INTERNAL
+#pragma warning disable SA1600
+#pragma warning disable CS1591
+ public
+#else
+ internal
+#endif
+ sealed class QueryPreparationTimesInternal
+ {
+ public static readonly QueryPreparationTimesInternal Zero = new QueryPreparationTimesInternal(
+ queryCompilationTime: TimeSpan.Zero,
+ logicalPlanBuildTime: TimeSpan.Zero,
+ physicalPlanBuildTime: TimeSpan.Zero,
+ queryOptimizationTime: TimeSpan.Zero);
+
+ ///
+ /// Initializes a new instance of the QueryPreparationTimes class.
+ ///
+ /// Query compile and optimization time
+ /// Query logical plan build time
+ /// Query physical plan build time
+ /// Query optimization time
+ public QueryPreparationTimesInternal(
+ TimeSpan queryCompilationTime,
+ TimeSpan logicalPlanBuildTime,
+ TimeSpan physicalPlanBuildTime,
+ TimeSpan queryOptimizationTime)
+ {
+ this.QueryCompilationTime = queryCompilationTime;
+ this.LogicalPlanBuildTime = logicalPlanBuildTime;
+ this.PhysicalPlanBuildTime = physicalPlanBuildTime;
+ this.QueryOptimizationTime = queryOptimizationTime;
+ }
+
+ ///
+ /// Gets the query compile time in the Azure DocumentDB database service.
+ ///
+ public TimeSpan QueryCompilationTime { get; }
+
+ ///
+ /// Gets the query logical plan build time in the Azure DocumentDB database service.
+ ///
+ public TimeSpan LogicalPlanBuildTime { get; }
+
+ ///
+ /// Gets the query physical plan build time in the Azure DocumentDB database service.
+ ///
+ public TimeSpan PhysicalPlanBuildTime { get; }
+
+ ///
+ /// Gets the query optimization time in the Azure DocumentDB database service.
+ ///
+ public TimeSpan QueryOptimizationTime { get; }
+ }
+}
\ No newline at end of file
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimes.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimes.cs
deleted file mode 100644
index 0fd8dc22f0..0000000000
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimes.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-//------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//------------------------------------------------------------
-namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
-{
- using System;
-
- ///
- /// Query runtime execution times in the Azure Cosmos DB service.
- ///
-#if INTERNAL
-#pragma warning disable SA1600
-#pragma warning disable CS1591
- public
-#else
- internal
-#endif
- sealed class RuntimeExecutionTimes
- {
- public static readonly RuntimeExecutionTimes Empty = new RuntimeExecutionTimes(
- queryEngineExecutionTime: default,
- systemFunctionExecutionTime: default,
- userDefinedFunctionExecutionTime: default);
-
- ///
- /// Initializes a new instance of the RuntimeExecutionTimes class.
- ///
- /// Query end - to - end execution time
- /// Total time spent executing system functions
- /// Total time spent executing user - defined functions
- public RuntimeExecutionTimes(
- TimeSpan queryEngineExecutionTime,
- TimeSpan systemFunctionExecutionTime,
- TimeSpan userDefinedFunctionExecutionTime)
- {
- this.QueryEngineExecutionTime = queryEngineExecutionTime;
- this.SystemFunctionExecutionTime = systemFunctionExecutionTime;
- this.UserDefinedFunctionExecutionTime = userDefinedFunctionExecutionTime;
- }
-
- ///
- /// Gets the total query runtime execution time in the Azure Cosmos DB service.
- ///
- public TimeSpan QueryEngineExecutionTime { get; }
-
- ///
- /// Gets the query system function execution time in the Azure Cosmos DB service.
- ///
- public TimeSpan SystemFunctionExecutionTime { get; }
-
- ///
- /// Gets the query user defined function execution time in the Azure Cosmos DB service.
- ///
- public TimeSpan UserDefinedFunctionExecutionTime { get; }
-
- public ref struct Accumulator
- {
- public Accumulator(TimeSpan queryEngineExecutionTime, TimeSpan systemFunctionExecutionTime, TimeSpan userDefinedFunctionExecutionTimes)
- {
- this.QueryEngineExecutionTime = queryEngineExecutionTime;
- this.SystemFunctionExecutionTime = systemFunctionExecutionTime;
- this.UserDefinedFunctionExecutionTime = userDefinedFunctionExecutionTimes;
- }
-
- public TimeSpan QueryEngineExecutionTime { get; set; }
- public TimeSpan SystemFunctionExecutionTime { get; set; }
- public TimeSpan UserDefinedFunctionExecutionTime { get; set; }
-
- public Accumulator Accumulate(RuntimeExecutionTimes runtimeExecutionTimes)
- {
- if (runtimeExecutionTimes == null)
- {
- throw new ArgumentNullException(nameof(runtimeExecutionTimes));
- }
-
- return new Accumulator(
- queryEngineExecutionTime: this.QueryEngineExecutionTime + runtimeExecutionTimes.QueryEngineExecutionTime,
- systemFunctionExecutionTime: this.SystemFunctionExecutionTime + runtimeExecutionTimes.SystemFunctionExecutionTime,
- userDefinedFunctionExecutionTimes: this.UserDefinedFunctionExecutionTime + runtimeExecutionTimes.UserDefinedFunctionExecutionTime);
- }
-
- public static RuntimeExecutionTimes ToRuntimeExecutionTimes(Accumulator accumulator)
- {
- return new RuntimeExecutionTimes(
- queryEngineExecutionTime: accumulator.QueryEngineExecutionTime,
- systemFunctionExecutionTime: accumulator.SystemFunctionExecutionTime,
- userDefinedFunctionExecutionTime: accumulator.UserDefinedFunctionExecutionTime);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesAccumulator.cs
new file mode 100644
index 0000000000..60f5e37573
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesAccumulator.cs
@@ -0,0 +1,48 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
+{
+ using System;
+ using System.Collections.Generic;
+
+ internal sealed class RuntimeExecutionTimesAccumulator
+ {
+ private readonly List runtimeExecutionTimesList;
+
+ public RuntimeExecutionTimesAccumulator()
+ {
+ this.runtimeExecutionTimesList = new List();
+ }
+
+ public void Accumulate(RuntimeExecutionTimesInternal runtimeExecutionTimes)
+ {
+ if (runtimeExecutionTimes == null)
+ {
+ throw new ArgumentNullException(nameof(runtimeExecutionTimes));
+ }
+
+ this.runtimeExecutionTimesList.Add(runtimeExecutionTimes);
+ }
+
+ public RuntimeExecutionTimesInternal GetRuntimeExecutionTimes()
+ {
+ TimeSpan queryEngineExecutionTime = TimeSpan.Zero;
+ TimeSpan systemFunctionExecutionTime = TimeSpan.Zero;
+ TimeSpan userDefinedFunctionExecutionTime = TimeSpan.Zero;
+
+ foreach (RuntimeExecutionTimesInternal runtimeExecutionTimes in this.runtimeExecutionTimesList)
+ {
+ queryEngineExecutionTime += runtimeExecutionTimes.QueryEngineExecutionTime;
+ systemFunctionExecutionTime += runtimeExecutionTimes.SystemFunctionExecutionTime;
+ userDefinedFunctionExecutionTime += runtimeExecutionTimes.UserDefinedFunctionExecutionTime;
+ }
+
+ return new RuntimeExecutionTimesInternal(
+ queryEngineExecutionTime: queryEngineExecutionTime,
+ systemFunctionExecutionTime: systemFunctionExecutionTime,
+ userDefinedFunctionExecutionTime: userDefinedFunctionExecutionTime);
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesInternal.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesInternal.cs
new file mode 100644
index 0000000000..bbd97ca45d
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimesInternal.cs
@@ -0,0 +1,56 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
+{
+ using System;
+
+ ///
+ /// Query runtime execution times in the Azure Cosmos DB service.
+ ///
+#if INTERNAL
+#pragma warning disable SA1600
+#pragma warning disable CS1591
+ public
+#else
+ internal
+#endif
+ sealed class RuntimeExecutionTimesInternal
+ {
+ public static readonly RuntimeExecutionTimesInternal Empty = new RuntimeExecutionTimesInternal(
+ queryEngineExecutionTime: TimeSpan.Zero,
+ systemFunctionExecutionTime: TimeSpan.Zero,
+ userDefinedFunctionExecutionTime: TimeSpan.Zero);
+
+ ///
+ /// Initializes a new instance of the RuntimeExecutionTimes class.
+ ///
+ /// Query end - to - end execution time
+ /// Total time spent executing system functions
+ /// Total time spent executing user - defined functions
+ public RuntimeExecutionTimesInternal(
+ TimeSpan queryEngineExecutionTime,
+ TimeSpan systemFunctionExecutionTime,
+ TimeSpan userDefinedFunctionExecutionTime)
+ {
+ this.QueryEngineExecutionTime = queryEngineExecutionTime;
+ this.SystemFunctionExecutionTime = systemFunctionExecutionTime;
+ this.UserDefinedFunctionExecutionTime = userDefinedFunctionExecutionTime;
+ }
+
+ ///
+ /// Gets the total query runtime execution time in the Azure Cosmos DB service.
+ ///
+ public TimeSpan QueryEngineExecutionTime { get; }
+
+ ///
+ /// Gets the query system function execution time in the Azure Cosmos DB service.
+ ///
+ public TimeSpan SystemFunctionExecutionTime { get; }
+
+ ///
+ /// Gets the query user defined function execution time in the Azure Cosmos DB service.
+ ///
+ public TimeSpan UserDefinedFunctionExecutionTime { get; }
+ }
+}
\ No newline at end of file
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetrics.cs
new file mode 100644
index 0000000000..3e7364f957
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetrics.cs
@@ -0,0 +1,23 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace Microsoft.Azure.Cosmos
+{
+ using System.Collections.Generic;
+
+ ///
+ /// Metrics received for queries from the backend.
+ ///
+ public abstract class ServerSideCumulativeMetrics
+ {
+ ///
+ /// Gets the ServerSideMetrics accumulated for a single round trip.
+ ///
+ public abstract ServerSideMetrics CumulativeMetrics { get; }
+
+ ///
+ /// Gets the list of ServerSideMetrics, one for for each partition.
+ ///
+ public abstract IReadOnlyList PartitionedMetrics { get; }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetricsInternal.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetricsInternal.cs
new file mode 100644
index 0000000000..5405482bb5
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideCumulativeMetricsInternal.cs
@@ -0,0 +1,29 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace Microsoft.Azure.Cosmos
+{
+ using System.Collections.Generic;
+ using System.Linq;
+ using Microsoft.Azure.Cosmos.Query.Core.Metrics;
+
+ ///
+ /// Internal implementation of metrics received for queries from the backend.
+ ///
+ internal class ServerSideCumulativeMetricsInternal : ServerSideCumulativeMetrics
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ internal ServerSideCumulativeMetricsInternal(IEnumerable serverSideMetricsList)
+ {
+ this.PartitionedMetrics = serverSideMetricsList.ToList();
+ this.CumulativeMetrics = ServerSideMetricsInternal.Create(serverSideMetricsList.Select(partitionedMetrics => partitionedMetrics.ServerSideMetricsInternal));
+ }
+
+ public override ServerSideMetrics CumulativeMetrics { get; }
+
+ public override IReadOnlyList PartitionedMetrics { get; }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetrics.cs
new file mode 100644
index 0000000000..ff215a582e
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetrics.cs
@@ -0,0 +1,74 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos
+{
+ using System;
+
+ ///
+ /// Metrics received for queries from the backend.
+ ///
+ public abstract class ServerSideMetrics
+ {
+ ///
+ /// Gets the total query time in the Azure Cosmos database service.
+ ///
+ public abstract TimeSpan TotalTime { get; }
+
+ ///
+ /// Gets the number of documents retrieved during query in the Azure Cosmos database service.
+ ///
+ public abstract long RetrievedDocumentCount { get; }
+
+ ///
+ /// Gets the size of documents retrieved in bytes during query in the Azure Cosmos DB service.
+ ///
+ public abstract long RetrievedDocumentSize { get; }
+
+ ///
+ /// Gets the number of documents returned by query in the Azure Cosmos DB service.
+ ///
+ public abstract long OutputDocumentCount { get; }
+
+ ///
+ /// Gets the size of documents outputted in bytes during query in the Azure Cosmos database service.
+ ///
+ public abstract long OutputDocumentSize { get; }
+
+ ///
+ /// Gets the query preparation time in the Azure Cosmos database service.
+ ///
+ public abstract TimeSpan QueryPreparationTime { get; }
+
+ ///
+ /// Gets the query index lookup time in the Azure Cosmos database service.
+ ///
+ public abstract TimeSpan IndexLookupTime { get; }
+
+ ///
+ /// Gets the document loading time during query in the Azure Cosmos database service.
+ ///
+ public abstract TimeSpan DocumentLoadTime { get; }
+
+ ///
+ /// Gets the query runtime execution time during query in the Azure Cosmos database service.
+ ///
+ public abstract TimeSpan RuntimeExecutionTime { get; }
+
+ ///
+ /// Gets the output writing/serializing time during query in the Azure Cosmos database service.
+ ///
+ public abstract TimeSpan DocumentWriteTime { get; }
+
+ ///
+ /// Gets the index hit ratio by query in the Azure Cosmos database service. Value is within the range [0,1].
+ ///
+ public abstract double IndexHitRatio { get; }
+
+ ///
+ /// Gets the VMExecution Time.
+ ///
+ public abstract TimeSpan VMExecutionTime { get; }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternal.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternal.cs
new file mode 100644
index 0000000000..6e80de06a5
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternal.cs
@@ -0,0 +1,153 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
+{
+ using System;
+ using System.Collections.Generic;
+
+ ///
+ /// internal implementation of metrics received for queries from the backend.
+ ///
+#if INTERNAL
+#pragma warning disable SA1600
+#pragma warning disable CS1591
+ public
+#else
+ internal
+#endif
+ sealed class ServerSideMetricsInternal : ServerSideMetrics
+ {
+ ///
+ /// QueryMetrics with all members having default (but not null) members.
+ ///
+ public static readonly ServerSideMetricsInternal Empty = new ServerSideMetricsInternal(
+ retrievedDocumentCount: 0,
+ retrievedDocumentSize: 0,
+ outputDocumentCount: 0,
+ outputDocumentSize: 0,
+ indexHitRatio: 0,
+ totalQueryExecutionTime: TimeSpan.Zero,
+ queryPreparationTimes: QueryPreparationTimesInternal.Zero,
+ indexLookupTime: TimeSpan.Zero,
+ documentLoadTime: TimeSpan.Zero,
+ vmExecutionTime: TimeSpan.Zero,
+ runtimeExecutionTimes: RuntimeExecutionTimesInternal.Empty,
+ documentWriteTime: TimeSpan.Zero);
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public ServerSideMetricsInternal(
+ long retrievedDocumentCount,
+ long retrievedDocumentSize,
+ long outputDocumentCount,
+ long outputDocumentSize,
+ double indexHitRatio,
+ TimeSpan totalQueryExecutionTime,
+ QueryPreparationTimesInternal queryPreparationTimes,
+ TimeSpan indexLookupTime,
+ TimeSpan documentLoadTime,
+ TimeSpan vmExecutionTime,
+ RuntimeExecutionTimesInternal runtimeExecutionTimes,
+ TimeSpan documentWriteTime,
+ string feedRange = null,
+ int? partitionKeyRangeId = null)
+ {
+ this.RetrievedDocumentCount = retrievedDocumentCount;
+ this.RetrievedDocumentSize = retrievedDocumentSize;
+ this.OutputDocumentCount = outputDocumentCount;
+ this.OutputDocumentSize = outputDocumentSize;
+ this.IndexHitRatio = indexHitRatio;
+ this.TotalTime = totalQueryExecutionTime;
+ this.QueryPreparationTimes = queryPreparationTimes ?? throw new ArgumentNullException($"{nameof(queryPreparationTimes)} can not be null.");
+ this.IndexLookupTime = indexLookupTime;
+ this.DocumentLoadTime = documentLoadTime;
+ this.VMExecutionTime = vmExecutionTime;
+ this.RuntimeExecutionTimes = runtimeExecutionTimes ?? throw new ArgumentNullException($"{nameof(runtimeExecutionTimes)} can not be null.");
+ this.DocumentWriteTime = documentWriteTime;
+ this.FeedRange = feedRange;
+ this.PartitionKeyRangeId = partitionKeyRangeId;
+ }
+
+ public override TimeSpan TotalTime { get; }
+
+ public override long RetrievedDocumentCount { get; }
+
+ public override long RetrievedDocumentSize { get; }
+
+ public override long OutputDocumentCount { get; }
+
+ public override long OutputDocumentSize { get; }
+
+ public QueryPreparationTimesInternal QueryPreparationTimes { get; }
+
+ public override TimeSpan QueryPreparationTime =>
+ this.QueryPreparationTimes.LogicalPlanBuildTime +
+ this.QueryPreparationTimes.PhysicalPlanBuildTime +
+ this.QueryPreparationTimes.QueryCompilationTime +
+ this.QueryPreparationTimes.QueryOptimizationTime;
+
+ public override TimeSpan IndexLookupTime { get; }
+
+ public override TimeSpan DocumentLoadTime { get; }
+
+ public RuntimeExecutionTimesInternal RuntimeExecutionTimes { get; }
+
+ public override TimeSpan RuntimeExecutionTime =>
+ this.RuntimeExecutionTimes.QueryEngineExecutionTime +
+ this.RuntimeExecutionTimes.SystemFunctionExecutionTime +
+ this.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime;
+
+ public override TimeSpan DocumentWriteTime { get; }
+
+ public override double IndexHitRatio { get; }
+
+ public override TimeSpan VMExecutionTime { get; }
+
+ public string FeedRange { get; set; }
+
+ public int? PartitionKeyRangeId { get; set; }
+
+ public static ServerSideMetricsInternal Create(IEnumerable serverSideMetricsEnumerable)
+ {
+ ServerSideMetricsInternalAccumulator accumulator = new ServerSideMetricsInternalAccumulator();
+ foreach (ServerSideMetricsInternal serverSideMetrics in serverSideMetricsEnumerable)
+ {
+ accumulator.Accumulate(serverSideMetrics);
+ }
+
+ return accumulator.GetServerSideMetrics();
+ }
+
+ public static bool TryParseFromDelimitedString(string delimitedString, out ServerSideMetricsInternal serverSideMetrics)
+ {
+ return ServerSideMetricsParser.TryParse(delimitedString, out serverSideMetrics);
+ }
+
+ public static ServerSideMetricsInternal ParseFromDelimitedString(string delimitedString)
+ {
+ if (!ServerSideMetricsParser.TryParse(delimitedString, out ServerSideMetricsInternal serverSideMetrics))
+ {
+ throw new FormatException();
+ }
+
+ return serverSideMetrics;
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternalAccumulator.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternalAccumulator.cs
new file mode 100644
index 0000000000..64be05e6b8
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsInternalAccumulator.cs
@@ -0,0 +1,146 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.Azure.Cosmos.Tracing;
+ using Microsoft.Azure.Cosmos.Tracing.TraceData;
+
+ internal sealed class ServerSideMetricsInternalAccumulator
+ {
+ private readonly List serverSideMetricsList;
+
+ public ServerSideMetricsInternalAccumulator()
+ {
+ this.serverSideMetricsList = new List();
+ }
+
+ public void Accumulate(ServerSideMetricsInternal serverSideMetrics)
+ {
+ if (serverSideMetrics == null)
+ {
+ throw new ArgumentNullException(nameof(serverSideMetrics));
+ }
+
+ this.serverSideMetricsList.Add(serverSideMetrics);
+ }
+
+ public ServerSideMetricsInternal GetServerSideMetrics()
+ {
+ TimeSpan totalTime = TimeSpan.Zero;
+ long retrievedDocumentCount = 0;
+ long retrievedDocumentSize = 0;
+ long outputDocumentCount = 0;
+ long outputDocumentSize = 0;
+ double indexHitRatio = 0;
+ QueryPreparationTimesAccumulator queryPreparationTimesAccumulator = new QueryPreparationTimesAccumulator();
+ TimeSpan indexLookupTime = TimeSpan.Zero;
+ TimeSpan documentLoadTime = TimeSpan.Zero;
+ RuntimeExecutionTimesAccumulator runtimeExecutionTimesAccumulator = new RuntimeExecutionTimesAccumulator();
+ TimeSpan documentWriteTime = TimeSpan.Zero;
+ TimeSpan vMExecutionTime = TimeSpan.Zero;
+
+ foreach (ServerSideMetricsInternal serverSideMetrics in this.serverSideMetricsList)
+ {
+ indexHitRatio = (retrievedDocumentCount + serverSideMetrics.RetrievedDocumentCount) != 0 ?
+ ((retrievedDocumentCount * indexHitRatio) + (serverSideMetrics.RetrievedDocumentCount * serverSideMetrics.IndexHitRatio)) / (retrievedDocumentCount + serverSideMetrics.RetrievedDocumentCount) :
+ 0;
+ totalTime += serverSideMetrics.TotalTime;
+ retrievedDocumentCount += serverSideMetrics.RetrievedDocumentCount;
+ retrievedDocumentSize += serverSideMetrics.RetrievedDocumentSize;
+ outputDocumentCount += serverSideMetrics.OutputDocumentCount;
+ outputDocumentSize += serverSideMetrics.OutputDocumentSize;
+ queryPreparationTimesAccumulator.Accumulate(serverSideMetrics.QueryPreparationTimes);
+ indexLookupTime += serverSideMetrics.IndexLookupTime;
+ documentLoadTime += serverSideMetrics.DocumentLoadTime;
+ runtimeExecutionTimesAccumulator.Accumulate(serverSideMetrics.RuntimeExecutionTimes);
+ documentWriteTime += serverSideMetrics.DocumentWriteTime;
+ vMExecutionTime += serverSideMetrics.VMExecutionTime;
+ }
+
+ return new ServerSideMetricsInternal(
+ retrievedDocumentCount: retrievedDocumentCount,
+ retrievedDocumentSize: retrievedDocumentSize,
+ outputDocumentCount: outputDocumentCount,
+ outputDocumentSize: outputDocumentSize,
+ indexHitRatio: indexHitRatio,
+ totalQueryExecutionTime: totalTime,
+ queryPreparationTimes: queryPreparationTimesAccumulator.GetQueryPreparationTimes(),
+ indexLookupTime: indexLookupTime,
+ documentLoadTime: documentLoadTime,
+ vmExecutionTime: vMExecutionTime,
+ runtimeExecutionTimes: runtimeExecutionTimesAccumulator.GetRuntimeExecutionTimes(),
+ documentWriteTime: documentWriteTime);
+ }
+
+ public List GetPartitionedServerSideMetrics()
+ {
+ return this.serverSideMetricsList;
+ }
+
+ public static void WalkTraceTreeForQueryMetrics(ITrace currentTrace, ServerSideMetricsInternalAccumulator accumulator)
+ {
+ if (currentTrace == null)
+ {
+ return;
+ }
+
+ foreach (object datum in currentTrace.Data.Values)
+ {
+ if (datum is QueryMetricsTraceDatum queryMetricsTraceDatum)
+ {
+ queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.FeedRange = currentTrace.Name;
+ queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.PartitionKeyRangeId = WalkTraceTreeForPartitionKeyRangeId(currentTrace);
+ accumulator.Accumulate(queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics);
+ return;
+ }
+ }
+
+ foreach (ITrace childTrace in currentTrace.Children)
+ {
+ WalkTraceTreeForQueryMetrics(childTrace, accumulator);
+ }
+
+ return;
+ }
+
+ private static int? WalkTraceTreeForPartitionKeyRangeId(ITrace currentTrace)
+ {
+ if (currentTrace == null)
+ {
+ return null;
+ }
+
+ foreach (Object datum in currentTrace.Data.Values)
+ {
+ if (datum is ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum)
+ {
+ if (clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList.Count > 0)
+ {
+ return int.TryParse(clientSideRequestStatisticsTraceDatum.StoreResponseStatisticsList[0].StoreResult.PartitionKeyRangeId, out int pKRangeId)
+ ? pKRangeId
+ : null;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ foreach (ITrace childTrace in currentTrace.Children)
+ {
+ int? partitionKeyRangeId = WalkTraceTreeForPartitionKeyRangeId(childTrace);
+ if (partitionKeyRangeId != null)
+ {
+ return partitionKeyRangeId;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsParser.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsParser.cs
similarity index 53%
rename from Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsParser.cs
rename to Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsParser.cs
index ecd5becdd4..eeba3c6c85 100644
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsParser.cs
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsParser.cs
@@ -8,7 +8,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
using System.Text;
///
- /// Parser for .
+ /// Parser for .
///
#if INTERNAL
#pragma warning disable SA1600
@@ -17,9 +17,9 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
#else
internal
#endif
- static class BackendMetricsParser
+ static class ServerSideMetricsParser
{
- public static unsafe bool TryParse(string deliminatedString, out BackendMetrics backendMetrics)
+ public static unsafe bool TryParse(string deliminatedString, out ServerSideMetricsInternal serverSideMetrics)
{
if (deliminatedString == null)
{
@@ -30,7 +30,7 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics
{
// Stack allocating a zero length buffer returns a null pointer
// so we special case the zero length string.
- backendMetrics = BackendMetrics.Empty;
+ serverSideMetrics = ServerSideMetricsInternal.Empty;
return true;
}
@@ -72,7 +72,7 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics
while (!corpus.IsEmpty)
{
- (BackendMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = BackendMetricsTokenizer.Read(corpus);
+ (ServerSideMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = ServerSideMetricsTokenizer.Read(corpus);
int bytesConsumed;
if (!tokenType.HasValue)
@@ -95,162 +95,162 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics
{
switch (tokenType.Value)
{
- case BackendMetricsTokenizer.TokenType.DocumentLoadTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.DocumentLoadTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out documentLoadTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.DocumentLoadTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.DocumentLoadTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out documentLoadTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.WriteOutputTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.WriteOutputTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out documentWriteTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.WriteOutputTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.WriteOutputTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out documentWriteTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.IndexLookupTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.IndexLookupTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out indexLookupTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.IndexLookupTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.IndexLookupTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out indexLookupTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.IndexUtilizationRatio:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.IndexUtilizationRatio.Length);
- if (!BackendMetricsParser.TryParseDoubleField(corpus, out indexHitRatio, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.IndexUtilizationRatio:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.IndexUtilizationRatio.Length);
+ if (!ServerSideMetricsParser.TryParseDoubleField(corpus, out indexHitRatio, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.QueryLogicalPlanBuildTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.QueryLogicalPlanBuildTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out logicalPlanBuildTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.QueryLogicalPlanBuildTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.QueryLogicalPlanBuildTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out logicalPlanBuildTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.OutputDocumentCount:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.OutputDocumentCount.Length);
- if (!BackendMetricsParser.TryParseLongField(corpus, out outputDocumentCount, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.OutputDocumentCount:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.OutputDocumentCount.Length);
+ if (!ServerSideMetricsParser.TryParseLongField(corpus, out outputDocumentCount, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.OutputDocumentSize:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.OutputDocumentSize.Length);
- if (!BackendMetricsParser.TryParseLongField(corpus, out outputDocumentSize, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.OutputDocumentSize:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.OutputDocumentSize.Length);
+ if (!ServerSideMetricsParser.TryParseLongField(corpus, out outputDocumentSize, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.QueryPhysicalPlanBuildTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.QueryPhysicalPlanBuildTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out physicalPlanBuildTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.QueryPhysicalPlanBuildTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.QueryPhysicalPlanBuildTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out physicalPlanBuildTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.QueryCompileTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.QueryCompileTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out queryCompilationTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.QueryCompileTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.QueryCompileTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out queryCompilationTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.QueryOptimizationTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.QueryOptimizationTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out queryOptimizationTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.QueryOptimizationTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.QueryOptimizationTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out queryOptimizationTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.RetrievedDocumentCount:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.RetrievedDocumentCount.Length);
- if (!BackendMetricsParser.TryParseLongField(corpus, out retrievedDocumentCount, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.RetrievedDocumentCount:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.RetrievedDocumentCount.Length);
+ if (!ServerSideMetricsParser.TryParseLongField(corpus, out retrievedDocumentCount, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.RetrievedDocumentSize:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.RetrievedDocumentSize.Length);
- if (!BackendMetricsParser.TryParseLongField(corpus, out retrievedDocumentSize, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.RetrievedDocumentSize:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.RetrievedDocumentSize.Length);
+ if (!ServerSideMetricsParser.TryParseLongField(corpus, out retrievedDocumentSize, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.SystemFunctionExecuteTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.SystemFunctionExecuteTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out systemFunctionExecutionTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.SystemFunctionExecuteTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.SystemFunctionExecuteTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out systemFunctionExecutionTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.TotalExecutionTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.TotalExecutionTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out totalQueryExecutionTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.TotalExecutionTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.TotalExecutionTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out totalQueryExecutionTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.UserFunctionExecuteTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.UserFunctionExecuteTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out userDefinedFunctionExecutionTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.UserFunctionExecuteTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.UserFunctionExecuteTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out userDefinedFunctionExecutionTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
- case BackendMetricsTokenizer.TokenType.VMExecutionTimeInMs:
- corpus = corpus.Slice(BackendMetricsTokenizer.TokenBuffers.VMExecutionTimeInMs.Length);
- if (!BackendMetricsParser.TryParseTimeSpanField(corpus, out vmExecutionTime, out bytesConsumed))
+ case ServerSideMetricsTokenizer.TokenType.VMExecutionTimeInMs:
+ corpus = corpus.Slice(ServerSideMetricsTokenizer.TokenBuffers.VMExecutionTimeInMs.Length);
+ if (!ServerSideMetricsParser.TryParseTimeSpanField(corpus, out vmExecutionTime, out bytesConsumed))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
break;
default:
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
}
corpus = corpus.Slice(bytesConsumed);
if (!corpus.IsEmpty)
{
- (BackendMetricsTokenizer.TokenType? semicolonToken, ReadOnlyMemory semicolonBuffer) = BackendMetricsTokenizer.Read(corpus);
- if (!semicolonToken.HasValue || (semicolonToken != BackendMetricsTokenizer.TokenType.SemiColonDelimiter))
+ (ServerSideMetricsTokenizer.TokenType? semicolonToken, ReadOnlyMemory semicolonBuffer) = ServerSideMetricsTokenizer.Read(corpus);
+ if (!semicolonToken.HasValue || (semicolonToken != ServerSideMetricsTokenizer.TokenType.SemiColonDelimiter))
{
- backendMetrics = default;
+ serverSideMetrics = default;
return false;
}
@@ -258,14 +258,14 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics
}
}
- backendMetrics = new BackendMetrics(
+ serverSideMetrics = new ServerSideMetricsInternal(
retrievedDocumentCount: retrievedDocumentCount,
retrievedDocumentSize: retrievedDocumentSize,
outputDocumentCount: outputDocumentCount,
outputDocumentSize: outputDocumentSize,
indexHitRatio: indexHitRatio,
totalQueryExecutionTime: totalQueryExecutionTime,
- queryPreparationTimes: new QueryPreparationTimes(
+ queryPreparationTimes: new QueryPreparationTimesInternal(
queryCompilationTime: queryCompilationTime,
logicalPlanBuildTime: logicalPlanBuildTime,
physicalPlanBuildTime: physicalPlanBuildTime,
@@ -273,7 +273,7 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics
indexLookupTime: indexLookupTime,
documentLoadTime: documentLoadTime,
vmExecutionTime: vmExecutionTime,
- runtimeExecutionTimes: new RuntimeExecutionTimes(
+ runtimeExecutionTimes: new RuntimeExecutionTimesInternal(
queryEngineExecutionTime: vmExecutionTime - indexLookupTime - documentLoadTime - documentWriteTime,
systemFunctionExecutionTime: systemFunctionExecutionTime,
userDefinedFunctionExecutionTime: userDefinedFunctionExecutionTime),
@@ -283,8 +283,8 @@ public static unsafe bool TryParse(string deliminatedString, out BackendMetrics
private static bool TryParseTimeSpanField(ReadOnlySpan corpus, out TimeSpan timeSpan, out int bytesConsumed)
{
- (BackendMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = BackendMetricsTokenizer.Read(corpus);
- if (!tokenType.HasValue || (tokenType.Value != BackendMetricsTokenizer.TokenType.EqualsDelimiter))
+ (ServerSideMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = ServerSideMetricsTokenizer.Read(corpus);
+ if (!tokenType.HasValue || (tokenType.Value != ServerSideMetricsTokenizer.TokenType.EqualsDelimiter))
{
timeSpan = default;
bytesConsumed = default;
@@ -306,8 +306,8 @@ private static bool TryParseTimeSpanField(ReadOnlySpan corpus, out TimeSpa
private static bool TryParseLongField(ReadOnlySpan corpus, out long value, out int bytesConsumed)
{
- (BackendMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = BackendMetricsTokenizer.Read(corpus);
- if (!tokenType.HasValue || (tokenType.Value != BackendMetricsTokenizer.TokenType.EqualsDelimiter))
+ (ServerSideMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = ServerSideMetricsTokenizer.Read(corpus);
+ if (!tokenType.HasValue || (tokenType.Value != ServerSideMetricsTokenizer.TokenType.EqualsDelimiter))
{
value = default;
bytesConsumed = default;
@@ -327,8 +327,8 @@ private static bool TryParseLongField(ReadOnlySpan corpus, out long value,
private static bool TryParseDoubleField(ReadOnlySpan corpus, out double value, out int bytesConsumed)
{
- (BackendMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = BackendMetricsTokenizer.Read(corpus);
- if (!tokenType.HasValue || (tokenType.Value != BackendMetricsTokenizer.TokenType.EqualsDelimiter))
+ (ServerSideMetricsTokenizer.TokenType? tokenType, ReadOnlyMemory buffer) = ServerSideMetricsTokenizer.Read(corpus);
+ if (!tokenType.HasValue || (tokenType.Value != ServerSideMetricsTokenizer.TokenType.EqualsDelimiter))
{
value = default;
bytesConsumed = default;
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsTokenizer.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsTokenizer.cs
similarity index 98%
rename from Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsTokenizer.cs
rename to Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsTokenizer.cs
index f17e6afbf4..431f3add64 100644
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendMetricsTokenizer.cs
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsTokenizer.cs
@@ -8,7 +8,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
using System.Text;
///
- /// Tokenizer for
+ /// Tokenizer for
///
#if INTERNAL
#pragma warning disable SA1600
@@ -18,7 +18,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
#else
internal
#endif
- static class BackendMetricsTokenizer
+ static class ServerSideMetricsTokenizer
{
public enum TokenType
{
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsUtils.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsUtils.cs
new file mode 100644
index 0000000000..a439bdfd57
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSideMetricsUtils.cs
@@ -0,0 +1,13 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace Microsoft.Azure.Cosmos.Query.Core.Metrics
+{
+ internal static class ServerSideMetricsUtils
+ {
+ public static string FormatTrace(this ServerSideMetricsInternal serverSideMetrics)
+ {
+ return $"totalExecutionTimeInMs={serverSideMetrics.TotalTime.TotalMilliseconds};queryCompileTimeInMs={serverSideMetrics.QueryPreparationTimes.QueryCompilationTime.TotalMilliseconds};queryLogicalPlanBuildTimeInMs={serverSideMetrics.QueryPreparationTimes.LogicalPlanBuildTime.TotalMilliseconds};queryPhysicalPlanBuildTimeInMs={serverSideMetrics.QueryPreparationTimes.PhysicalPlanBuildTime.TotalMilliseconds};queryOptimizationTimeInMs={serverSideMetrics.QueryPreparationTimes.QueryOptimizationTime.TotalMilliseconds};indexLookupTimeInMs={serverSideMetrics.IndexLookupTime.TotalMilliseconds};documentLoadTimeInMs={serverSideMetrics.DocumentLoadTime.TotalMilliseconds};systemFunctionExecuteTimeInMs={serverSideMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime.TotalMilliseconds};userFunctionExecuteTimeInMs={serverSideMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime.TotalMilliseconds};retrievedDocumentCount={serverSideMetrics.RetrievedDocumentCount};retrievedDocumentSize={serverSideMetrics.RetrievedDocumentSize};outputDocumentCount={serverSideMetrics.OutputDocumentCount};outputDocumentSize={serverSideMetrics.OutputDocumentSize};writeOutputTimeInMs={serverSideMetrics.DocumentWriteTime.TotalMilliseconds};indexUtilizationRatio={serverSideMetrics.IndexHitRatio}";
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetrics.cs
new file mode 100644
index 0000000000..3fd1f47094
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetrics.cs
@@ -0,0 +1,27 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos
+{
+ ///
+ /// Represents server side metrics specific for a single partition.
+ ///
+ public abstract class ServerSidePartitionedMetrics
+ {
+ ///
+ /// Gets the backend metrics for the request.
+ ///
+ public abstract ServerSideMetrics ServerSideMetrics { get; }
+
+ ///
+ /// Gets the FeedRange for the partition.
+ ///
+ public abstract string FeedRange { get; }
+
+ ///
+ /// Gets the partition key range id for the partition.
+ ///
+ public abstract int? PartitionKeyRangeId { get; }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetricsInternal.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetricsInternal.cs
new file mode 100644
index 0000000000..9ed30963a6
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/ServerSidePartitionedMetricsInternal.cs
@@ -0,0 +1,40 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos
+{
+ using Microsoft.Azure.Cosmos.Query.Core.Metrics;
+
+ ///
+ /// The internal implementation for server side metrics specific for a single partition.
+ ///
+ internal class ServerSidePartitionedMetricsInternal : ServerSidePartitionedMetrics
+ {
+ internal ServerSidePartitionedMetricsInternal(ServerSideMetricsInternal serverSideMetricsInternal)
+ : this(serverSideMetricsInternal, serverSideMetricsInternal.FeedRange, serverSideMetricsInternal.PartitionKeyRangeId)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ internal ServerSidePartitionedMetricsInternal(ServerSideMetricsInternal serverSideMetricsInternal, string feedRange, int? partitionKeyRangeId)
+ {
+ this.ServerSideMetricsInternal = serverSideMetricsInternal;
+ this.FeedRange = feedRange;
+ this.PartitionKeyRangeId = partitionKeyRangeId;
+ }
+
+ public ServerSideMetricsInternal ServerSideMetricsInternal { get; }
+
+ public override ServerSideMetrics ServerSideMetrics => this.ServerSideMetricsInternal;
+
+ public override string FeedRange { get; }
+
+ public override int? PartitionKeyRangeId { get; }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs
index b237c68c2a..dd09fde938 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs
@@ -33,6 +33,7 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
using System.Reflection;
using System.Text.RegularExpressions;
using Microsoft.Azure.Cosmos.Diagnostics;
+ using Microsoft.Azure.Cosmos.Query.Core.Metrics;
[TestClass]
public class CosmosItemTests : BaseCosmosClientHelper
@@ -141,6 +142,7 @@ public async Task CreateDropItemTest()
Assert.IsFalse(string.IsNullOrEmpty(diagnostics.ToString()));
Assert.IsTrue(diagnostics.GetClientElapsedTime() > TimeSpan.Zero);
Assert.AreEqual(0, response.Diagnostics.GetFailedRequestCount());
+ Assert.IsNull(response.Diagnostics.GetQueryMetrics());
response = await this.Container.ReadItemAsync(testItem.id, new Cosmos.PartitionKey(testItem.pk));
Assert.IsNotNull(response);
@@ -158,6 +160,7 @@ public async Task CreateDropItemTest()
Assert.IsNotNull(response.Diagnostics);
Assert.IsFalse(string.IsNullOrEmpty(response.Diagnostics.ToString()));
Assert.IsTrue(response.Diagnostics.GetClientElapsedTime() > TimeSpan.Zero);
+ Assert.IsNull(response.Diagnostics.GetQueryMetrics());
}
[TestMethod]
@@ -386,6 +389,7 @@ public async Task CreateDropItemMultiPartPartitionKeyTest()
ItemResponse response = await multiPartPkContainer.CreateItemAsync(item: testItem);
Assert.IsNotNull(response);
Assert.AreEqual(HttpStatusCode.Created, response.StatusCode);
+ Assert.IsNull(response.Diagnostics.GetQueryMetrics());
ItemResponse readResponse = await multiPartPkContainer.ReadItemAsync(id: testItem.id, partitionKey: new Cosmos.PartitionKey("pk1"));
Assert.IsNotNull(readResponse);
@@ -603,6 +607,7 @@ public async Task UpsertItemTest()
Assert.IsNotNull(response);
Assert.AreEqual(HttpStatusCode.Created, response.StatusCode);
Assert.IsNotNull(response.Headers.Session);
+ Assert.IsNull(response.Diagnostics.GetQueryMetrics());
}
{
@@ -613,6 +618,7 @@ public async Task UpsertItemTest()
Assert.IsNotNull(response);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
Assert.IsNotNull(response.Headers.Session);
+ Assert.IsNull(response.Diagnostics.GetQueryMetrics());
}
}
@@ -703,6 +709,7 @@ await feedIterator.ReadNextAsync(this.cancellationToken))
}
}
+ Assert.IsNull(responseMessage.Diagnostics.GetQueryMetrics());
}
}
@@ -842,7 +849,7 @@ public async Task PartitionKeyDeleteTestForSubpartitionedContainer()
}
[TestMethod]
- public async Task ItemCustomSerialzierTest()
+ public async Task ItemCustomSerializerTest()
{
DateTime createDateTime = DateTime.UtcNow;
Dictionary keyValuePairs = new Dictionary()
@@ -1278,6 +1285,22 @@ public async Task QuerySinglePartitionItemStreamTest(int perPKItemCount, int max
System.Diagnostics.Trace.TraceInformation($"ContinuationToken: {lastContinuationToken}");
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
+ ServerSideCumulativeMetrics metrics = response.Diagnostics.GetQueryMetrics();
+ Assert.IsTrue(metrics.PartitionedMetrics.Count == 1);
+ Assert.IsTrue(metrics.CumulativeMetrics.TotalTime > TimeSpan.Zero);
+ Assert.IsTrue(metrics.CumulativeMetrics.QueryPreparationTime > TimeSpan.Zero);
+
+ if (metrics.CumulativeMetrics.RetrievedDocumentCount >= 1)
+ {
+ Assert.IsTrue(metrics.CumulativeMetrics.RetrievedDocumentSize > 0);
+ Assert.IsTrue(metrics.CumulativeMetrics.DocumentLoadTime > TimeSpan.Zero);
+ Assert.IsTrue(metrics.CumulativeMetrics.RuntimeExecutionTime > TimeSpan.Zero);
+ }
+ else
+ {
+ Assert.AreEqual(0, metrics.CumulativeMetrics.RetrievedDocumentSize);
+ }
+
using (StreamReader sr = new StreamReader(response.Content))
using (JsonTextReader jtr = new JsonTextReader(sr))
{
@@ -1317,9 +1340,9 @@ public async Task QuerySinglePartitionItemStreamTest(int perPKItemCount, int max
[TestMethod]
public async Task ItemMultiplePartitionQuery()
{
- IList deleteList = await ToDoActivity.CreateRandomItems(this.Container, 3, randomPartitionKey: true);
+ IList itemList = await ToDoActivity.CreateRandomItems(this.Container, 3, randomPartitionKey: true);
- ToDoActivity find = deleteList.First();
+ ToDoActivity find = itemList.First();
QueryDefinition sql = new QueryDefinition("select * from toDoActivity t where t.id = '" + find.id + "'");
QueryRequestOptions requestOptions = new QueryRequestOptions()
@@ -1345,6 +1368,111 @@ public async Task ItemMultiplePartitionQuery()
ToDoActivity response = iter.First();
Assert.AreEqual(find.id, response.id);
}
+
+ ServerSideCumulativeMetrics metrics = iter.Diagnostics.GetQueryMetrics();
+
+ if (metrics != null)
+ {
+ Assert.IsTrue(metrics.PartitionedMetrics.Count == 3);
+ Assert.IsTrue(metrics.CumulativeMetrics.TotalTime > TimeSpan.Zero);
+ Assert.IsTrue(metrics.CumulativeMetrics.QueryPreparationTime > TimeSpan.Zero);
+
+ foreach (ServerSidePartitionedMetrics partitionedMetrics in metrics.PartitionedMetrics)
+ {
+ Assert.IsNotNull(partitionedMetrics);
+ Assert.IsNotNull(partitionedMetrics.PartitionKeyRangeId);
+ }
+
+ if (metrics.CumulativeMetrics.RetrievedDocumentCount >= 1)
+ {
+ Assert.IsTrue(metrics.CumulativeMetrics.RetrievedDocumentSize > 0);
+ Assert.IsTrue(metrics.CumulativeMetrics.DocumentLoadTime > TimeSpan.Zero);
+ Assert.IsTrue(metrics.CumulativeMetrics.RuntimeExecutionTime > TimeSpan.Zero);
+ }
+ else
+ {
+ Assert.AreEqual(0, metrics.CumulativeMetrics.RetrievedDocumentSize);
+ }
+ }
+ else
+ {
+ string diag = iter.Diagnostics.ToString();
+ Assert.IsNotNull(diag);
+ }
+ }
+
+ Assert.IsTrue(found);
+ }
+
+ ///
+ /// Validate single partition query using gateway mode.
+ ///
+ [TestMethod]
+ public async Task ItemSinglePartitionQueryGateway()
+ {
+ ContainerResponse containerResponse = await this.database.CreateContainerAsync(
+ new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPath: "/pk"));
+
+ Container createdContainer = (ContainerInlineCore)containerResponse;
+ CosmosClient client1 = TestCommon.CreateCosmosClient(useGateway: true);
+
+ Container container = client1.GetContainer(this.database.Id, createdContainer.Id);
+
+ string findId = "id2002";
+ ToDoActivity item = ToDoActivity.CreateRandomToDoActivity("pk2002", findId);
+ await container.CreateItemAsync(item);
+
+ QueryDefinition sql = new QueryDefinition("select * from toDoActivity t where t.id = '" + findId + "'");
+
+ QueryRequestOptions requestOptions = new QueryRequestOptions()
+ {
+ MaxBufferedItemCount = 10,
+ ResponseContinuationTokenLimitInKb = 500,
+ MaxItemCount = 1,
+ MaxConcurrency = 1,
+ };
+
+ FeedIterator feedIterator = container.GetItemQueryIterator(
+ sql,
+ requestOptions: requestOptions);
+
+ bool found = false;
+ while (feedIterator.HasMoreResults)
+ {
+ FeedResponse iter = await feedIterator.ReadNextAsync();
+ Assert.IsTrue(iter.Count() <= 1);
+ if (iter.Count() == 1)
+ {
+ found = true;
+ ToDoActivity response = iter.First();
+ Assert.AreEqual(findId, response.id);
+ }
+
+ ServerSideCumulativeMetrics metrics = iter.Diagnostics.GetQueryMetrics();
+
+ if (metrics != null)
+ {
+ Assert.IsTrue(metrics.PartitionedMetrics.Count == 1);
+ Assert.IsTrue(metrics.CumulativeMetrics.TotalTime > TimeSpan.Zero);
+ Assert.IsTrue(metrics.CumulativeMetrics.QueryPreparationTime > TimeSpan.Zero);
+
+ foreach (ServerSidePartitionedMetrics partitionedMetrics in metrics.PartitionedMetrics)
+ {
+ Assert.IsNotNull(partitionedMetrics);
+ Assert.IsNull(partitionedMetrics.PartitionKeyRangeId);
+ }
+
+ if (metrics.CumulativeMetrics.RetrievedDocumentCount >= 1)
+ {
+ Assert.IsTrue(metrics.CumulativeMetrics.RetrievedDocumentSize > 0);
+ Assert.IsTrue(metrics.CumulativeMetrics.DocumentLoadTime > TimeSpan.Zero);
+ Assert.IsTrue(metrics.CumulativeMetrics.RuntimeExecutionTime > TimeSpan.Zero);
+ }
+ else
+ {
+ Assert.AreEqual(0, metrics.CumulativeMetrics.RetrievedDocumentSize);
+ }
+ }
}
Assert.IsTrue(found);
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsDatumVisitor.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsDatumVisitor.cs
index 200150875b..c100146bdb 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsDatumVisitor.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryPerfTest/QueryStatisticsDatumVisitor.cs
@@ -41,13 +41,13 @@ public void AddGetCosmosElementResponseTime(double time)
public void Visit(QueryMetricsTraceDatum queryMetricsTraceDatum)
{
- this.queryMetrics.RetrievedDocumentCount = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.RetrievedDocumentCount;
- this.queryMetrics.RetrievedDocumentSize = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.RetrievedDocumentSize;
- this.queryMetrics.OutputDocumentCount = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.OutputDocumentCount;
- this.queryMetrics.OutputDocumentSize = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.OutputDocumentSize;
- this.queryMetrics.TotalQueryExecutionTime = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.TotalTime.TotalMilliseconds;
- this.queryMetrics.DocumentLoadTime = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.DocumentLoadTime.TotalMilliseconds;
- this.queryMetrics.DocumentWriteTime = queryMetricsTraceDatum.QueryMetrics.BackendMetrics.DocumentWriteTime.TotalMilliseconds;
+ this.queryMetrics.RetrievedDocumentCount = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.RetrievedDocumentCount;
+ this.queryMetrics.RetrievedDocumentSize = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.RetrievedDocumentSize;
+ this.queryMetrics.OutputDocumentCount = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.OutputDocumentCount;
+ this.queryMetrics.OutputDocumentSize = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.OutputDocumentSize;
+ this.queryMetrics.TotalQueryExecutionTime = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.TotalTime.TotalMilliseconds;
+ this.queryMetrics.DocumentLoadTime = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.DocumentLoadTime.TotalMilliseconds;
+ this.queryMetrics.DocumentWriteTime = queryMetricsTraceDatum.QueryMetrics.ServerSideMetrics.DocumentWriteTime.TotalMilliseconds;
}
public void Visit(ClientSideRequestStatisticsTraceDatum clientSideRequestStatisticsTraceDatum)
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryTests.cs
index afc25ec771..d971223f09 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/QueryTests.cs
@@ -1870,11 +1870,11 @@ public async Task TestQueryMetricsNonZero()
QueryMetrics queryMetrics = QueryMetrics.CreateFromIEnumerable(feedResonse.QueryMetrics.Values);
- Assert.IsTrue(queryMetrics.BackendMetrics.RetrievedDocumentCount > 0);
- Assert.IsTrue(queryMetrics.BackendMetrics.RetrievedDocumentSize > 0);
- Assert.IsTrue(queryMetrics.BackendMetrics.OutputDocumentCount > 0);
- Assert.IsTrue(queryMetrics.BackendMetrics.OutputDocumentSize > 0);
- Assert.IsTrue(queryMetrics.BackendMetrics.IndexHitRatio > 0);
+ Assert.IsTrue(queryMetrics.ServerSideMetrics.RetrievedDocumentCount > 0);
+ Assert.IsTrue(queryMetrics.ServerSideMetrics.RetrievedDocumentSize > 0);
+ Assert.IsTrue(queryMetrics.ServerSideMetrics.OutputDocumentCount > 0);
+ Assert.IsTrue(queryMetrics.ServerSideMetrics.OutputDocumentSize > 0);
+ Assert.IsTrue(queryMetrics.ServerSideMetrics.IndexHitRatio > 0);
await client.DeleteDatabaseAsync(database);
}
@@ -1960,7 +1960,7 @@ private void TestForceQueryScanHeaders(Database database, bool partitionedCollec
query,
feedOptions).AsDocumentQuery().ExecuteNextAsync().Result;
queryMetrics = result.QueryMetrics.Values.Aggregate((curr, acc) => curr + acc);
- Assert.AreEqual(TimeSpan.Zero, queryMetrics.BackendMetrics.IndexLookupTime);
+ Assert.AreEqual(TimeSpan.Zero, queryMetrics.ServerSideMetrics.IndexLookupTime);
// Without ForceQueryScan
feedOptions = new FeedOptions()
@@ -1976,7 +1976,7 @@ private void TestForceQueryScanHeaders(Database database, bool partitionedCollec
query,
feedOptions).AsDocumentQuery().ExecuteNextAsync().Result;
queryMetrics = result.QueryMetrics.Values.Aggregate((curr, acc) => curr + acc);
- Assert.AreNotEqual(TimeSpan.Zero, queryMetrics.BackendMetrics.IndexLookupTime);
+ Assert.AreNotEqual(TimeSpan.Zero, queryMetrics.ServerSideMetrics.IndexLookupTime);
}
private void TestFeedOptionInput(
@@ -2315,19 +2315,19 @@ private void ValidateQueryMetrics(QueryMetrics metrics)
Assert.AreEqual(0, metrics.ClientSideMetrics.Retries);
//We are not checking VMExecutionTime, since that is not a public property
//Assert.IsTrue(metrics.QueryEngineTimes.VMExecutionTime.TotalMilliseconds > 0, "Expected VMExecutionTimeInMs to be > 0, metrics = {0}", metrics);
- Assert.IsTrue(metrics.BackendMetrics.QueryPreparationTimes.QueryCompilationTime.TotalMilliseconds > 0, "Expected CompileTimeInMs to be > 0, metrics = {0}", metrics);
+ Assert.IsTrue(metrics.ServerSideMetrics.QueryPreparationTimes.QueryCompilationTime.TotalMilliseconds > 0, "Expected CompileTimeInMs to be > 0, metrics = {0}", metrics);
//We are not checking DocumentLoadTime and RetrievedDocumentCount, since some queries don't return any documents (especially in the last continuation).
//Assert.IsTrue(metrics.QueryEngineTimes.DocumentLoadTime.TotalMilliseconds > 0, "Expected DocumentLoadTimeInMs to be > 0, metrics = {0}", metrics);
//Assert.IsTrue(metrics.RetrievedDocumentCount > 0, "Expected RetrievedDocumentCount to be > 0, metrics = {0}", metrics);
- Assert.IsTrue(metrics.BackendMetrics.TotalTime.TotalMilliseconds > 0, "Expected TotalExecutionTimeInMs to be > 0, metrics = {0}", metrics);
+ Assert.IsTrue(metrics.ServerSideMetrics.TotalTime.TotalMilliseconds > 0, "Expected TotalExecutionTimeInMs to be > 0, metrics = {0}", metrics);
//Assert.IsTrue(metrics.QueryEngineTimes.WriteOutputTime.TotalMilliseconds > 0, "Expected WriteOutputTimeInMs to be > 0, metrics = {0}", metrics);
//Assert.IsTrue(metrics.RetrievedDocumentSize > 0, "Expected RetrievedDocumentSize to be > 0, metrics = {0}", metrics);
- Assert.IsTrue(metrics.BackendMetrics.IndexLookupTime.TotalMilliseconds > 0, "Expected IndexLookupTimeInMs to be > 0, metrics = {0}", metrics);
- Assert.IsTrue(metrics.BackendMetrics.QueryPreparationTimes.LogicalPlanBuildTime.TotalMilliseconds > 0, "Expected LogicalPlanBuildTimeInMs to be > 0, metrics = {0}", metrics);
+ Assert.IsTrue(metrics.ServerSideMetrics.IndexLookupTime.TotalMilliseconds > 0, "Expected IndexLookupTimeInMs to be > 0, metrics = {0}", metrics);
+ Assert.IsTrue(metrics.ServerSideMetrics.QueryPreparationTimes.LogicalPlanBuildTime.TotalMilliseconds > 0, "Expected LogicalPlanBuildTimeInMs to be > 0, metrics = {0}", metrics);
//Assert.AreEqual(metrics.QueryEngineTimes.VMExecutionTime - metrics.QueryEngineTimes.IndexLookupTime - metrics.QueryEngineTimes.DocumentLoadTime - metrics.QueryEngineTimes.WriteOutputTime,
// metrics.QueryEngineTimes.RuntimeExecutionTimes.TotalTime);
- Assert.IsTrue(metrics.BackendMetrics.RuntimeExecutionTimes.QueryEngineExecutionTime >= metrics.BackendMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime + metrics.BackendMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime,
- "Expected Query VM Execution Time to be > {0}, metrics = {1}", metrics.BackendMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime + metrics.BackendMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime, metrics);
+ Assert.IsTrue(metrics.ServerSideMetrics.RuntimeExecutionTimes.QueryEngineExecutionTime >= metrics.ServerSideMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime + metrics.ServerSideMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime,
+ "Expected Query VM Execution Time to be > {0}, metrics = {1}", metrics.ServerSideMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime + metrics.ServerSideMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime, metrics);
//Assert.IsTrue(metrics.QueryEngineTimes.VMExecutionTime >= metrics.QueryEngineTimes.RuntimeExecutionTimes.TotalTime,
// "Expected Query VM Execution Time to be > {0}, metrics = {1}", metrics.QueryEngineTimes.RuntimeExecutionTimes.TotalTime, metrics);
}
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Query/Metrics/Performance.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Query/Metrics/Performance.cs
index 6d5db62d6d..40484e792c 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Query/Metrics/Performance.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Performance.Tests/Query/Metrics/Performance.cs
@@ -37,7 +37,7 @@ public void TestParse()
ValueStopwatch stopwatch = ValueStopwatch.StartNew();
for (int i = 0; i < 100000; i++)
{
- BackendMetricsParser.TryParse(delimitedString, out BackendMetrics backendMetrics);
+ ServerSideMetricsParser.TryParse(delimitedString, out ServerSideMetricsInternal serverSideMetrics);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml
index d1dee72a0f..75cd9894de 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml
@@ -126,7 +126,7 @@
{
QueryMetricsTraceDatum datum = new QueryMetricsTraceDatum(
new Lazy(() => new QueryMetrics(
- BackendMetricsTests.MockBackendMetrics,
+ ServerSideMetricsTests.ServerSideMetrics,
IndexUtilizationInfoTests.MockIndexUtilizationInfo,
ClientSideMetricsTests.MockClientSideMetrics)));
rootTrace.AddDatum("Query Metrics", datum);
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json
index 7fde376d49..759762f21f 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetSDKAPI.json
@@ -3124,6 +3124,11 @@
"Attributes": [],
"MethodInfo": "Int32 GetFailedRequestCount();IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
},
+ "Microsoft.Azure.Cosmos.ServerSideCumulativeMetrics GetQueryMetrics()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "Microsoft.Azure.Cosmos.ServerSideCumulativeMetrics GetQueryMetrics();IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
"System.Collections.Generic.IReadOnlyList`1[System.ValueTuple`2[System.String,System.Uri]] GetContactedRegions()": {
"Type": "Method",
"Attributes": [],
@@ -9029,6 +9034,194 @@
},
"NestedTypes": {}
},
+ "Microsoft.Azure.Cosmos.ServerSideCumulativeMetrics;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
+ "Subclasses": {},
+ "Members": {
+ "Microsoft.Azure.Cosmos.ServerSideMetrics CumulativeMetrics": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "Microsoft.Azure.Cosmos.ServerSideMetrics CumulativeMetrics;CanRead:True;CanWrite:False;Microsoft.Azure.Cosmos.ServerSideMetrics get_CumulativeMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Microsoft.Azure.Cosmos.ServerSideMetrics get_CumulativeMetrics()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "Microsoft.Azure.Cosmos.ServerSideMetrics get_CumulativeMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Collections.Generic.IReadOnlyList`1[Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics] get_PartitionedMetrics()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.Collections.Generic.IReadOnlyList`1[Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics] get_PartitionedMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Collections.Generic.IReadOnlyList`1[Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics] PartitionedMetrics": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.Collections.Generic.IReadOnlyList`1[Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics] PartitionedMetrics;CanRead:True;CanWrite:False;System.Collections.Generic.IReadOnlyList`1[Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics] get_PartitionedMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ }
+ },
+ "NestedTypes": {}
+ },
+ "Microsoft.Azure.Cosmos.ServerSideMetrics;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
+ "Subclasses": {},
+ "Members": {
+ "Double get_IndexHitRatio()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "Double get_IndexHitRatio();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Double IndexHitRatio": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "Double IndexHitRatio;CanRead:True;CanWrite:False;Double get_IndexHitRatio();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Int64 get_OutputDocumentCount()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "Int64 get_OutputDocumentCount();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Int64 get_OutputDocumentSize()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "Int64 get_OutputDocumentSize();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Int64 get_RetrievedDocumentCount()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "Int64 get_RetrievedDocumentCount();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Int64 get_RetrievedDocumentSize()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "Int64 get_RetrievedDocumentSize();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Int64 OutputDocumentCount": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "Int64 OutputDocumentCount;CanRead:True;CanWrite:False;Int64 get_OutputDocumentCount();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Int64 OutputDocumentSize": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "Int64 OutputDocumentSize;CanRead:True;CanWrite:False;Int64 get_OutputDocumentSize();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Int64 RetrievedDocumentCount": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "Int64 RetrievedDocumentCount;CanRead:True;CanWrite:False;Int64 get_RetrievedDocumentCount();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Int64 RetrievedDocumentSize": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "Int64 RetrievedDocumentSize;CanRead:True;CanWrite:False;Int64 get_RetrievedDocumentSize();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan DocumentLoadTime": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan DocumentLoadTime;CanRead:True;CanWrite:False;System.TimeSpan get_DocumentLoadTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan DocumentWriteTime": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan DocumentWriteTime;CanRead:True;CanWrite:False;System.TimeSpan get_DocumentWriteTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan get_DocumentLoadTime()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan get_DocumentLoadTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan get_DocumentWriteTime()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan get_DocumentWriteTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan get_IndexLookupTime()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan get_IndexLookupTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan get_QueryPreparationTime()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan get_QueryPreparationTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan get_RuntimeExecutionTime()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan get_RuntimeExecutionTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan get_TotalTime()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan get_TotalTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan get_VMExecutionTime()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan get_VMExecutionTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan IndexLookupTime": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan IndexLookupTime;CanRead:True;CanWrite:False;System.TimeSpan get_IndexLookupTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan QueryPreparationTime": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan QueryPreparationTime;CanRead:True;CanWrite:False;System.TimeSpan get_QueryPreparationTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan RuntimeExecutionTime": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan RuntimeExecutionTime;CanRead:True;CanWrite:False;System.TimeSpan get_RuntimeExecutionTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan TotalTime": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan TotalTime;CanRead:True;CanWrite:False;System.TimeSpan get_TotalTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.TimeSpan VMExecutionTime": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.TimeSpan VMExecutionTime;CanRead:True;CanWrite:False;System.TimeSpan get_VMExecutionTime();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ }
+ },
+ "NestedTypes": {}
+ },
+ "Microsoft.Azure.Cosmos.ServerSidePartitionedMetrics;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
+ "Subclasses": {},
+ "Members": {
+ "Microsoft.Azure.Cosmos.ServerSideMetrics get_ServerSideMetrics()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "Microsoft.Azure.Cosmos.ServerSideMetrics get_ServerSideMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Microsoft.Azure.Cosmos.ServerSideMetrics ServerSideMetrics": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "Microsoft.Azure.Cosmos.ServerSideMetrics ServerSideMetrics;CanRead:True;CanWrite:False;Microsoft.Azure.Cosmos.ServerSideMetrics get_ServerSideMetrics();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Nullable`1[System.Int32] get_PartitionKeyRangeId()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.Nullable`1[System.Int32] get_PartitionKeyRangeId();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Nullable`1[System.Int32] PartitionKeyRangeId": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.Nullable`1[System.Int32] PartitionKeyRangeId;CanRead:True;CanWrite:False;System.Nullable`1[System.Int32] get_PartitionKeyRangeId();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.String FeedRange": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.String FeedRange;CanRead:True;CanWrite:False;System.String get_FeedRange();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.String get_FeedRange()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.String get_FeedRange();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ }
+ },
+ "NestedTypes": {}
+ },
"Microsoft.Azure.Cosmos.Spatial.BoundingBox;System.Object;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
"Subclasses": {},
"Members": {
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ClientSideMetricsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ClientSideMetricsTests.cs
index 4a446bb933..90f9fec8ad 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ClientSideMetricsTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ClientSideMetricsTests.cs
@@ -21,11 +21,11 @@ public class ClientSideMetricsTests
[TestMethod]
public void TestAccumulator()
{
- ClientSideMetrics.Accumulator accumulator = new ClientSideMetrics.Accumulator();
- accumulator = accumulator.Accumulate(MockClientSideMetrics);
- accumulator = accumulator.Accumulate(MockClientSideMetrics);
+ ClientSideMetricsAccumulator accumulator = new ClientSideMetricsAccumulator();
+ accumulator.Accumulate(MockClientSideMetrics);
+ accumulator.Accumulate(MockClientSideMetrics);
- ClientSideMetrics doubleMetrics = ClientSideMetrics.Accumulator.ToClientSideMetrics(accumulator);
+ ClientSideMetrics doubleMetrics = accumulator.GetClientSideMetrics();
Assert.AreEqual(2 * MockClientSideMetrics.Retries, doubleMetrics.Retries);
Assert.AreEqual(2 * MockClientSideMetrics.RequestCharge, doubleMetrics.RequestCharge);
Assert.AreEqual(2 * MockClientSideMetrics.FetchExecutionRanges.Count(), doubleMetrics.FetchExecutionRanges.Count());
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/IndexUtilizationInfoTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/IndexUtilizationInfoTests.cs
index 13702de3b5..9fe272a6bd 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/IndexUtilizationInfoTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/IndexUtilizationInfoTests.cs
@@ -8,7 +8,6 @@ namespace Microsoft.Azure.Cosmos.Tests.Query.Metrics
using VisualStudio.TestTools.UnitTesting;
using Microsoft.Azure.Cosmos.Query.Core.Metrics;
using System.Collections.Generic;
- using System.Text;
[TestClass]
public class IndexUtilizationInfoTests
@@ -35,11 +34,11 @@ public class IndexUtilizationInfoTests
[TestMethod]
public void TestAccumulator()
{
- IndexUtilizationInfo.Accumulator accumulator = new IndexUtilizationInfo.Accumulator();
- accumulator = accumulator.Accumulate(MockIndexUtilizationInfo);
- accumulator = accumulator.Accumulate(MockIndexUtilizationInfo);
+ IndexUtilizationInfoAccumulator accumulator = new IndexUtilizationInfoAccumulator();
+ accumulator.Accumulate(MockIndexUtilizationInfo);
+ accumulator.Accumulate(MockIndexUtilizationInfo);
- IndexUtilizationInfo doubleInfo = IndexUtilizationInfo.Accumulator.ToIndexUtilizationInfo(accumulator);
+ IndexUtilizationInfo doubleInfo = accumulator.GetIndexUtilizationInfo();
Assert.AreEqual(2 * MockIndexUtilizationInfo.PotentialSingleIndexes.Count, doubleInfo.PotentialSingleIndexes.Count);
Assert.AreEqual(2 * MockIndexUtilizationInfo.UtilizedSingleIndexes.Count, doubleInfo.UtilizedSingleIndexes.Count);
Assert.AreEqual(2 * MockIndexUtilizationInfo.PotentialCompositeIndexes.Count, doubleInfo.PotentialCompositeIndexes.Count);
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/QueryMetricsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/QueryMetricsTests.cs
index d655de097a..17f73616c2 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/QueryMetricsTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/QueryMetricsTests.cs
@@ -12,21 +12,21 @@ namespace Microsoft.Azure.Cosmos.Tests.Query.Metrics
public class QueryMetricsTests
{
private static readonly QueryMetrics MockQueryMetrics = new QueryMetrics(
- BackendMetricsTests.MockBackendMetrics,
+ ServerSideMetricsTests.ServerSideMetrics,
IndexUtilizationInfoTests.MockIndexUtilizationInfo,
ClientSideMetricsTests.MockClientSideMetrics);
[TestMethod]
public void TestAccumulator()
{
- QueryMetrics.Accumulator accumulator = new QueryMetrics.Accumulator();
- accumulator = accumulator.Accumulate(MockQueryMetrics);
- accumulator = accumulator.Accumulate(MockQueryMetrics);
+ QueryMetricsAccumulator accumulator = new QueryMetricsAccumulator();
+ accumulator.Accumulate(MockQueryMetrics);
+ accumulator.Accumulate(MockQueryMetrics);
- QueryMetrics doubleQueryMetrics = QueryMetrics.Accumulator.ToQueryMetrics(accumulator);
+ QueryMetrics doubleQueryMetrics = accumulator.GetQueryMetrics();
// Spot check
- Assert.AreEqual(2 * BackendMetricsTests.MockBackendMetrics.IndexLookupTime, doubleQueryMetrics.BackendMetrics.IndexLookupTime);
+ Assert.AreEqual(2 * ServerSideMetricsTests.ServerSideMetrics.IndexLookupTime, doubleQueryMetrics.ServerSideMetrics.IndexLookupTime);
Assert.AreEqual(2 * IndexUtilizationInfoTests.MockIndexUtilizationInfo.PotentialSingleIndexes.Count, doubleQueryMetrics.IndexUtilizationInfo.PotentialSingleIndexes.Count);
Assert.AreEqual(2 * ClientSideMetricsTests.MockClientSideMetrics.RequestCharge, doubleQueryMetrics.ClientSideMetrics.RequestCharge);
}
@@ -37,7 +37,7 @@ public void TestAddition()
QueryMetrics doubleQueryMetrics = MockQueryMetrics + MockQueryMetrics;
// Spot check
- Assert.AreEqual(2 * BackendMetricsTests.MockBackendMetrics.IndexLookupTime, doubleQueryMetrics.BackendMetrics.IndexLookupTime);
+ Assert.AreEqual(2 * ServerSideMetricsTests.ServerSideMetrics.IndexLookupTime, doubleQueryMetrics.ServerSideMetrics.IndexLookupTime);
Assert.AreEqual(2 * IndexUtilizationInfoTests.MockIndexUtilizationInfo.PotentialSingleIndexes.Count, doubleQueryMetrics.IndexUtilizationInfo.PotentialSingleIndexes.Count);
Assert.AreEqual(2 * ClientSideMetricsTests.MockClientSideMetrics.RequestCharge, doubleQueryMetrics.ClientSideMetrics.RequestCharge);
}
@@ -48,7 +48,7 @@ public void TestCreateFromEnumerable()
QueryMetrics tripleQueryMetrics = QueryMetrics.CreateFromIEnumerable(new List() { MockQueryMetrics, MockQueryMetrics, MockQueryMetrics });
// Spot check
- Assert.AreEqual(3 * BackendMetricsTests.MockBackendMetrics.IndexLookupTime, tripleQueryMetrics.BackendMetrics.IndexLookupTime);
+ Assert.AreEqual(3 * ServerSideMetricsTests.ServerSideMetrics.IndexLookupTime, tripleQueryMetrics.ServerSideMetrics.IndexLookupTime);
Assert.AreEqual(3 * IndexUtilizationInfoTests.MockIndexUtilizationInfo.PotentialSingleIndexes.Count, tripleQueryMetrics.IndexUtilizationInfo.PotentialSingleIndexes.Count);
Assert.AreEqual(3 * ClientSideMetricsTests.MockClientSideMetrics.RequestCharge, tripleQueryMetrics.ClientSideMetrics.RequestCharge);
}
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/BackendMetricsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ServerSideMetricsTests.cs
similarity index 78%
rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/BackendMetricsTests.cs
rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ServerSideMetricsTests.cs
index 221057790d..4c6e382ebf 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/BackendMetricsTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/ServerSideMetricsTests.cs
@@ -7,11 +7,10 @@ namespace Microsoft.Azure.Cosmos.Tests.Query.Metrics
using System;
using VisualStudio.TestTools.UnitTesting;
using Microsoft.Azure.Cosmos.Query.Core.Metrics;
- using System.Diagnostics;
using System.Collections.Generic;
[TestClass]
- public class BackendMetricsTests
+ public class ServerSideMetricsTests
{
private static readonly TimeSpan totalExecutionTime = TimeSpan.FromTicks((long)(TimeSpan.TicksPerMillisecond * 33.67));
private static readonly TimeSpan queryCompileTime = TimeSpan.FromTicks((long)(TimeSpan.TicksPerMillisecond * 0.06));
@@ -32,14 +31,14 @@ public class BackendMetricsTests
private static readonly string delimitedString = $"totalExecutionTimeInMs={totalExecutionTime.TotalMilliseconds};queryCompileTimeInMs={queryCompileTime.TotalMilliseconds};queryLogicalPlanBuildTimeInMs={logicalPlanBuildTime.TotalMilliseconds};queryPhysicalPlanBuildTimeInMs={physicalPlanBuildTime.TotalMilliseconds};queryOptimizationTimeInMs={queryOptimizationTime.TotalMilliseconds};VMExecutionTimeInMs={vmExecutionTime.TotalMilliseconds};indexLookupTimeInMs={indexLookupTime.TotalMilliseconds};documentLoadTimeInMs={documentLoadTime.TotalMilliseconds};systemFunctionExecuteTimeInMs={systemFunctionExecuteTime.TotalMilliseconds};userFunctionExecuteTimeInMs={userFunctionExecuteTime.TotalMilliseconds};retrievedDocumentCount={retrievedDocumentCount};retrievedDocumentSize={retrievedDocumentSize};outputDocumentCount={outputDocumentCount};outputDocumentSize={outputDocumentSize};writeOutputTimeInMs={documentWriteTime.TotalMilliseconds};indexUtilizationRatio={indexHitRatio}";
- internal static readonly BackendMetrics MockBackendMetrics = new BackendMetrics(
+ internal static readonly ServerSideMetricsInternal ServerSideMetrics = new ServerSideMetricsInternal(
retrievedDocumentCount,
retrievedDocumentSize,
outputDocumentCount,
outputDocumentSize,
indexHitRatio,
totalExecutionTime,
- new QueryPreparationTimes(
+ new QueryPreparationTimesInternal(
queryCompileTime,
logicalPlanBuildTime,
physicalPlanBuildTime,
@@ -47,7 +46,7 @@ public class BackendMetricsTests
indexLookupTime,
documentLoadTime,
vmExecutionTime,
- new RuntimeExecutionTimes(
+ new RuntimeExecutionTimesInternal(
totalExecutionTime - systemFunctionExecuteTime - userFunctionExecuteTime,
systemFunctionExecuteTime,
userFunctionExecuteTime),
@@ -57,13 +56,13 @@ public class BackendMetricsTests
[TestMethod]
public void TestParse()
{
- BackendMetricsTests.ValidateParse(delimitedString, MockBackendMetrics);
+ ServerSideMetricsTests.ValidateParse(delimitedString, ServerSideMetrics);
}
[TestMethod]
public void TestParseEmptyString()
{
- BackendMetricsTests.ValidateParse(string.Empty, BackendMetrics.Empty);
+ ServerSideMetricsTests.ValidateParse(string.Empty, ServerSideMetricsInternal.Empty);
}
[TestMethod]
@@ -72,14 +71,14 @@ public void TestParseStringWithMissingFields()
TimeSpan totalExecutionTime = TimeSpan.FromTicks((long)(TimeSpan.TicksPerMillisecond * 33.67));
string delimitedString = $"totalExecutionTimeInMs={totalExecutionTime.TotalMilliseconds}";
- BackendMetrics expected = new BackendMetrics(
+ ServerSideMetricsInternal expected = new ServerSideMetricsInternal(
default(long),
default(long),
default(long),
default(long),
default(double),
totalExecutionTime,
- new QueryPreparationTimes(
+ new QueryPreparationTimesInternal(
default(TimeSpan),
default(TimeSpan),
default(TimeSpan),
@@ -87,27 +86,27 @@ public void TestParseStringWithMissingFields()
default(TimeSpan),
default(TimeSpan),
default(TimeSpan),
- new RuntimeExecutionTimes(
+ new RuntimeExecutionTimesInternal(
default(TimeSpan),
default(TimeSpan),
default(TimeSpan)),
default(TimeSpan));
- BackendMetricsTests.ValidateParse(delimitedString, expected);
+ ServerSideMetricsTests.ValidateParse(delimitedString, expected);
}
[TestMethod]
public void TestParseStringWithTrailingUnknownField()
{
string delimitedString = $"thisIsNotAKnownField=asdf";
- BackendMetrics expected = new BackendMetrics(
+ ServerSideMetricsInternal expected = new ServerSideMetricsInternal(
default(long),
default(long),
default(long),
default(long),
default(double),
default(TimeSpan),
- new QueryPreparationTimes(
+ new QueryPreparationTimesInternal(
default(TimeSpan),
default(TimeSpan),
default(TimeSpan),
@@ -115,13 +114,13 @@ public void TestParseStringWithTrailingUnknownField()
default(TimeSpan),
default(TimeSpan),
default(TimeSpan),
- new RuntimeExecutionTimes(
+ new RuntimeExecutionTimesInternal(
default(TimeSpan),
default(TimeSpan),
default(TimeSpan)),
default(TimeSpan));
- BackendMetricsTests.ValidateParse(delimitedString, expected);
+ ServerSideMetricsTests.ValidateParse(delimitedString, expected);
}
[TestMethod]
@@ -129,7 +128,7 @@ public void TestParseStringWithTrailingUnknownField()
[DataRow("totalExecutionTimeInMs=33.6+totalExecutionTimeInMs=33.6", DisplayName = "Wrong Delimiter")]
public void TestNegativeCases(string delimitedString)
{
- Assert.IsFalse(BackendMetricsParser.TryParse(delimitedString, out BackendMetrics backendMetrics));
+ Assert.IsFalse(ServerSideMetricsParser.TryParse(delimitedString, out ServerSideMetricsInternal serverSideMetrics));
}
[TestMethod]
@@ -137,14 +136,14 @@ public void TestParseStringWithUnknownField()
{
TimeSpan totalExecutionTime = TimeSpan.FromTicks((long)(TimeSpan.TicksPerMillisecond * 33.67));
string delimitedString = $"totalExecutionTimeInMs={totalExecutionTime.TotalMilliseconds};thisIsNotAKnownField={totalExecutionTime.TotalMilliseconds};totalExecutionTimeInMs={totalExecutionTime.TotalMilliseconds}";
- BackendMetrics expected = new BackendMetrics(
+ ServerSideMetricsInternal expected = new ServerSideMetricsInternal(
default(long),
default(long),
default(long),
default(long),
default(double),
totalExecutionTime,
- new QueryPreparationTimes(
+ new QueryPreparationTimesInternal(
default(TimeSpan),
default(TimeSpan),
default(TimeSpan),
@@ -152,31 +151,34 @@ public void TestParseStringWithUnknownField()
default(TimeSpan),
default(TimeSpan),
default(TimeSpan),
- new RuntimeExecutionTimes(
+ new RuntimeExecutionTimesInternal(
default(TimeSpan),
default(TimeSpan),
default(TimeSpan)),
default(TimeSpan));
- BackendMetricsTests.ValidateParse(delimitedString, expected);
+ ServerSideMetricsTests.ValidateParse(delimitedString, expected);
}
[TestMethod]
public void TestAccumulator()
{
- BackendMetrics.Accumulator accumulator = new BackendMetrics.Accumulator();
- accumulator = accumulator.Accumulate(MockBackendMetrics);
- accumulator = accumulator.Accumulate(MockBackendMetrics);
+ ServerSideMetricsInternalAccumulator accumulator = new ServerSideMetricsInternalAccumulator();
+ accumulator.Accumulate(ServerSideMetrics);
+ accumulator.Accumulate(ServerSideMetrics);
+ ServerSideMetricsInternal serverSideMetricsFromAddition = accumulator.GetServerSideMetrics();
- BackendMetrics backendMetricsFromAddition = BackendMetrics.Accumulator.ToBackendMetrics(accumulator);
- BackendMetrics expected = new BackendMetrics(
+ List metricsList = new List { ServerSideMetrics, ServerSideMetrics };
+ ServerSideMetricsInternal serverSideMetricsFromCreate = ServerSideMetricsInternal.Create(metricsList);
+
+ ServerSideMetricsInternal expected = new ServerSideMetricsInternal(
retrievedDocumentCount * 2,
retrievedDocumentSize * 2,
outputDocumentCount * 2,
outputDocumentSize * 2,
indexHitRatio,
totalExecutionTime * 2,
- new QueryPreparationTimes(
+ new QueryPreparationTimesInternal(
queryCompileTime * 2,
logicalPlanBuildTime * 2,
physicalPlanBuildTime * 2,
@@ -184,22 +186,22 @@ public void TestAccumulator()
indexLookupTime * 2,
documentLoadTime * 2,
vmExecutionTime * 2,
- new RuntimeExecutionTimes(
+ new RuntimeExecutionTimesInternal(
(totalExecutionTime - systemFunctionExecuteTime - userFunctionExecuteTime) * 2,
systemFunctionExecuteTime * 2,
userFunctionExecuteTime * 2),
documentWriteTime * 2);
- BackendMetricsTests.ValidateBackendMetricsEquals(expected, backendMetricsFromAddition);
+ ServerSideMetricsTests.ValidateServerSideMetricsEquals(expected, serverSideMetricsFromAddition);
+ ServerSideMetricsTests.ValidateServerSideMetricsEquals(expected, serverSideMetricsFromCreate);
}
-
- private static void ValidateParse(string delimitedString, BackendMetrics expected)
+ private static void ValidateParse(string delimitedString, ServerSideMetricsInternal expected)
{
- Assert.IsTrue(BackendMetricsParser.TryParse(delimitedString, out BackendMetrics actual));
- BackendMetricsTests.ValidateBackendMetricsEquals(expected, actual);
+ Assert.IsTrue(ServerSideMetricsParser.TryParse(delimitedString, out ServerSideMetricsInternal actual));
+ ServerSideMetricsTests.ValidateServerSideMetricsEquals(expected, actual);
}
- private static void ValidateBackendMetricsEquals(BackendMetrics expected, BackendMetrics actual)
+ private static void ValidateServerSideMetricsEquals(ServerSideMetricsInternal expected, ServerSideMetricsInternal actual)
{
Assert.AreEqual(expected.DocumentLoadTime, actual.DocumentLoadTime);
Assert.AreEqual(expected.DocumentWriteTime, actual.DocumentWriteTime);
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs
index fe3dc7054f..2d69341182 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs
@@ -41,7 +41,7 @@ namespace Microsoft.Azure.Cosmos.Tests.Tracing
public sealed class TraceWriterBaselineTests : BaselineTests
{
private static readonly Lazy MockQueryMetrics = new Lazy(() => new QueryMetrics(
- BackendMetricsTests.MockBackendMetrics,
+ ServerSideMetricsTests.ServerSideMetrics,
IndexUtilizationInfoTests.MockIndexUtilizationInfo,
ClientSideMetricsTests.MockClientSideMetrics));
@@ -316,7 +316,7 @@ public void TraceData()
{
QueryMetricsTraceDatum datum = new QueryMetricsTraceDatum(
new Lazy(() => new QueryMetrics(
- BackendMetricsTests.MockBackendMetrics,
+ ServerSideMetricsTests.ServerSideMetrics,
IndexUtilizationInfoTests.MockIndexUtilizationInfo,
ClientSideMetricsTests.MockClientSideMetrics)));
rootTrace.AddDatum("Query Metrics", datum);