Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding basic request diagnostics for V3 #615

Merged
merged 26 commits into from
Aug 30, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e7c3424
inital commit
simplynaveen20 Jul 31, 2019
0a0f200
making cosmosDiagnostic public
simplynaveen20 Jul 31, 2019
1b75148
bumping direct version
simplynaveen20 Jul 31, 2019
431de60
Merge branch 'master' into users/nakumar/requestDiagnosticsV3
simplynaveen20 Aug 1, 2019
1478d41
removing formatting of json
simplynaveen20 Aug 1, 2019
464eccf
merging with master
simplynaveen20 Aug 16, 2019
94bf545
removing extra line
simplynaveen20 Aug 16, 2019
34774d3
Merge branch 'master' into users/nakumar/requestDiagnosticsV3
simplynaveen20 Aug 19, 2019
0367e03
updating per new changes with clientsiderequestdiagnostics
simplynaveen20 Aug 19, 2019
bd317ad
Merge branch 'master' into users/nakumar/requestDiagnosticsV3
simplynaveen20 Aug 21, 2019
567521a
using to string on CLientSideRequestDiagnostics
simplynaveen20 Aug 21, 2019
06613ae
updating DOtNetSDKAPI
simplynaveen20 Aug 21, 2019
feaef5e
updating DotNetSDKAPI.json
simplynaveen20 Aug 21, 2019
179281f
moving cosmosDiagnostic as abstract clas
simplynaveen20 Aug 21, 2019
4d82e31
adding abstract tostring
simplynaveen20 Aug 22, 2019
8fb181c
updating change log
simplynaveen20 Aug 22, 2019
baace6c
removing query metrics from header
simplynaveen20 Aug 22, 2019
af0b757
removing populateQueryOption flag from request option
simplynaveen20 Aug 26, 2019
04855e7
merging with master
simplynaveen20 Aug 27, 2019
9ce1424
updating contract
simplynaveen20 Aug 27, 2019
250d43e
Merge branch 'master' into users/nakumar/requestDiagnosticsV3
simplynaveen20 Aug 27, 2019
f84aa5e
Merge branch 'master' into users/nakumar/requestDiagnosticsV3
j82w Aug 29, 2019
00dd4c3
upgrading direct to 3.1.6 to leverage IClientSideRequestDiagnostics
simplynaveen20 Aug 29, 2019
ac5b28f
Merge branch 'master' into users/nakumar/requestDiagnosticsV3
simplynaveen20 Aug 30, 2019
cd411e1
changing name of cosmosDiagnostics to diagnostics
simplynaveen20 Aug 30, 2019
9a42e92
moving diagnostics to Diagnostics
simplynaveen20 Aug 30, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
upgrading direct to 3.1.6 to leverage IClientSideRequestDiagnostics
  • Loading branch information
simplynaveen20 committed Aug 29, 2019
commit 00dd4c30d14706b805b1b7e017af762dab1150dc
4 changes: 2 additions & 2 deletions Microsoft.Azure.Cosmos/src/ClientRetryPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal sealed class ClientRetryPolicy : IDocumentClientRetryPolicy
private Uri locationEndpoint;
private RetryContext retryContext;

private ClientSideRequestStatistics sharedStatistics;
private IClientSideRequestStatistics sharedStatistics;

