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

Client Telemetry And Diagnostics : Adds VMId or Unique Id in payload #3100

Merged
merged 29 commits into from
Apr 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
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
4 changes: 4 additions & 0 deletions Microsoft.Azure.Cosmos/src/DocumentClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace Microsoft.Azure.Cosmos
using Microsoft.Azure.Cosmos.Query;
using Microsoft.Azure.Cosmos.Query.Core.QueryPlan;
using Microsoft.Azure.Cosmos.Routing;
using Microsoft.Azure.Cosmos.Telemetry;
using Microsoft.Azure.Cosmos.Tracing;
using Microsoft.Azure.Cosmos.Tracing.TraceData;
using Microsoft.Azure.Documents;
Expand Down Expand Up @@ -897,6 +898,9 @@ internal virtual void Initialize(Uri serviceEndpoint,
this.sendingRequest,
this.receivedResponse);

// Loading VM Information (non blocking call and initialization won't fail if this call fails)
VmMetadataApiHandler.TryInitialize(this.httpClient);

if (sessionContainer != null)
{
this.sessionContainer = sessionContainer;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace Microsoft.Azure.Cosmos
{
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;

internal sealed class HttpTimeoutPolicyNoRetry : HttpTimeoutPolicy
sourabh1007 marked this conversation as resolved.
Show resolved Hide resolved
{
public static readonly HttpTimeoutPolicy Instance = new HttpTimeoutPolicyNoRetry();
private static readonly string Name = nameof(HttpTimeoutPolicyNoRetry);

private HttpTimeoutPolicyNoRetry()
{
}

private readonly IReadOnlyList<(TimeSpan requestTimeout, TimeSpan delayForNextRequest)> TimeoutsAndDelays = new List<(TimeSpan requestTimeout, TimeSpan delayForNextRequest)>();

public override string TimeoutPolicyName => HttpTimeoutPolicyNoRetry.Name;

public override TimeSpan MaximumRetryTimeLimit => TimeSpan.Zero;

public override int TotalRetryCount => 0;

public override IEnumerator<(TimeSpan requestTimeout, TimeSpan delayForNextRequest)> GetTimeoutEnumerator()
{
return this.TimeoutsAndDelays.GetEnumerator();
}

// Always Unsafe to retry
public override bool IsSafeToRetry(HttpMethod httpMethod)
{
return false;
}

public override bool ShouldRetryBasedOnResponse(HttpMethod requestHttpMethod, HttpResponseMessage responseMessage)
{
return false;
}
}
}
14 changes: 7 additions & 7 deletions Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ internal class ClientTelemetry : IDisposable
private static readonly TimeSpan observingWindow = ClientTelemetryOptions.GetScheduledTimeSpan();

private readonly ClientTelemetryProperties clientTelemetryInfo;

private readonly DocumentClient documentClient;
private readonly CosmosHttpClient httpClient;
private readonly AuthorizationTokenProvider tokenProvider;
Expand Down Expand Up @@ -135,17 +134,18 @@ private async Task EnrichAndSendAsync()
this.clientTelemetryInfo.GlobalDatabaseAccountName = accountProperties?.Id;
}

// Load host information if not available (it caches the information)
AzureVMMetadata azMetadata = await ClientTelemetryHelper.LoadAzureVmMetaDataAsync(this.httpClient);

Compute vmInformation = azMetadata?.Compute;
// Load host information from cache
Compute vmInformation = VmMetadataApiHandler.GetMachineInfo();
if (vmInformation != null)
{
this.clientTelemetryInfo.ApplicationRegion = vmInformation.Location;
this.clientTelemetryInfo.HostEnvInfo = ClientTelemetryOptions.GetHostInformation(vmInformation);

//TODO: Set AcceleratingNetwork flag from instance metadata once it is available.
}

this.clientTelemetryInfo.MachineId = VmMetadataApiHandler.GetMachineId();

await Task.Delay(observingWindow, this.cancellationTokenSource.Token);

