Reporting Sinks

Stream realtime and final statistics to built-in observability targets or custom enterprise sinks.

Built-In Vendor Sinks

LoadStrike includes first-party reporting sinks for InfluxDB, TimescaleDB, Grafana Loki, Datadog, Splunk HEC, and OTEL Collector. All built-in sinks publish LoadStrike reporting events plus metric projections, including realtime scenario stats, custom metrics, final run summaries, final metric snapshots, status-code rows, threshold outcomes, and final plugin-table rows such as failed-response and correlation summaries. Final sink export also carries started/completed timestamps plus run-result artifact metadata such as report files, disabled sink names, and sink error counts. Datadog sends both log and metrics intake, Splunk sends HEC event envelopes for both log and metric data, OTEL Collector sends OTLP/HTTP logs and metrics, and the storage-backed sinks write the same reporting events and metric projections into their native backends.

Configuration Model

Each sink accepts an options object in code and can also bind missing values from infra config sections: LoadStrike:ReportingSinks:InfluxDb, LoadStrike:ReportingSinks:TimescaleDb, LoadStrike:ReportingSinks:GrafanaLoki, LoadStrike:ReportingSinks:Datadog, LoadStrike:ReportingSinks:Splunk, and LoadStrike:ReportingSinks:OtelCollector. TypeScript/JavaScript also expose named option constructors (InfluxDbReportingSinkOptions, GrafanaLokiReportingSinkOptions, TimescaleDbReportingSinkOptions, DatadogReportingSinkOptions, SplunkReportingSinkOptions, and OtelCollectorReportingSinkOptions) alongside object-literal inputs. Influx writes use nanosecond precision and can split projected metrics into a dedicated MetricsMeasurementName. TimescaleDB can split projected metrics into a dedicated MetricsTableName. Grafana Loki can keep log events in Loki while sending OTLP/HTTP metrics through MetricsBaseUrl, MetricsEndpointPath, and MetricsHeaders. Splunk uses the HEC event endpoint, OTEL uses OTLP/HTTP, and final plugin-table rows are included in exported sink data where supported.

Failure Handling

Sink init, start, realtime writes, and final export use retry and backoff. If a sink continues to fail, LoadStrike logs a warning, disables that sink for the run, and continues load execution instead of aborting the scenario run.

Grafana Starter Assets

Matching datasource YAML files, dashboard provider YAML, and starter dashboard JSON files are available from the documentation downloads area so customers can wire Grafana to Loki, InfluxDB, or TimescaleDB without pulling the source repository.

Custom Sink Contract

Implement ILoadStrikeReportingSink and register via WithReportingSinks when you need a project-specific destination. Lifecycle includes Init(LoadStrikeBaseContext, infraConfig), Start(LoadStrikeSessionStartInfo), SaveRealtimeStats(LoadStrikeScenarioStats[]), SaveRealtimeMetrics(LoadStrikeMetricStats), SaveFinalStats(LoadStrikeNodeStats), SaveRunResult(LoadStrikeSinkRunResult), and Stop. The run-result callback receives report file paths, disabled sink names, sink error details, and the started/completed timestamps for the run. Python custom sinks now quiesce realtime emissions before SaveFinalStats, SaveRunResult, and Stop so final lifecycle ordering stays deterministic.

Plan Gate

Built-in vendor sinks require the matching vendor entitlement and are available on Business and Enterprise plans. Custom reporting sinks remain enterprise-only and require extensions.reporting_sinks.custom.

Feature Usage Samples

How to use snippets for Reporting Sinks.

Switch between C#, Java, Python, TypeScript, and JavaScript to see the native SDK shape for this sample.

Licensing note: every runnable sample requires a valid runner key via WithRunnerKey("...") or config key LoadStrike:RunnerKey.

Reporting Sink

var sink = new DatadogReportingSink(new DatadogReportingSinkOptions
{
    BaseUrl = "https://api.datadoghq.com",
    ApiKey = "dd-api-key",
    ApplicationKey = "dd-app-key",
    StaticTags =
    {
        ["environment"] = "staging"
    }
});

