diff --git a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs
index cb3ffe6c04..4c753b0b27 100644
--- a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs
+++ b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosDiagnostics.cs
@@ -43,6 +43,16 @@ public virtual int GetFailedRequestCount()
throw new NotImplementedException($"{nameof(CosmosDiagnostics)}.{nameof(GetFailedRequestCount)}");
}
+ ///
+ /// This represents the accumulated backend query metrics for the request.
+ ///
+ /// The string represemation of the query metrics dictionary.
+ public virtual BackendAccumulatedMetrics GetQueryMetrics()
+ {
+ // Default implementation avoids breaking change for users upgrading.
+ throw new NotImplementedException($"{nameof(CosmosDiagnostics)}.{nameof(GetQueryMetrics)}");
+ }
+
///
/// Gets the string field instance in the Azure CosmosDB database service.
///
diff --git a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs
index 07e340f0ac..5c610de166 100644
--- a/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs
+++ b/Microsoft.Azure.Cosmos/src/Diagnostics/CosmosTraceDiagnostics.cs
@@ -9,6 +9,7 @@ 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;
@@ -49,11 +50,42 @@ public override TimeSpan GetClientElapsedTime()
return this.Value?.Summary?.RegionsContacted;
}
+ public override BackendAccumulatedMetrics GetQueryMetrics()
+ {
+ QueryMetrics queryMetrics = QueryMetrics.Empty;
+ this.WalkTraceTreeForQueryMetrics(this.Value, ref queryMetrics);
+ return new BackendAccumulatedMetrics(queryMetrics);
+ }
+
internal bool IsGoneExceptionHit()
{
return this.WalkTraceTreeForGoneException(this.Value);
}
+ private bool WalkTraceTreeForQueryMetrics(ITrace currentTrace, ref QueryMetrics queryMetrics)
+ {
+ if (currentTrace == null)
+ {
+ return false;
+ }
+
+ foreach (object datums in currentTrace.Data.Values)
+ {
+ if (datums is QueryMetricsTraceDatum queryMetricsTraceDatum)
+ {
+ queryMetrics += queryMetricsTraceDatum.QueryMetrics;
+ return true;
+ }
+ }
+
+ foreach (ITrace childTrace in currentTrace.Children)
+ {
+ this.WalkTraceTreeForQueryMetrics(childTrace, ref queryMetrics);
+ }
+
+ return false;
+ }
+
private bool WalkTraceTreeForGoneException(ITrace currentTrace)
{
if (currentTrace == null)
diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendAccumulatedMetrics.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendAccumulatedMetrics.cs
new file mode 100644
index 0000000000..b377e6b713
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/BackendAccumulatedMetrics.cs
@@ -0,0 +1,140 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+namespace Microsoft.Azure.Cosmos
+{
+ using System;
+ using Microsoft.Azure.Cosmos.Query.Core.Metrics;
+
+ ///
+ /// Exposed metrics received for queries from the backend.
+ ///
+ public sealed class BackendAccumulatedMetrics
+ {
+ internal BackendAccumulatedMetrics(QueryMetrics queryMetrics)
+ {
+ this.RetrievedDocumentCount = queryMetrics.BackendMetrics.RetrievedDocumentCount;
+ this.RetrievedDocumentSize = queryMetrics.BackendMetrics.RetrievedDocumentSize;
+ this.OutputDocumentCount = queryMetrics.BackendMetrics.OutputDocumentCount;
+ this.OutputDocumentSize = queryMetrics.BackendMetrics.OutputDocumentSize;
+ this.IndexHitRatio = queryMetrics.BackendMetrics.IndexHitRatio;
+ this.TotalTime = queryMetrics.BackendMetrics.TotalTime;
+ this.QueryCompilationTime = queryMetrics.BackendMetrics.QueryPreparationTimes.QueryCompilationTime;
+ this.LogicalPlanBuildTime = queryMetrics.BackendMetrics.QueryPreparationTimes.LogicalPlanBuildTime;
+ this.PhysicalPlanBuildTime = queryMetrics.BackendMetrics.QueryPreparationTimes.PhysicalPlanBuildTime;
+ this.QueryOptimizationTime = queryMetrics.BackendMetrics.QueryPreparationTimes.QueryOptimizationTime;
+ this.IndexLookupTime = queryMetrics.BackendMetrics.IndexLookupTime;
+ this.DocumentLoadTime = queryMetrics.BackendMetrics.DocumentLoadTime;
+ this.VMExecutionTime = queryMetrics.BackendMetrics.VMExecutionTime;
+ this.SystemFunctionExecutionTime = queryMetrics.BackendMetrics.RuntimeExecutionTimes.SystemFunctionExecutionTime;
+ this.UserDefinedFunctionExecutionTime = queryMetrics.BackendMetrics.RuntimeExecutionTimes.UserDefinedFunctionExecutionTime;
+ this.QueryEngineExecutionTime = queryMetrics.BackendMetrics.RuntimeExecutionTimes.QueryEngineExecutionTime;
+ this.DocumentWriteTime = queryMetrics.BackendMetrics.DocumentWriteTime;
+ }
+
+ ///
+ /// Gets the total query time in the Azure Cosmos database service.
+ ///
+ public TimeSpan TotalTime { get; }
+
+ ///
+ /// 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; }
+
+ ///
+ /// 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 TimeSpan 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 TimeSpan 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; }
+
+ ///
+ /// 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; }
+
+ ///
+ /// Gets the total query runtime execution time in the Azure Cosmos DB service.
+ ///
+ public TimeSpan QueryEngineExecutionTime { get; }
+
+ ///
+ /// String representation of the QueryBackendMetrics.
+ ///
+ /// Metric text
+ public override string ToString()
+ {
+ return $"totalExecutionTimeInMs={this.TotalTime.TotalMilliseconds};queryCompileTimeInMs={this.QueryCompilationTime.TotalMilliseconds};queryLogicalPlanBuildTimeInMs={this.LogicalPlanBuildTime.TotalMilliseconds};queryPhysicalPlanBuildTimeInMs={this.PhysicalPlanBuildTime.TotalMilliseconds};queryOptimizationTimeInMs={this.QueryOptimizationTime.TotalMilliseconds};indexLookupTimeInMs={this.IndexLookupTime.TotalMilliseconds};documentLoadTimeInMs={this.DocumentLoadTime.TotalMilliseconds};systemFunctionExecuteTimeInMs={this.SystemFunctionExecutionTime.TotalMilliseconds};userFunctionExecuteTimeInMs={this.UserDefinedFunctionExecutionTime.TotalMilliseconds};retrievedDocumentCount={this.RetrievedDocumentCount};retrievedDocumentSize={this.RetrievedDocumentSize};outputDocumentCount={this.OutputDocumentCount};outputDocumentSize={this.OutputDocumentSize};writeOutputTimeInMs={this.DocumentWriteTime.TotalMilliseconds};indexUtilizationRatio={this.IndexHitRatio}";
+ }
+
+ }
+}
\ 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
index 0fd8dc22f0..9a4dadc6f3 100644
--- a/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimes.cs
+++ b/Microsoft.Azure.Cosmos/src/Query/Core/Metrics/RuntimeExecutionTimes.cs
@@ -62,9 +62,9 @@ public Accumulator(TimeSpan queryEngineExecutionTime, TimeSpan systemFunctionExe
this.UserDefinedFunctionExecutionTime = userDefinedFunctionExecutionTimes;
}
- public TimeSpan QueryEngineExecutionTime { get; set; }
- public TimeSpan SystemFunctionExecutionTime { get; set; }
- public TimeSpan UserDefinedFunctionExecutionTime { get; set; }
+ public TimeSpan QueryEngineExecutionTime { get; }
+ public TimeSpan SystemFunctionExecutionTime { get; }
+ public TimeSpan UserDefinedFunctionExecutionTime { get; }
public Accumulator Accumulate(RuntimeExecutionTimes runtimeExecutionTimes)
{
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/BackendAccumulatedMetricsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/BackendAccumulatedMetricsTests.cs
new file mode 100644
index 0000000000..7b05c1fd71
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Metrics/BackendAccumulatedMetricsTests.cs
@@ -0,0 +1,13 @@
+namespace Microsoft.Azure.Cosmos.Tests.Query.Metrics
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using System.Threading.Tasks;
+
+ internal class BackendAccumulatedMetricsTests
+ {
+ //TODO
+ }
+}