public ClientRetryPolicy(
GlobalEndpointManager globalEndpointManager,
Expand All @@ -50,7 +50,7 @@ public ClientRetryPolicy(
this.sessionTokenRetryCount = 0;
this.canUseMultipleWriteLocations = false;

this.sharedStatistics = new ClientSideRequestStatistics();
this.sharedStatistics = new CosmosClientSideRequestStatistics();
}

/// <summary>
Expand Down
6 changes: 3 additions & 3 deletions Microsoft.Azure.Cosmos/src/DocumentFeedResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ internal DocumentFeedResponse(
INameValueCollection responseHeaders,
bool useETagAsContinuation = false,
IReadOnlyDictionary<string, QueryMetrics> queryMetrics = null,
ClientSideRequestStatistics requestStats = null,
IClientSideRequestStatistics requestStats = null,
string disallowContinuationTokenMessage = null,
long responseLengthBytes = 0)
: this(result)
Expand All @@ -79,7 +79,7 @@ internal DocumentFeedResponse(
IEnumerable<T> result,
int count,
INameValueCollection responseHeaders,
ClientSideRequestStatistics requestStats,
IClientSideRequestStatistics requestStats,
long responseLengthBytes)
: this(result, count, responseHeaders, false, null, requestStats, responseLengthBytes: responseLengthBytes)
{
Expand All @@ -91,7 +91,7 @@ internal DocumentFeedResponse(
/// <remarks>
/// This value is currently used for tracking replica Uris.
/// </remarks>
internal ClientSideRequestStatistics RequestStatistics { get; private set; }
internal IClientSideRequestStatistics RequestStatistics { get; private set; }

/// <summary>
/// Gets the response length in bytes
Expand Down
2 changes: 1 addition & 1 deletion Microsoft.Azure.Cosmos/src/Microsoft.Azure.Cosmos.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<NeutralLanguage>en-US</NeutralLanguage>
<ClientVersion>3.1.1</ClientVersion>
<DirectVersion>3.1.5</DirectVersion>
<DirectVersion>3.1.6</DirectVersion>
<HybridRowVersion>1.0.0-preview</HybridRowVersion>
<DirectPackageName Condition=" '$(SignAssembly)' == 'true' ">Microsoft.Azure.Cosmos.Direct</DirectPackageName>
<DirectPackageName Condition=" '$(SignAssembly)' != 'true' ">Microsoft.Azure.Cosmos.Direct.MyGet</DirectPackageName>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------

namespace Microsoft.Azure.Cosmos
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using Microsoft.Azure.Documents;
using Newtonsoft.Json;

internal sealed class CosmosClientSideRequestStatistics : IClientSideRequestStatistics
{
internal const int MaxSupplementalRequestsForToString = 10;

internal DateTime requestStartTime;
internal DateTime requestEndTime;

private object lockObject = new object();

internal List<StoreResponseStatistics> responseStatisticsList;
internal List<StoreResponseStatistics> supplementalResponseStatisticsList;
internal Dictionary<string, AddressResolutionStatistics> addressResolutionStatistics;

[JsonIgnoreAttribute]
public List<Uri> ContactedReplicas { get; set; }
[JsonIgnoreAttribute]
public HashSet<Uri> FailedReplicas { get; private set; }
[JsonIgnoreAttribute]
public HashSet<Uri> RegionsContacted { get; private set; }

public CosmosClientSideRequestStatistics()
{
this.requestStartTime = DateTime.UtcNow;
this.requestEndTime = DateTime.UtcNow;
this.responseStatisticsList = new List<StoreResponseStatistics>();
this.supplementalResponseStatisticsList = new List<StoreResponseStatistics>();
this.addressResolutionStatistics = new Dictionary<string, AddressResolutionStatistics>();
this.ContactedReplicas = new List<Uri>();
this.FailedReplicas = new HashSet<Uri>();
this.RegionsContacted = new HashSet<Uri>();
}

public TimeSpan RequestLatency
{
get
{
return this.requestEndTime - this.requestStartTime;
}
}

public bool IsCpuOverloaded
{
get
{
foreach (StoreResponseStatistics responseStatistics in this.responseStatisticsList)
{
if (responseStatistics.StoreResult.IsClientCpuOverloaded)
{
return true;
}
}
foreach (StoreResponseStatistics responseStatistics in this.supplementalResponseStatisticsList)
{
if (responseStatistics.StoreResult.IsClientCpuOverloaded)
{
return true;
}
}
return false;
}
}

public void RecordResponse(DocumentServiceRequest request, StoreResult storeResult)
{
DateTime responseTime = DateTime.UtcNow;

StoreResponseStatistics responseStatistics;
responseStatistics.RequestResponseTime = responseTime;
responseStatistics.StoreResult = storeResult;
responseStatistics.RequestOperationType = request.OperationType;
responseStatistics.RequestResourceType = request.ResourceType;

Uri locationEndpoint = request.RequestContext.LocationEndpointToRoute;

lock (this.lockObject)
{
if (responseTime > this.requestEndTime)
{
this.requestEndTime = responseTime;
}

if (locationEndpoint != null)
{
this.RegionsContacted.Add(locationEndpoint);
}

if (responseStatistics.RequestOperationType == OperationType.Head || responseStatistics.RequestOperationType == OperationType.HeadFeed)
{
this.supplementalResponseStatisticsList.Add(responseStatistics);
}
else
{
this.responseStatisticsList.Add(responseStatistics);
}
}
}

public string RecordAddressResolutionStart(Uri targetEndpoint)
{
string identifier = Guid.NewGuid().ToString();
AddressResolutionStatistics resolutionStats = new AddressResolutionStatistics
{
StartTime = DateTime.UtcNow,
EndTime = DateTime.MaxValue,
TargetEndpoint = targetEndpoint == null ? "<NULL>" : targetEndpoint.ToString()
};

lock (this.lockObject)
{
this.addressResolutionStatistics.Add(identifier, resolutionStats);
}

return identifier;
}

public void RecordAddressResolutionEnd(string identifier)
{
if (string.IsNullOrEmpty(identifier))
{
return;
}

DateTime responseTime = DateTime.UtcNow;
lock (this.lockObject)
{
if (!this.addressResolutionStatistics.ContainsKey(identifier))
{
throw new ArgumentException("Identifier {0} does not exist. Please call start before calling end.", identifier);
}

if (responseTime > this.requestEndTime)
{
this.requestEndTime = responseTime;
}

this.addressResolutionStatistics[identifier].EndTime = responseTime;
}
}

internal struct StoreResponseStatistics
{
public DateTime RequestResponseTime;
public StoreResult StoreResult;
public ResourceType RequestResourceType;
public OperationType RequestOperationType;

public override string ToString()
{
return String.Format(CultureInfo.InvariantCulture, "ResponseTime: {0}, StoreResult: {1}, ResourceType: {2}, OperationType: {3}",
this.RequestResponseTime.ToString("o", System.Globalization.CultureInfo.InvariantCulture),
this.StoreResult != null ? this.StoreResult.ToString() : string.Empty,
this.RequestResourceType, this.RequestOperationType);
}
}

internal class AddressResolutionStatistics
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string TargetEndpoint { get; set; }

public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "AddressResolution - StartTime: {0}, EndTime: {1}, TargetEndpoint: {2}",
this.StartTime.ToString("o", System.Globalization.CultureInfo.InvariantCulture),
this.EndTime.ToString("o", System.Globalization.CultureInfo.InvariantCulture),
this.TargetEndpoint);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,56 @@

namespace Microsoft.Azure.Cosmos
{
using Microsoft.Azure.Documents;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using static Microsoft.Azure.Cosmos.CosmosClientSideRequestStatistics;

internal sealed class PointOperationStatistics : CosmosDiagnostics
internal class PointOperationStatistics : CosmosDiagnostics
{
private ClientSideRequestStatistics clientSideRequestStatistics;
public DateTime requestStartTime { get; private set; }

public PointOperationStatistics(ClientSideRequestStatistics clientSideRequestStatistics)
public DateTime requestEndTime { get; private set; }

public List<StoreResponseStatistics> responseStatisticsList { get; private set; }

public List<StoreResponseStatistics> supplementalResponseStatisticsList { get; private set; }

public Dictionary<string, AddressResolutionStatistics> addressResolutionStatistics { get; private set; }

internal List<Uri> contactedReplicas { get; set; }

internal HashSet<Uri> failedReplicas { get; private set; }
simplynaveen20 marked this conversation as resolved.
Show resolved Hide resolved

public HashSet<Uri> regionsContacted { get; private set; }

public TimeSpan requestLatency { get; private set; }

public PointOperationStatistics(CosmosClientSideRequestStatistics clientSideRequestStatistics)
{
this.clientSideRequestStatistics = clientSideRequestStatistics;
this.requestStartTime = clientSideRequestStatistics.requestStartTime;
this.requestEndTime = clientSideRequestStatistics.requestEndTime;
this.responseStatisticsList = clientSideRequestStatistics.responseStatisticsList;
this.supplementalResponseStatisticsList = clientSideRequestStatistics.supplementalResponseStatisticsList;
this.addressResolutionStatistics = clientSideRequestStatistics.addressResolutionStatistics;
this.contactedReplicas = clientSideRequestStatistics.ContactedReplicas;
this.failedReplicas = clientSideRequestStatistics.FailedReplicas;
this.regionsContacted = clientSideRequestStatistics.RegionsContacted;
this.requestLatency = clientSideRequestStatistics.RequestLatency;
}

public override string ToString()
{
return this.clientSideRequestStatistics.ToString();
if (this.supplementalResponseStatisticsList != null)
{
int supplementalResponseStatisticsListCount = this.supplementalResponseStatisticsList.Count;
int countToRemove = Math.Max(supplementalResponseStatisticsListCount - CosmosClientSideRequestStatistics.MaxSupplementalRequestsForToString, 0);
if (countToRemove > 0)
{
this.supplementalResponseStatisticsList.RemoveRange(0, countToRemove);
}
}
return JsonConvert.SerializeObject(this);
}
}
}
2 changes: 1 addition & 1 deletion Microsoft.Azure.Cosmos/src/StoredProcedureResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public TValue Response
/// Gets the clientside request statics for execution of stored procedure.
/// </summary>
/// <value>The clientside request statics for execution of stored procedure.</value>
internal ClientSideRequestStatistics RequestStatistics
internal IClientSideRequestStatistics RequestStatistics
{
get
{
Expand Down
6 changes: 5 additions & 1 deletion Microsoft.Azure.Cosmos/src/Util/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ internal static ResponseMessage ToCosmosResponseMessage(this DocumentServiceResp

if (response.RequestStats != null)
{
cosmosResponse.cosmosDiagnostics = new PointOperationStatistics(response.RequestStats);
CosmosClientSideRequestStatistics cosmosClientSideRequestStatistics = response.RequestStats as CosmosClientSideRequestStatistics;
if (cosmosClientSideRequestStatistics != null)
{
cosmosResponse.cosmosDiagnostics = new PointOperationStatistics(cosmosClientSideRequestStatistics);
}
}

return cosmosResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RootNamespace>Microsoft.Azure.Cosmos</RootNamespace>
<AssemblyName>Microsoft.Azure.Cosmos.EmulatorTests</AssemblyName>
<DirectVersion>3.1.5</DirectVersion>
<DirectVersion>3.1.6</DirectVersion>
<HybridRowVersion>1.0.0-preview</HybridRowVersion>
<DirectPackageName Condition=" '$(SignAssembly)' == 'true' ">Microsoft.Azure.Cosmos.Direct</DirectPackageName>
<DirectPackageName Condition=" '$(SignAssembly)' != 'true' ">Microsoft.Azure.Cosmos.Direct.MyGet</DirectPackageName>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<IsPackable>false</IsPackable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RootNamespace>Microsoft.Azure.Cosmos</RootNamespace>
<DirectVersion>3.1.4</DirectVersion>
<DirectVersion>3.1.6</DirectVersion>
<HybridRowVersion>1.0.0-preview</HybridRowVersion>
<DirectPackageName Condition=" '$(SignAssembly)' == 'true' ">Microsoft.Azure.Cosmos.Direct</DirectPackageName>
<DirectPackageName Condition=" '$(SignAssembly)' != 'true' ">Microsoft.Azure.Cosmos.Direct.MyGet</DirectPackageName>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<IsPackable>false</IsPackable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RootNamespace>Microsoft.Azure.Cosmos</RootNamespace>
<DirectVersion>3.1.5</DirectVersion>
<DirectVersion>3.1.6</DirectVersion>
<HybridRowVersion>1.0.0-preview</HybridRowVersion>
<DirectPackageName Condition=" '$(SignAssembly)' == 'true' ">Microsoft.Azure.Cosmos.Direct</DirectPackageName>
<DirectPackageName Condition=" '$(SignAssembly)' != 'true' ">Microsoft.Azure.Cosmos.Direct.MyGet</DirectPackageName>
Expand Down
Loading