Skip to content

Commit

Permalink
adding test
Browse files Browse the repository at this point in the history
  • Loading branch information
sourabh1007 committed Sep 20, 2024
1 parent 4380db5 commit 0782397
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 27 deletions.
2 changes: 1 addition & 1 deletion Microsoft.Azure.Cosmos/src/Handler/TelemetryHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public override async Task<ResponseMessage> SendAsync(
RequestCharge = response.Headers.RequestCharge,
SubStatusCode = response.Headers.SubStatusCode,
Trace = response.Trace,
MaxItemCount = Convert.ToString(new Random().Next(100)),
MaxItemCount = request.Headers.PageSize,
ActualItemCount = response.Headers.ItemCount,
PartitionKeyRangeId = request.Headers.PartitionKeyRangeId
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ internal class OpenTelemetryMetricsCollector : ITelemetryCollector
private readonly string clientId;
private readonly string accountName;

private static readonly ConcurrentBag<Tuple<int, KeyValuePair<string, object>[]>> maxItemCounts = new ();
private static ConcurrentBag<Tuple<int, KeyValuePair<string, object>[]>> maxItemCounts = null;
private static ConcurrentBag<Tuple<int, KeyValuePair<string, object>[]>> actualItemCounts = null;
private static ConcurrentBag<Tuple<int, KeyValuePair<string, object>[]>> regionsContactedCounts = null;

/// <summary>
/// Initializes a new instance of the OpenTelemetryMetricsCollector class.
Expand Down Expand Up @@ -48,7 +50,9 @@ public void CollectOperationAndNetworkInfo(Func<TelemetryInformation> getTelemet

KeyValuePair<string, object>[] dimensions = new[]
{
new KeyValuePair<string, object>("Container", $"{this.accountName}/{telemetryInformation.DatabaseId}/{telemetryInformation.ContainerId}"),
new KeyValuePair<string, object>("AccountName", this.accountName),
new KeyValuePair<string, object>("Container", telemetryInformation.ContainerId),
new KeyValuePair<string, object>("Database", telemetryInformation.DatabaseId),
new KeyValuePair<string, object>("Operation", telemetryInformation.OperationType),
new KeyValuePair<string, object>("OperationStatusCode", telemetryInformation.StatusCode),
new KeyValuePair<string, object>("ClientCorrelationId", this.clientId),
Expand All @@ -66,8 +70,18 @@ public void CollectOperationAndNetworkInfo(Func<TelemetryInformation> getTelemet
/// <param name="dimensions">Key-value pairs representing various metadata about the operation (e.g., container, operation type, consistency level).</param>
private static void PushOperationLevelMetrics(TelemetryInformation telemetryInformation, KeyValuePair<string, object>[] dimensions)
{
Console.WriteLine("Pushing maxItemCounts " + telemetryInformation.MaxItemCount);
maxItemCounts ??= new ConcurrentBag<Tuple<int, KeyValuePair<string, object>[]>>();
maxItemCounts.Add(new Tuple<int, KeyValuePair<string, object>[]>(Convert.ToInt32(telemetryInformation.MaxItemCount), dimensions));

Console.WriteLine("Pushing ActualItemCount " + telemetryInformation.ActualItemCount);
actualItemCounts ??= new ConcurrentBag<Tuple<int, KeyValuePair<string, object>[]>>();
actualItemCounts.Add(new Tuple<int, KeyValuePair<string, object>[]>(Convert.ToInt32(telemetryInformation.ActualItemCount), dimensions));

Console.WriteLine("Pushing telemetryInformation.RegionsContactedList.Count " + telemetryInformation.RegionsContactedList.Count);
regionsContactedCounts ??= new ConcurrentBag<Tuple<int, KeyValuePair<string, object>[]>>();
regionsContactedCounts.Add(new Tuple<int, KeyValuePair<string, object>[]>(telemetryInformation.RegionsContactedList.Count, dimensions));

OpenTelemetryMetrics.RequestUnitsHistogram.Record(telemetryInformation.RequestCharge, dimensions);
OpenTelemetryMetrics.RequestLatencyHistogram.Record(telemetryInformation.RequestLatency.Value.Milliseconds, dimensions);
OpenTelemetryMetrics.NumberOfOperationCallCounter.Add(1, dimensions);
Expand All @@ -77,9 +91,27 @@ public static IEnumerable<Measurement<int>> GetMaxItemCount()
{
foreach (Tuple<int, KeyValuePair<string, object>[]> maxItemCount in maxItemCounts)
{
Console.WriteLine("Pulling maxItemCounts " + maxItemCount.Item1);
yield return new Measurement<int>(maxItemCount.Item1, maxItemCount.Item2);
}
}
}

public static IEnumerable<Measurement<int>> GetActualItemCount()
{
foreach (Tuple<int, KeyValuePair<string, object>[]> actualItemCount in actualItemCounts)
{
Console.WriteLine("Pulling actualItemCount " + actualItemCount.Item1);
yield return new Measurement<int>(actualItemCount.Item1, actualItemCount.Item2);
}
}

public static IEnumerable<Measurement<int>> GetRegionContactedCount()
{
foreach (Tuple<int, KeyValuePair<string, object>[]> regionContactedCount in regionsContactedCounts)
{
Console.WriteLine("Pulling regionContactedCount " + regionContactedCount.Item1);
yield return new Measurement<int>(regionContactedCount.Item1, regionContactedCount.Item2);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,21 @@ internal static class OpenTelemetryMetrics

internal static readonly ObservableGauge<int> maxItemGauge =
CosmosMeter.CreateObservableGauge<int>(name: "cosmos.client.op.maxItemCount",
observeValue: () => OpenTelemetryMetricsCollector.GetMaxItemCount(),
observeValues: () => OpenTelemetryMetricsCollector.GetMaxItemCount(),
unit: "#",
description: "For feed operations (query, readAll, readMany, change feed) and batch operations this meter capture the requested maxItemCount per page/request");

/*internal static readonly ObservableGauge<int> ActualItemCounter =
CosmosMeter.CreateObservableGauge<int>(name: "cosmos.client.op.actualItemCount",
internal static readonly ObservableGauge<int> ActualItemCounter =
CosmosMeter.CreateObservableGauge<int>(name: "cosmos.client.op.actualItemCount",
observeValues: () => OpenTelemetryMetricsCollector.GetActualItemCount(),
unit: "#",
description: "For feed operations (query, readAll, readMany, change feed) batch operations this meter capture the actual item count in responses from the service");

internal static readonly ObservableGauge<int> RegionsContactedCounter =
CosmosMeter.CreateObservableGauge<int>(name: "cosmos.client.op.regionsContacted",
unit: "#",
description: "Number of regions contacted when executing an operation");*/
CosmosMeter.CreateObservableGauge<int>(name: "cosmos.client.op.regionsContacted",
observeValues: () => OpenTelemetryMetricsCollector.GetRegionContactedCount(),
unit: "# regions",
description: "Number of regions contacted when executing an operation");

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------

namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests.Metrics
{
using OpenTelemetry.Metrics;
using OpenTelemetry;
using System;

public class CustomMetricExporter : BaseExporter<Metric>
{
// This method will be called periodically by OpenTelemetry SDK
public override ExportResult Export(in Batch<Metric> batch)
{
Console.WriteLine("\n[Custom Exporter] Exporting metrics:");

int gaugeCount = 0;
foreach (var metric in batch)
{
Console.WriteLine($"Metric: {metric.Name}, Type: {metric.MetricType}");

foreach (var metricPoint in metric.GetMetricPoints())
{
switch (metric.MetricType)
{
case MetricType.LongSum:
Console.WriteLine($"Value (Counter): {metricPoint.GetSumLong()}");
break;
case MetricType.LongGauge:
Console.WriteLine($"Value (Gauge): {metricPoint.GetGaugeLastValueLong()}");
gaugeCount++;
break;
case MetricType.Histogram:
Console.WriteLine($"Value (Histogram): {metricPoint.GetHistogramCount()}");

foreach (HistogramBucket bucket in metricPoint.GetHistogramBuckets())
{
Console.WriteLine($"{bucket.ExplicitBound} : {bucket.BucketCount}");
}
break;
}
}

}

Console.WriteLine($"Total gauge values exported: {gaugeCount}");
Console.WriteLine();

return ExportResult.Success;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,11 @@
namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests.Metrics
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos.Fluent;
using Microsoft.Azure.Documents;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Moq.Protected;
using OpenTelemetry.Metrics;
using OpenTelemetry;
using System.Diagnostics;
Expand Down Expand Up @@ -61,13 +54,11 @@ public async Task Cleanup()
[TestMethod]
public async Task OperationLevelMetrics()
{
//var histogramBuckets = new double[] { 0, 5, 10, 25, 50, 75, 100, 250, 500 };
MeterProvider meterProvider = Sdk
.CreateMeterProviderBuilder()
.AddMeter("*")/*
.AddView("cosmos.client.op.RUs", new ExplicitBucketHistogramConfiguration { Boundaries = histogramBuckets })*/
.AddConsoleExporter()
.Build();
.CreateMeterProviderBuilder()
.AddMeter("*")
.AddReader(new PeriodicExportingMetricReader(new CustomMetricExporter(), exportIntervalMilliseconds: 3000))
.Build();

int httpCallsMade = 0;
HttpClientHandlerHelper httpClientHandlerHelper = new HttpClientHandlerHelper
Expand Down Expand Up @@ -98,8 +89,6 @@ public async Task OperationLevelMetrics()

ContainerInternal container = (ContainerInternal)cosmosClient.GetContainer(this.database.Id, "ClientCreateAndInitializeContainer");

await Task.Delay(1000);

Stopwatch sw = Stopwatch.StartNew();
sw.Start();
while(true)
Expand All @@ -112,8 +101,6 @@ public async Task OperationLevelMetrics()
}
}
sw.Stop();

await Task.Delay(1000);

cosmosClient.Dispose();

Expand Down

0 comments on commit 0782397

Please sign in to comment.