Reputation: 6883
I'm using external service, based on REST calls, and I want to track the time that took the service to respond to my requests. My code is written with C# (core v2.2)
I planning to count times for all the HTTP requests (with Stopwatch
) and keep this information in a List<long>
. Every 60 seconds I will write the tracked information from the list to Google Custom Metrics.
In the end, I expect to see the AVERAGE
time of execution in a graph.
This is my code so far:
public class CustomMetricsWritter
{
public CustomMetricsWritter(string projectId)
{
this.Client = MetricServiceClient.Create();
this.ProjectId = projectId;
}
private MetricServiceClient Client { get; set; }
public string ProjectId { get; private set; }
public object CreateMetric(string metricType, string title, string description, string unit)
{
// Prepare custom metric descriptor.
MetricDescriptor metricDescriptor = new MetricDescriptor();
metricDescriptor.DisplayName = title;
metricDescriptor.Description = description;
metricDescriptor.MetricKind = MetricKind.Gauge;
metricDescriptor.ValueType = MetricDescriptor.Types.ValueType.Double;
metricDescriptor.Type = metricType;
metricDescriptor.Unit = unit;
CreateMetricDescriptorRequest request = new CreateMetricDescriptorRequest
{
ProjectName = new ProjectName(this.ProjectId),
};
request.MetricDescriptor = metricDescriptor;
// Make the request.
return Client.CreateMetricDescriptor(request);
}
public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public async Task WriteTimeSeriesDataAsync(string metricDescriptor, TypedValue[] points, string machineName)
{
// Initialize request argument(s).
ProjectName name = new ProjectName(this.ProjectId);
// Prepare a data point.
Timestamp timeStamp = new Timestamp();
timeStamp.Seconds = (long)(DateTime.UtcNow - UnixEpoch).TotalSeconds;
TimeInterval interval = new TimeInterval();
interval.EndTime = timeStamp;
// Prepare monitored resource.
MonitoredResource resource = new MonitoredResource();
resource.Type = "global";
resource.Labels.Add("project_id", this.ProjectId);
// Add newly created time series to list of time series to be written.
List<TimeSeries> timeSeries = new List<TimeSeries>(points.Length);
// Prepare custom metric.
Metric metric = new Metric();
metric.Type = metricDescriptor;
metric.Labels.Add("machine", machineName);
// Create a new time series using inputs.
TimeSeries timeSeriesData = new TimeSeries();
timeSeriesData.Metric = metric;
timeSeriesData.Resource = resource;
foreach (var point in points)
{
Point dataPoint = new Point();
dataPoint.Value = point;
dataPoint.Interval = interval;
timeSeriesData.Points.Add(dataPoint);
}
timeSeries.Add(timeSeriesData);
// Write time series data.
await this.Client.CreateTimeSeriesAsync(name, timeSeries).ConfigureAwait(false);
}
}
I running this class with this code (create the metric and then fill it with dummy values):
try
{
CustomMetricsWritter customMetricsWriter = new CustomMetricsWritter(Consts.GOOGLE_CLOUD_PROJECT);
string metric = "custom.googleapis.com/web/latency";
customMetricsWriter.CreateMetric(metric, "Execution Latency", "Calling REST service (MS).", "{INT64}");
// Exception thrown in the next line ----->
await customMetricsWriter.WriteTimeSeriesDataAsync(
metric,
new TypedValue[] {
new TypedValue(){ Int64Value = 150},
new TypedValue(){ Int64Value = 250},
new TypedValue(){ Int64Value = 350},
},
"my-machine-type");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
throw;
}
I getting back this thrown exception:
Grpc.Core.RpcException: Status(StatusCode=InvalidArgument, Detail="One or more TimeSeries could not be written: Field timeSeries[0].points had an invalid value: Only one point can be written per TimeSeries per request.: timeSeries[0]")
at Google.Api.Gax.Grpc.ApiCallRetryExtensions.<>c__DisplayClass0_0`2.<<WithRetry>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at ***.CustomMetricsWritter.WriteTimeSeriesDataAsync(String metricDescriptor, TypedValue[] points, String machineName) in ***\GoogleCloud\CustomMetricsWritter.cs:line 131
at Test.Program.MainAsync() in ***\Test\Program.cs:line 156
What I'm doing wrong?
Upvotes: 0
Views: 361