LoadStrikeRunner.RegisterScenarios(scenario)
    .WithReportingSinks(sink)
    .WithRunnerKey("rkl_your_local_runner_key")
    .Run();

Built-In Sink Options

InfluxDb

Writes reporting events and metric projections into InfluxDB, with an optional separate metrics measurement.

TimescaleDb

Writes reporting events and projected metrics into PostgreSQL or TimescaleDB tables.

GrafanaLoki

Writes log-style reporting events to Loki and can forward projected metrics through the OTLP metrics companion settings.

Datadog

Sends reporting events to Datadog logs and projected metrics to Datadog metrics.

Splunk

Sends both reporting events and metric projections through the Splunk HEC event endpoint.

OtelCollector

Sends OTLP/HTTP logs and metrics to an OpenTelemetry collector pipeline.

Custom sink

Enterprise projects can also register a custom reporting sink implementation when a built-in destination is not enough.

{
  "LoadStrike": {
    "ReportingSinks": {
      "InfluxDb": {
        "BaseUrl": "https://influx.example.com",
        "Organization": "performance-team",
        "Bucket": "loadstrike-runs",
        "Token": "influx-token",
        "MeasurementName": "loadstrike_events",
        "MetricsMeasurementName": "loadstrike_metrics"
      },
      "TimescaleDb": {
        "ConnectionString": "Host=db.example.com;Port=5432;Database=loadstrike;Username=postgres;Password=postgres",
        "Schema": "observability",
        "TableName": "loadstrike_reporting_events",
        "MetricsTableName": "loadstrike_reporting_metrics"
      },
      "GrafanaLoki": {
        "BaseUrl": "https://loki.example.com",
        "BearerToken": "loki-token",
        "MetricsBaseUrl": "https://otel-gateway.example.com",
        "MetricsEndpointPath": "/v1/metrics",
        "MetricsHeaders": {
          "Authorization": "Bearer otlp-metrics-token"
        }
      },
      "Datadog": {
        "BaseUrl": "https://api.datadoghq.com",
        "ApiKey": "dd-api-key",
        "ApplicationKey": "dd-app-key"
      },
      "Splunk": {
        "BaseUrl": "https://splunk.example.com",
        "Token": "splunk-hec-token"
      },
      "OtelCollector": {
        "BaseUrl": "https://otel.example.com",
        "Headers": {
          "Authorization": "Bearer otel-token"
        }
      }
    }
  }
}

Individual Sink Samples

Use the built-in sink that matches your storage or observability destination. All built-in sinks export reporting events plus metric projections, and final export also includes final metric snapshots, started/completed timestamps, report-file metadata, disabled sink names, sink error counts, and plugin-table rows so failed responses and correlation tables can be queried outside the HTML report. Missing sink values can bind from LoadStrike:ReportingSinks:* infra-config sections. Datadog sends both logs and metrics, Splunk sends HEC event envelopes for both, OTEL Collector sends OTLP/HTTP logs and metrics, and Grafana starter downloads are available for InfluxDB, TimescaleDB, and Grafana Loki.

Datadog Sink

Use Datadog when you want LoadStrike reporting events to arrive in Datadog Logs and the matching metric projections to arrive in Datadog Metrics.

var scenario = LoadStrikeScenario.Empty("orders-load")
    .WithLoadSimulations(
        LoadStrikeSimulation.Inject(rate: 25, interval: TimeSpan.FromSeconds(1), during: TimeSpan.FromMinutes(2))
    );

var datadogSink = new DatadogReportingSink(new DatadogReportingSinkOptions
{
    BaseUrl = "https://api.datadoghq.com",
    ApiKey = "dd-api-key",
    ApplicationKey = "dd-app-key",
    StaticTags =
    {
        ["environment"] = "staging",
        ["service"] = "orders-api"
    },
    StaticAttributes =
    {
        ["team"] = "performance"
    }
});

