feat(servicedefaults): add SeqOptions configuration and integrate with OpenTelemetry logging and tracing

This commit is contained in:
Stevan Freeborn
2026-03-11 18:52:05 -05:00
parent e30f19e939
commit 64c64e8d95
6 changed files with 66 additions and 3 deletions
+6
View File
@@ -70,6 +70,9 @@ jobs:
PLAID_CLIENT_ID: ${{ secrets.PLAID_CLIENT_ID }}
PLAID_SECRET: ${{ secrets.PLAID_SECRET }}
PLAID_WEBHOOK: ${{ secrets.PLAID_WEBHOOK }}
SEQ_SERVER_URL: ${{ secrets.SEQ_SERVER_URL }}
SEQ_API_KEY_HEADER: ${{ secrets.SEQ_API_KEY_HEADER }}
SEQ_API_KEY: ${{ secrets.SEQ_API_KEY }}
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
@@ -88,6 +91,9 @@ jobs:
PLAID_CLIENT_ID=${PLAID_CLIENT_ID}
PLAID_SECRET=${PLAID_SECRET}
PLAID_WEBHOOK=${PLAID_WEBHOOK}
SEQ_SERVER_URL=${SEQ_SERVER_URL}
SEQ_API_KEY_HEADER=${SEQ_API_KEY_HEADER}
SEQ_API_KEY=${SEQ_API_KEY}
EOF
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d --remove-orphans
+3
View File
@@ -21,6 +21,9 @@ services:
- PlaidClientOptions__ClientId=${PLAID_CLIENT_ID}
- PlaidClientOptions__Secret=${PLAID_SECRET}
- PlaidClientOptions__Webhook=${PLAID_WEBHOOK}
- SeqOptions__ServerUrl=${SEQ_SERVER_URL}
- SeqOptions__ApiKeyHeader=${SEQ_API_KEY_HEADER}
- SeqOptions__ApiKey=${SEQ_API_KEY}
volumes:
- ./data:/data
- ./keys:/keys
+3
View File
@@ -27,6 +27,9 @@ services:
- PlaidClientOptions__ClientId=${PLAID_CLIENT_ID}
- PlaidClientOptions__Secret=${PLAID_SECRET}
- PlaidClientOptions__Webhook=${PLAID_WEBHOOK}
- SeqOptions__ServerUrl=${SEQ_SERVER_URL}
- SeqOptions__ApiKeyHeader=${SEQ_API_KEY_HEADER}
- SeqOptions__ApiKey=${SEQ_API_KEY}
volumes:
- ./data:/data
- ./keys:/keys
+6 -1
View File
@@ -23,5 +23,10 @@
"ClientId": "ClientId",
"Secret": "Secret",
"Webhook": "Webhook"
},
"SeqOptions": {
"ServerUrl": "ServerUrl",
"ApiKeyHeader": "ApiKeyHeader",
"ApiKey": "ApiKey"
}
}
}
@@ -0,0 +1,14 @@
namespace FiscalOS.ServiceDefaults;
internal sealed class SeqOptions
{
public string ServerUrl { get; init; } = string.Empty;
public string ApiKeyHeader { get; init; } = string.Empty;
public string ApiKey { get; init; } = string.Empty;
public bool IsEnabled => string.IsNullOrWhiteSpace(ServerUrl) is false &&
string.IsNullOrWhiteSpace(ApiKeyHeader) is false &&
string.IsNullOrWhiteSpace(ApiKey) is false;
public string LogEndpoint => $"{ServerUrl}/ingest/otlp/v1/logs";
public string TraceEndpoint => $"{ServerUrl}/ingest/otlp/v1/traces";
public string AuthHeader => $"{ApiKeyHeader}={ApiKey}";
}
@@ -1,3 +1,8 @@
using Microsoft.Extensions.Configuration;
using OpenTelemetry.Exporter;
using OpenTelemetry.Logs;
namespace FiscalOS.ServiceDefaults;
public static class ServiceDefaultsExtensions
@@ -76,11 +81,38 @@ public static class ServiceDefaultsExtensions
private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
{
var seqOptions = new SeqOptions();
builder.Configuration.GetSection(nameof(SeqOptions)).Bind(seqOptions);
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
if (useOtlpExporter)
var otel = builder.Services.AddOpenTelemetry();
if (seqOptions.IsEnabled)
{
builder.Services.AddOpenTelemetry().UseOtlpExporter();
otel
.WithLogging(lb =>
{
lb.AddOtlpExporter(o =>
{
o.Protocol = OtlpExportProtocol.HttpProtobuf;
o.Endpoint = new Uri(seqOptions.LogEndpoint);
o.Headers = seqOptions.AuthHeader;
});
})
.WithTracing(tb =>
{
tb.AddOtlpExporter(o =>
{
o.Protocol = OtlpExportProtocol.HttpProtobuf;
o.Endpoint = new Uri(seqOptions.TraceEndpoint);
o.Headers = seqOptions.AuthHeader;
});
});
}
else if (useOtlpExporter)
{
otel.UseOtlpExporter();
}
return builder;