// If cancellation is requested after the delay then return from here.
Expand Down Expand Up @@ -329,7 +329,7 @@ await this.tokenProvider.AddAuthorizationHeaderAsync(

using HttpResponseMessage response = await this.httpClient.SendHttpAsync(CreateRequestMessage,
ResourceType.Telemetry,
HttpTimeoutPolicyDefault.Instance,
HttpTimeoutPolicyNoRetry.Instance,
sourabh1007 marked this conversation as resolved.
Show resolved Hide resolved
null,
this.cancellationTokenSource.Token);

Expand Down Expand Up @@ -369,7 +369,7 @@ public void Dispose()
{
this.cancellationTokenSource.Cancel();
this.cancellationTokenSource.Dispose();

this.telemetryTask = null;
}
}
Expand Down
51 changes: 2 additions & 49 deletions Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ namespace Microsoft.Azure.Cosmos.Telemetry

internal static class ClientTelemetryHelper
{
internal static AzureVMMetadata azMetadata = null;

private static readonly Uri vmMetadataEndpointUrl = ClientTelemetryOptions.GetVmMetadataUrl();

/// <summary>
/// Task to get Account Properties from cache if available otherwise make a network call.
/// </summary>
Expand All @@ -42,50 +38,6 @@ internal static async Task<AccountProperties> SetAccountNameAsync(DocumentClient
return null;
}

/// <summary>
/// Task to collect virtual machine metadata information. using instance metedata service API.
/// ref: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=windows
/// Collects only application region and environment information
/// </summary>
/// <returns>Async Task</returns>
internal static async Task<AzureVMMetadata> LoadAzureVmMetaDataAsync(CosmosHttpClient httpClient)
{
if (azMetadata == null)
{
DefaultTrace.TraceVerbose("Getting VM Metadata Information for Telemetry.");
try
{
static ValueTask<HttpRequestMessage> CreateRequestMessage()
{
HttpRequestMessage request = new HttpRequestMessage()
{
RequestUri = vmMetadataEndpointUrl,
Method = HttpMethod.Get,
};
request.Headers.Add("Metadata", "true");

return new ValueTask<HttpRequestMessage>(request);
}

using HttpResponseMessage httpResponseMessage = await httpClient
.SendHttpAsync(createRequestMessageAsync: CreateRequestMessage,
resourceType: ResourceType.Telemetry,
timeoutPolicy: HttpTimeoutPolicyDefault.Instance,
clientSideRequestStatistics: null,
cancellationToken: new CancellationToken()); // Do not want to cancel the whole process if this call fails

azMetadata = await ClientTelemetryOptions.ProcessResponseAsync(httpResponseMessage);

}
catch (Exception ex)
{
DefaultTrace.TraceError("Exception in LoadAzureVmMetaDataAsync() {0}", ex.Message);
}
}

return azMetadata;
}

/// <summary>
/// Record System Usage and update passed system Info collection. Right now, it collects following metrics
/// 1) CPU Usage
Expand Down Expand Up @@ -118,7 +70,7 @@ internal static void RecordSystemUsage(
{
systemInfoCollection.Add(TelemetrySystemUsage.GetTcpConnectionCount(systemUsageHistory.Values));
}

}

/// <summary>
Expand Down Expand Up @@ -186,5 +138,6 @@ internal static string GetContactedRegions(CosmosDiagnostics cosmosDiagnostics)

return regionsContacted.ToString();
}

}
}
31 changes: 0 additions & 31 deletions Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetryOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@
namespace Microsoft.Azure.Cosmos.Telemetry
{
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos.Core.Trace;
using Microsoft.Azure.Documents;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

internal static class ClientTelemetryOptions
{
Expand Down Expand Up @@ -73,7 +70,6 @@ internal static class ClientTelemetryOptions
internal const string IsThreadStarvingName = "SystemPool_IsThreadStarving_True";
internal const string IsThreadStarvingUnit = "Count";

internal const string DefaultVmMetadataUrL = "http://169.254.169.254/metadata/instance?api-version=2020-06-01";
internal const double DefaultTimeStampInSeconds = 600;
internal const double Percentile50 = 50.0;
internal const double Percentile90 = 90.0;
Expand All @@ -92,7 +88,6 @@ internal static class ClientTelemetryOptions

internal static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };

private static Uri vmMetadataUrl;
private static Uri clientTelemetryEndpoint;
private static string environmentName;
private static TimeSpan scheduledTimeSpan = TimeSpan.Zero;
Expand All @@ -108,22 +103,6 @@ internal static bool IsClientTelemetryEnabled()
return isTelemetryEnabled;
}

