Description
Now that we have OTEL, add DAB info
The current OTEL implementation only has generic/basic ASPNET information.
Traces:
https://github.com/Azure/data-api-builder/blob/jerry-otel-design/docs/design/otel-trace.md
Trace: DAB Request
β βββ Tags:
β β βββ trace_id: <unique_trace_id>
β β βββ service.name: "Data API Builder"
β β βββ deployment.environment: "production" (or "development")
β
βββ Activity: Request Setup
β βββ Tags:
β β βββ http.method: "GET" | "POST" | "PUT" | "DELETE"
β β βββ action.type: "CREATE" | "READ" | "UPDATE" | "DELETE" | "EXECUTE"
β β βββ http.status_code: "200" | "400" | "500"
β β βββ http.url: "/api/entity"
β β βββ http.querystring: "?xyz" {only when mode = development}
β β βββ user.role: "Anonymous"
β β βββ api.type: "REST" | "GRAPHQL"
β β βββ api.entity: "User"
β β β
β βββ Span: Validate Request Context
β β βββ Tags:
β β β βββ validation.result: "Success" | "Failure"
β β βββ Event: Validation Error (if any)
β β βββ Tags: { error.message: "<error_details>", error.type: "<exception_type>" }
β β
β βββ Span: Process Request
β β β
β β βββ Event: Error (if any)
β β βββ Tags: { error.message: "<error_details>", error.type: "<exception_type>" }
β β
β βββ Span: Format Response
β β β
β β βββ Event: Response Sent
β β βββ Tags: { event.name: "Response Sent", timestamp: <time> }
β
βββ Activity: Database Query
βββ Tags:
β βββ data-source.name: {data-source.telemetry.name}
β βββ data-source.type: "mssql" | "mysql" | "postgresql" | "cosmos" | "sqldw"
β βββ db.operation: "SELECT" | "INSERT" | "UPDATE" | "DELETE" | "EXECUTE"
β βββ db.statement: "<SQL_query_text>" {only when mode = development}
β
βββ Span: Data Operation
β β βββ query.rows_returned: <num_rows>
β β βββ query.mb_returned: <double>
β β βββ query.used_cache: true | false
β β
β βββ Event: Cache Returned
β β
β βββ Event: Connection Opened
β β
β βββ Event: Query Executed
β β
β βββ Event: Connection Opened
β β
β βββ Event: Error (if any)
β βββ Tags: { error.message: "<error_details>", error.type: "<exception_type>" }
Metrics:
TelemetryHelper.cs
using System;
using System.Diagnostics.Metrics;
public static class TelemetryHelper
{
private static readonly Meter Meter = new("Dab.Metrics");
private static readonly Counter<long> RequestsTotal = Meter.CreateCounter<long>("requests_total");
private static readonly UpDownCounter<long> RequestsActive = Meter.CreateUpDownCounter<long>("requests_active");
private static readonly Counter<long> RequestErrors = Meter.CreateCounter<long>("request_errors");
public static void TrackRequest(string method, string statusCode, string endpoint, string apiType)
{
RequestsTotal.Add(1,
new("method", method),
new("status_code", statusCode),
new("endpoint", endpoint),
new("api_type", apiType));
}
public static void TrackError(string method, string statusCode, string endpoint, string apiType, Exception ex)
{
RequestErrors.Add(1,
new("method", method),
new("status_code", statusCode),
new("endpoint", endpoint),
new("api_type", apiType),
new("error_type", ex.GetType().Name));
}
public static void IncrementActiveRequests() => RequestsActive.Add(1);
public static void DecrementActiveRequests() => RequestsActive.Add(-1);
}
Then use it like.
[HttpGet]
public IActionResult GetAsync(...)
{
TelemetryHelper.IncrementActiveRequests();
try
{
// Simulating success
TelemetryHelper.TrackRequest("GET", "200", "User", "REST");
return Ok(new { Message = "Hello, World!" });
}
catch (Exception ex)
{
TelemetryHelper.TrackError("GET", "500", "User", "REST", ex);
return StatusCode(500, new { Error = "An error occurred" });
}
finally
{
TelemetryHelper.DecrementActiveRequests();
}
}