LoadStrikeRunner.RegisterScenarios(scenario)
    .WithReportingSinks(datadogSink)
    .WithRunnerKey("rkl_your_local_runner_key")
    .Run();

Splunk HEC Sink

Use Splunk when you want both reporting events and metric projections written through the Splunk HTTP Event Collector event endpoint.

var scenario = LoadStrikeScenario.Empty("checkout-load")
    .WithLoadSimulations(
        LoadStrikeSimulation.KeepConstant(copies: 12, during: TimeSpan.FromMinutes(5))
    );

var splunkSink = new SplunkReportingSink(new SplunkReportingSinkOptions
{
    BaseUrl = "https://splunk.example.com",
    Token = "splunk-hec-token",
    Source = "loadstrike",
    Sourcetype = "_json",
    Index = "observability",
    StaticFields =
    {
        ["environment"] = "preprod",
        ["service"] = "checkout"
    }
});

LoadStrikeRunner.RegisterScenarios(scenario)
    .WithReportingSinks(splunkSink)
    .WithRunnerKey("rkl_your_local_runner_key")
    .Run();

OTEL Collector Sink

Use OTEL Collector when you want OTLP/HTTP logs and metrics sent to an OpenTelemetry collector or compatible vendor pipeline.

var scenario = LoadStrikeScenario.Empty("payments-load")
    .WithLoadSimulations(
        LoadStrikeSimulation.Inject(rate: 10, interval: TimeSpan.FromSeconds(1), during: TimeSpan.FromMinutes(3))
    );

var otelSink = new OtelCollectorReportingSink(new OtelCollectorReportingSinkOptions
{
    BaseUrl = "https://otel.example.com",
    Headers =
    {
        ["Authorization"] = "Bearer otel-token"
    },
    StaticResourceAttributes =
    {
        ["deployment.environment"] = "production-like",
        ["service.name"] = "payments"
    }
});

LoadStrikeRunner.RegisterScenarios(scenario)
    .WithReportingSinks(otelSink)
    .WithRunnerKey("rkl_your_local_runner_key")
    .Run();

InfluxDB Sink

Best when you want line-protocol ingestion into an InfluxDB bucket and then chart reporting events plus metric projections. Use MetricsMeasurementName when you want the projected metrics split into a separate measurement.

var scenario = LoadStrikeScenario.Empty("orders-load")
    .WithLoadSimulations(
        LoadStrikeSimulation.Inject(rate: 25, interval: TimeSpan.FromSeconds(1), during: TimeSpan.FromMinutes(2))
    );

var influxSink = new InfluxDbReportingSink(new InfluxDbReportingSinkOptions
{
    BaseUrl = "https://influx.example.com",
    Organization = "performance-team",
    Bucket = "loadstrike-runs",
    Token = "influx-token",
    MeasurementName = "loadstrike_orders",
    MetricsMeasurementName = "loadstrike_orders_metrics",
    StaticTags =
    {
        ["environment"] = "staging",
        ["service"] = "orders-api"
    }
});

LoadStrikeRunner.RegisterScenarios(scenario)
    .WithReportingSinks(influxSink)
    .WithRunnerKey("rkl_your_local_runner_key")
    .Run();

TimescaleDB Sink

Use this when you want PostgreSQL-compatible storage with JSONB reporting-event rows and a separate metrics table for projected metrics, plus Timescale hypertables for time-series retention and querying.

var scenario = LoadStrikeScenario.Empty("checkout-load")
    .WithLoadSimulations(
        LoadStrikeSimulation.KeepConstant(copies: 12, during: TimeSpan.FromMinutes(5))
    );

var timescaleSink = new TimescaleDbReportingSink(new TimescaleDbReportingSinkOptions
{
    ConnectionString = "Host=db.example.com;Port=5432;Database=loadstrike;Username=postgres;Password=postgres",
    Schema = "observability",
    TableName = "loadstrike_reporting_events",
    MetricsTableName = "loadstrike_reporting_metrics",
    CreateSchemaIfMissing = true,
    EnableHypertableIfAvailable = true,
    StaticTags =
    {
        ["environment"] = "preprod",
        ["service"] = "checkout"
    }
});

