-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[AzureMonitorLiveMetrics] POC (#40001)
* working POC * update public api
- Loading branch information
1 parent
663c0f4
commit dd563c7
Showing
14 changed files
with
708 additions
and
15 deletions.
There are no files selected for viewing
19 changes: 19 additions & 0 deletions
19
...r.OpenTelemetry.LiveMetrics/api/Azure.Monitor.OpenTelemetry.LiveMetrics.netstandard2.0.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
...Monitor.OpenTelemetry.LiveMetrics/src/Customizations/QuickPulseSDKClientAPIsRestClient.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
#nullable disable | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Text.Json; | ||
using System.Threading; | ||
using Azure.Core; | ||
using Azure.Monitor.OpenTelemetry.LiveMetrics.Models; | ||
|
||
namespace Azure.Monitor.OpenTelemetry.LiveMetrics | ||
{ | ||
internal partial class QuickPulseSDKClientAPIsRestClient | ||
{ | ||
/// <summary> SDK ping. </summary> | ||
/// <param name="ikey"> The ikey of the target Application Insights component that displays server info sent by /QuickPulseService.svc/ping. </param> | ||
/// <param name="apikey"> Deprecated. An alternative way to pass api key. Use AAD auth instead. </param> | ||
/// <param name="xMsQpsTransmissionTime"> Timestamp when SDK transmits the metrics and documents to QuickPulse. A 8-byte long type of ticks. </param> | ||
/// <param name="xMsQpsMachineName"> Computer name where AI SDK lives. QuickPulse uses machine name with instance name as a backup. </param> | ||
/// <param name="xMsQpsInstanceName"> Service instance name where AI SDK lives. QuickPulse uses machine name with instance name as a backup. </param> | ||
/// <param name="xMsQpsStreamId"> Identifies an AI SDK as trusted agent to report metrics and documents. </param> | ||
/// <param name="xMsQpsRoleName"> Cloud role name for which SDK reports metrics and documents. </param> | ||
/// <param name="xMsQpsInvariantVersion"> Version/generation of the data contract (MonitoringDataPoint) between SDK and QuickPulse. </param> | ||
/// <param name="xMsQpsConfigurationEtag"> An encoded string that indicates whether the collection configuration is changed. </param> | ||
/// <param name="monitoringDataPoint"> Data contract between SDK and QuickPulse. /QuickPulseService.svc/ping uses this as a backup source of machine name, instance name and invariant version. </param> | ||
/// <param name="cancellationToken"> The cancellation token to use. </param> | ||
/// <exception cref="ArgumentNullException"> <paramref name="ikey"/> is null. </exception> | ||
public ResponseWithHeaders<object, QuickPulseSDKClientAPIsPingHeaders> PingCustom(string ikey, string apikey = null, int? xMsQpsTransmissionTime = null, string xMsQpsMachineName = null, string xMsQpsInstanceName = null, string xMsQpsStreamId = null, string xMsQpsRoleName = null, string xMsQpsInvariantVersion = null, string xMsQpsConfigurationEtag = null, MonitoringDataPoint monitoringDataPoint = null, CancellationToken cancellationToken = default) | ||
{ | ||
if (ikey == null) | ||
{ | ||
throw new ArgumentNullException(nameof(ikey)); | ||
} | ||
|
||
using var message = CreatePingRequest(ikey, apikey, xMsQpsTransmissionTime, xMsQpsMachineName, xMsQpsInstanceName, xMsQpsStreamId, xMsQpsRoleName, xMsQpsInvariantVersion, xMsQpsConfigurationEtag, monitoringDataPoint); | ||
_pipeline.Send(message, cancellationToken); | ||
var headers = new QuickPulseSDKClientAPIsPingHeaders(message.Response); | ||
switch (message.Response.Status) | ||
{ | ||
case 200: | ||
{ | ||
CollectionConfigurationInfo value = default; | ||
if (message.Response.Headers.ContentLength != 0) | ||
{ | ||
using var document = JsonDocument.Parse(message.Response.ContentStream); | ||
value = CollectionConfigurationInfo.DeserializeCollectionConfigurationInfo(document.RootElement); | ||
} | ||
return ResponseWithHeaders.FromValue<object, QuickPulseSDKClientAPIsPingHeaders>(value, headers, message.Response); | ||
} | ||
case 400: | ||
case 401: | ||
case 403: | ||
case 404: | ||
case 500: | ||
case 503: | ||
{ | ||
ServiceError value = default; | ||
using var document = JsonDocument.Parse(message.Response.ContentStream); | ||
value = ServiceError.DeserializeServiceError(document.RootElement); | ||
return ResponseWithHeaders.FromValue<object, QuickPulseSDKClientAPIsPingHeaders>(value, headers, message.Response); | ||
} | ||
default: | ||
throw new RequestFailedException(message.Response); | ||
} | ||
} | ||
|
||
/// <summary> SDK post. </summary> | ||
/// <param name="ikey"> The ikey of the target Application Insights component that displays metrics and documents sent by /QuickPulseService.svc/post. </param> | ||
/// <param name="apikey"> An alternative way to pass api key. Deprecated. Use AAD authentication instead. </param> | ||
/// <param name="xMsQpsConfigurationEtag"> An encoded string that indicates whether the collection configuration is changed. </param> | ||
/// <param name="xMsQpsTransmissionTime"> Timestamp when SDK transmits the metrics and documents to QuickPulse. A 8-byte long type of ticks. </param> | ||
/// <param name="monitoringDataPoints"> Data contract between SDK and QuickPulse. /QuickPulseService.svc/post uses this to publish metrics and documents to the backend QuickPulse server. </param> | ||
/// <param name="cancellationToken"> The cancellation token to use. </param> | ||
/// <exception cref="ArgumentNullException"> <paramref name="ikey"/> is null. </exception> | ||
public ResponseWithHeaders<object, QuickPulseSDKClientAPIsPostHeaders> PostCustom(string ikey, string apikey = null, string xMsQpsConfigurationEtag = null, int? xMsQpsTransmissionTime = null, IEnumerable<MonitoringDataPoint> monitoringDataPoints = null, CancellationToken cancellationToken = default) | ||
{ | ||
if (ikey == null) | ||
{ | ||
throw new ArgumentNullException(nameof(ikey)); | ||
} | ||
|
||
using var message = CreatePostRequest(ikey, apikey, xMsQpsConfigurationEtag, xMsQpsTransmissionTime, monitoringDataPoints); | ||
_pipeline.Send(message, cancellationToken); | ||
var headers = new QuickPulseSDKClientAPIsPostHeaders(message.Response); | ||
switch (message.Response.Status) | ||
{ | ||
case 200: | ||
{ | ||
CollectionConfigurationInfo value = default; | ||
if (message.Response.Headers.ContentLength != 0) | ||
{ | ||
using var document = JsonDocument.Parse(message.Response.ContentStream); | ||
value = CollectionConfigurationInfo.DeserializeCollectionConfigurationInfo(document.RootElement); | ||
} | ||
return ResponseWithHeaders.FromValue<object, QuickPulseSDKClientAPIsPostHeaders>(value, headers, message.Response); | ||
} | ||
case 400: | ||
case 401: | ||
case 403: | ||
case 404: | ||
case 500: | ||
case 503: | ||
{ | ||
ServiceError value = default; | ||
using var document = JsonDocument.Parse(message.Response.ContentStream); | ||
value = ServiceError.DeserializeServiceError(document.RootElement); | ||
return ResponseWithHeaders.FromValue<object, QuickPulseSDKClientAPIsPostHeaders>(value, headers, message.Response); | ||
} | ||
default: | ||
throw new RequestFailedException(message.Response); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
sdk/monitor/Azure.Monitor.OpenTelemetry.LiveMetrics/src/Internals/Manager.Metrics.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics.Metrics; | ||
using System.Diagnostics; | ||
using OpenTelemetry; | ||
using OpenTelemetry.Metrics; | ||
using System.Collections.Concurrent; | ||
|
||
namespace Azure.Monitor.OpenTelemetry.LiveMetrics.Internals | ||
{ | ||
internal partial class Manager | ||
{ | ||
private Meter? _meter; | ||
private MeterProvider? _meterProvider; | ||
private BaseExportingMetricReader? _metricReader; | ||
private readonly ConcurrentQueue<List<Models.MetricPoint>> _queue = new(); | ||
|
||
private PerformanceCounter _performanceCounter_ProcessorTime = new PerformanceCounter(categoryName: "Processor", counterName: "% Processor Time", instanceName: "_Total"); | ||
private PerformanceCounter _performanceCounter_CommittedBytes = new PerformanceCounter(categoryName: "Memory", counterName: "Committed Bytes"); | ||
|
||
private Instrument? _myObservableGauge1; | ||
private Instrument? _myObservableGauge2; | ||
|
||
private void InitializeMetrics() | ||
{ | ||
var uniqueTestId = Guid.NewGuid(); | ||
|
||
//var meterName = $"meterName{uniqueTestId}"; | ||
var meterName = LiveMetricConstants.LiveMetricMeterName; | ||
_meter = new Meter(meterName, "1.0"); | ||
|
||
_myObservableGauge1 = _meter.CreateObservableGauge(LiveMetricConstants.MemoryCommittedBytesInstrumentName, () => | ||
{ | ||
return new Measurement<float>(value: _performanceCounter_CommittedBytes.NextValue()); | ||
}); | ||
|
||
_myObservableGauge2 = _meter.CreateObservableGauge(LiveMetricConstants.ProcessorTimeInstrumentName, () => | ||
{ | ||
return new Measurement<float>(value: _performanceCounter_ProcessorTime.NextValue()); | ||
}); | ||
|
||
_metricReader = new BaseExportingMetricReader(new LiveMetricsMetricExporter(_queue)); | ||
|
||
var meterProviderBuilder = Sdk.CreateMeterProviderBuilder() | ||
.AddMeter(meterName) | ||
.AddReader(_metricReader); | ||
|
||
_meterProvider = meterProviderBuilder.Build(); | ||
} | ||
|
||
private IEnumerable<Models.MetricPoint> CollectMetrics() | ||
{ | ||
_metricReader?.Collect(); | ||
|
||
if (_queue.TryDequeue(out var metricPoint)) | ||
{ | ||
return metricPoint; | ||
} | ||
else | ||
{ | ||
return Array.Empty<Models.MetricPoint>(); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.