< Summary

Information
Class: Chronicis.Api.Infrastructure.DatadogTracerState
Assembly: Chronicis.Api
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Api/Infrastructure/DatadogDiagnostics.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 6
Coverable lines: 6
Total lines: 192
Line coverage: 0%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_ServiceName()100%210%
get_Environment()100%210%
get_ServiceVersion()100%210%
get_AgentUri()100%210%
get_LogsInjectionEnabled()100%210%
get_TraceEnabled()100%210%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Api/Infrastructure/DatadogDiagnostics.cs

#LineLine coverage
 1using Datadog.Trace;
 2
 3namespace Chronicis.Api.Infrastructure;
 4
 5/// <summary>
 6/// Read-only diagnostic utilities for Datadog APM tracing.
 7///
 8/// IMPORTANT: This class does NOT configure the tracer. All Datadog configuration
 9/// is driven exclusively by DD_* environment variables, which are read by the
 10/// Datadog.Trace automatic instrumentation before application code runs.
 11///
 12/// This class provides:
 13/// - Read-only access to environment variables
 14/// - Read-only access to Tracer.Instance.Settings
 15/// - Agent connectivity testing
 16///
 17/// It does NOT:
 18/// - Call Tracer.Configure()
 19/// - Mutate TracerSettings
 20/// - Apply fallback values or defaults
 21/// - Make assumptions about the runtime environment
 22/// </summary>
 23public static class DatadogDiagnostics
 24{
 25    /// <summary>
 26    /// Logs the current Datadog tracer state for verification.
 27    /// Read-only - does not configure anything.
 28    /// </summary>
 29    public static void LogTracerState(Serilog.ILogger logger)
 30    {
 31        try
 32        {
 33            var envVars = ReadEnvironmentVariables();
 34            var tracerSettings = Tracer.Instance.Settings;
 35        }
 36        catch (Exception ex)
 37        {
 38            logger.Warning(ex, "Failed to read Datadog tracer state");
 39        }
 40    }
 41
 42    /// <summary>
 43    /// Reads current environment variables (DD_*) without interpretation or fallbacks.
 44    /// </summary>
 45    public static DatadogEnvVars ReadEnvironmentVariables()
 46    {
 47        return new DatadogEnvVars
 48        {
 49            DD_SERVICE = Environment.GetEnvironmentVariable("DD_SERVICE"),
 50            DD_ENV = Environment.GetEnvironmentVariable("DD_ENV"),
 51            DD_VERSION = Environment.GetEnvironmentVariable("DD_VERSION"),
 52            DD_AGENT_HOST = Environment.GetEnvironmentVariable("DD_AGENT_HOST"),
 53            DD_TRACE_AGENT_PORT = Environment.GetEnvironmentVariable("DD_TRACE_AGENT_PORT"),
 54            DD_LOGS_INJECTION = Environment.GetEnvironmentVariable("DD_LOGS_INJECTION"),
 55            DD_TRACE_ENABLED = Environment.GetEnvironmentVariable("DD_TRACE_ENABLED"),
 56            DD_TRACE_AGENT_URL = Environment.GetEnvironmentVariable("DD_TRACE_AGENT_URL"),
 57            ASPNETCORE_ENVIRONMENT = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
 58        };
 59    }
 60
 61    /// <summary>
 62    /// Reads current tracer settings. Read-only snapshot of Tracer.Instance.Settings.
 63    /// </summary>
 64    public static DatadogTracerState ReadTracerState()
 65    {
 66        var settings = Tracer.Instance.Settings;
 67
 68        return new DatadogTracerState
 69        {
 70            ServiceName = settings.ServiceName,
 71            Environment = settings.Environment,
 72            ServiceVersion = settings.ServiceVersion,
 73            AgentUri = settings.AgentUri?.ToString(),
 74            LogsInjectionEnabled = settings.LogsInjectionEnabled,
 75            TraceEnabled = settings.TraceEnabled
 76        };
 77    }
 78
 79    /// <summary>
 80    /// Attempts to reach a Datadog agent endpoint and returns connectivity status.
 81    /// </summary>
 82    public static async Task<AgentConnectivityResult> CheckAgentConnectivityAsync(
 83        HttpClient httpClient,
 84        string agentBaseUrl)
 85    {
 86        if (string.IsNullOrEmpty(agentBaseUrl))
 87        {
 88            return new AgentConnectivityResult
 89            {
 90                Url = "(not provided)",
 91                Status = "skipped",
 92                Message = "No URL provided"
 93            };
 94        }
 95
 96        var infoUrl = $"{agentBaseUrl.TrimEnd('/')}/info";
 97
 98        try
 99        {
 100            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
 101            var response = await httpClient.GetAsync(infoUrl, cts.Token);
 102
 103            if (response.IsSuccessStatusCode)
 104            {
 105                var content = await response.Content.ReadAsStringAsync(cts.Token);
 106                return new AgentConnectivityResult
 107                {
 108                    Url = infoUrl,
 109                    Status = "reachable",
 110                    StatusCode = (int)response.StatusCode,
 111                    AgentInfo = content
 112                };
 113            }
 114
 115            return new AgentConnectivityResult
 116            {
 117                Url = infoUrl,
 118                Status = "http_error",
 119                StatusCode = (int)response.StatusCode,
 120                Message = $"HTTP {(int)response.StatusCode} {response.ReasonPhrase}"
 121            };
 122        }
 123        catch (HttpRequestException ex)
 124        {
 125            return new AgentConnectivityResult
 126            {
 127                Url = infoUrl,
 128                Status = "unreachable",
 129                Message = ex.Message
 130            };
 131        }
 132        catch (TaskCanceledException)
 133        {
 134            return new AgentConnectivityResult
 135            {
 136                Url = infoUrl,
 137                Status = "timeout",
 138                Message = "Connection timed out after 5 seconds"
 139            };
 140        }
 141        catch (Exception ex)
 142        {
 143            return new AgentConnectivityResult
 144            {
 145                Url = infoUrl,
 146                Status = "error",
 147                Message = ex.Message
 148            };
 149        }
 150    }
 151}
 152
 153/// <summary>
 154/// Raw environment variable values. No interpretation, no fallbacks.
 155/// </summary>
 156public record DatadogEnvVars
 157{
 158    public string? DD_SERVICE { get; init; }
 159    public string? DD_ENV { get; init; }
 160    public string? DD_VERSION { get; init; }
 161    public string? DD_AGENT_HOST { get; init; }
 162    public string? DD_TRACE_AGENT_PORT { get; init; }
 163    public string? DD_TRACE_AGENT_URL { get; init; }
 164    public string? DD_LOGS_INJECTION { get; init; }
 165    public string? DD_TRACE_ENABLED { get; init; }
 166    public string? ASPNETCORE_ENVIRONMENT { get; init; }
 167}
 168
 169/// <summary>
 170/// Read-only snapshot of Tracer.Instance.Settings.
 171/// </summary>
 172public record DatadogTracerState
 173{
 0174    public string? ServiceName { get; init; }
 0175    public string? Environment { get; init; }
 0176    public string? ServiceVersion { get; init; }
 0177    public string? AgentUri { get; init; }
 0178    public bool LogsInjectionEnabled { get; init; }
 0179    public bool TraceEnabled { get; init; }
 180}
 181
 182/// <summary>
 183/// Result of an agent connectivity check.
 184/// </summary>
 185public record AgentConnectivityResult
 186{
 187    public required string Url { get; init; }
 188    public required string Status { get; init; }
 189    public int? StatusCode { get; init; }
 190    public string? Message { get; init; }
 191    public string? AgentInfo { get; init; }
 192}