internal static Uri GetVmMetadataUrl()
{
if (vmMetadataUrl == null)
{
string vmMetadataUrlProp = ConfigurationManager.GetEnvironmentVariable<string>(
EnvPropsClientTelemetryVmMetadataUrl, DefaultVmMetadataUrL);
if (!String.IsNullOrEmpty(vmMetadataUrlProp))
{
vmMetadataUrl = new Uri(vmMetadataUrlProp);
}

DefaultTrace.TraceInformation($"VM metadata URL for telemetry {vmMetadataUrlProp}");
}
return vmMetadataUrl;
}

internal static TimeSpan GetScheduledTimeSpan()
{
if (scheduledTimeSpan.Equals(TimeSpan.Zero))
Expand Down Expand Up @@ -154,16 +133,6 @@ internal static TimeSpan GetScheduledTimeSpan()
return scheduledTimeSpan;
}

internal static async Task<AzureVMMetadata> ProcessResponseAsync(HttpResponseMessage httpResponseMessage)
{
if (httpResponseMessage.Content == null)
{
return null;
}
string jsonVmInfo = await httpResponseMessage.Content.ReadAsStringAsync();
return JObject.Parse(jsonVmInfo).ToObject<AzureVMMetadata>();
}

internal static string GetHostInformation(Compute vmInformation)
{
return String.Concat(vmInformation?.OSType, "|",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ internal sealed class ClientTelemetryProperties
[JsonProperty(PropertyName = "clientId")]
internal string ClientId { get; }

[JsonProperty(PropertyName = "machineId")]
internal string MachineId { get; set; }

[JsonProperty(PropertyName = "processId")]
internal string ProcessId { get; }

Expand Down Expand Up @@ -97,7 +100,8 @@ public ClientTelemetryProperties(string dateTimeUtc,
IReadOnlyList<string> preferredRegions,
List<SystemInfo> systemInfo,
List<OperationInfo> cacheRefreshInfo,
List<OperationInfo> operationInfo)
List<OperationInfo> operationInfo,
string machineId)
{
this.DateTimeUtc = dateTimeUtc;
this.ClientId = clientId;
Expand All @@ -112,6 +116,7 @@ public ClientTelemetryProperties(string dateTimeUtc,
this.CacheRefreshInfo = cacheRefreshInfo;
this.OperationInfo = operationInfo;
this.PreferredRegions = preferredRegions;
this.MachineId = machineId;
}
}
}
13 changes: 12 additions & 1 deletion Microsoft.Azure.Cosmos/src/Telemetry/Compute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,21 @@ namespace Microsoft.Azure.Cosmos.Telemetry
[Serializable]
internal sealed class Compute
{
public Compute(string location, string sKU, string azEnvironment, string oSType, string vMSize)
[JsonConstructor]
public Compute(
string vMId,
string location,
string sKU,
string azEnvironment,
string oSType,
string vMSize)
{
this.Location = location;
this.SKU = sKU;
this.AzEnvironment = azEnvironment;
this.OSType = oSType;
this.VMSize = vMSize;
this.VMId = "vmId:" + vMId;
}

[JsonProperty(PropertyName = "location")]
Expand All @@ -33,6 +41,9 @@ public Compute(string location, string sKU, string azEnvironment, string oSType,

[JsonProperty(PropertyName = "vmSize")]
internal string VMSize { get; }

[JsonProperty(PropertyName = "vmId")]
internal string VMId { get; }
}

}
Loading