LoadStrikeRunner.RegisterScenarios(scenario)
    .WithReportingSinks(timescaleSink)
    .WithRunnerKey("rkl_your_local_runner_key")
    .Run();

Grafana Loki Sink

Use Grafana Loki when you want log-style reporting-event storage in Loki and an OTLP/HTTP companion metrics stream for the projected metrics. This keeps logs in Loki while still giving you metric series for dashboards and alerts.

var scenario = LoadStrikeScenario.Empty("payments-load")
    .WithLoadSimulations(
        LoadStrikeSimulation.Inject(rate: 10, interval: TimeSpan.FromSeconds(1), during: TimeSpan.FromMinutes(3))
    );

var lokiSink = new GrafanaLokiReportingSink(new GrafanaLokiReportingSinkOptions
{
    BaseUrl = "https://loki.example.com",
    MetricsBaseUrl = "https://otel-gateway.example.com",
    MetricsEndpointPath = "/v1/metrics",
    MetricsHeaders =
    {
        ["Authorization"] = "Bearer otlp-metrics-token"
    },
    TenantId = "platform-team",
    BearerToken = "loki-token",
    StaticLabels =
    {
        ["environment"] = "production-like",
        ["service"] = "payments"
    }
});

LoadStrikeRunner.RegisterScenarios(scenario)
    .WithReportingSinks(lokiSink)
    .WithRunnerKey("rkl_your_local_runner_key")
    .Run();

Custom Sink

Use a custom sink when you need to push LoadStrike events into an internal platform that is not covered by the built-in vendor sinks. This remains Enterprise-only.

public sealed class InternalOpsSink : ILoadStrikeReportingSink
{
    public string SinkName => "internal-ops";

    public Task Init(LoadStrikeBaseContext context, IConfiguration infraConfig) => Task.CompletedTask;

    public Task Start(LoadStrikeSessionStartInfo sessionInfo) => Task.CompletedTask;

    public Task SaveRealtimeStats(LoadStrikeScenarioStats[] stats)
    {
        foreach (var scenario in stats)
        {
            Console.WriteLine($"{scenario.ScenarioName}: {scenario.AllRequestCount}");
        }

        return Task.CompletedTask;
    }

    public Task SaveRealtimeMetrics(LoadStrikeMetricStats metrics) => Task.CompletedTask;

    public Task SaveFinalStats(LoadStrikeNodeStats stats)
    {
        Console.WriteLine($"Final requests: {stats.AllRequestCount}");
        return Task.CompletedTask;
    }

    public Task Stop() => Task.CompletedTask;
}

LoadStrikeRunner.RegisterScenarios(scenario)
    .WithReportingSinks(new InternalOpsSink())
    .WithRunnerKey("rkl_your_local_runner_key")
    .Run();

Full Observability Asset Guide

Use the public downloads below when you need the matching Grafana files or sink templates without cloning the source repository.

Public download paths:
- /downloads/grafana/provisioning/datasources/loadstrike-loki.yaml
- /downloads/grafana/provisioning/datasources/loadstrike-influxdb.yaml
- /downloads/grafana/provisioning/datasources/loadstrike-timescaledb.yaml
- /downloads/grafana/provisioning/dashboards/loadstrike.yaml
- /downloads/grafana/dashboards/loadstrike-loki-overview.json
- /downloads/grafana/dashboards/loadstrike-influxdb-overview.json
- /downloads/grafana/dashboards/loadstrike-timescaledb-overview.json
- /downloads/observability/sinks/loadstrike-datadog-reporting-sink.json
- /downloads/observability/sinks/loadstrike-splunk-reporting-sink.json
- /downloads/observability/sinks/loadstrike-otel-collector-reporting-sink.json
- /downloads/observability/loadstrike-observability-assets-guide.md