CloudWatch Integration
Send logs and metrics to AWS CloudWatch using the PrimusSaaS.Logging.CloudWatch companion package.
Install
dotnet add package PrimusSaaS.Logging.CloudWatch --version 1.5.0
Operational Logs
Route structured logs to a CloudWatch Logs group:
using PrimusSaaS.Logging.CloudWatch;
builder.Logging.AddPrimus(options =>
{
options.ApplicationId = "my-app";
options.AddCloudWatchTarget(cw =>
{
cw.LogGroupName = "/app/my-app/logs";
cw.Region = "us-east-1";
});
});
Audit Log Routing
Route audit entries to a separate CloudWatch log group for compliance isolation:
builder.Logging.AddPrimus(options =>
{
options.ApplicationId = "my-app";
// Operational logs
options.AddCloudWatchTarget(cw =>
{
cw.LogGroupName = "/app/my-app/logs";
cw.Region = "us-east-1";
});
// Audit entries (separate log group)
options.AddCloudWatchAuditTarget(cw =>
{
cw.LogGroupName = "/app/my-app/audit";
cw.Region = "us-east-1";
});
});
CloudWatch Metrics (EMF)
Bridge System.Diagnostics.Metrics to CloudWatch via Embedded Metric Format (EMF). Metrics are published through CloudWatch Logs and automatically extracted as custom metrics — no additional AWS SDK dependency needed.
using PrimusSaaS.Logging.CloudWatch;
var publisher = CloudWatchExtensions.CreateMetricsPublisher(options =>
{
options.MetricsLogGroupName = "/app/my-app/metrics";
options.MetricsNamespace = "MyApp/Primus";
options.FlushIntervalMs = 60_000; // 1 minute
});
Metrics Options
| Option | Default | Description |
|---|---|---|
MetricsLogGroupName | (required) | CloudWatch Logs group for EMF entries |
MetricsLogStreamName | auto-generated | Log stream name |
MetricsNamespace | "PrimusSaaS" | CloudWatch metric namespace |
FlushIntervalMs | 60000 | Flush interval in milliseconds |
Built-in Metrics
| Metric | Type | Description |
|---|---|---|
primus.requests_processed | Counter | Total requests processed |
primus.errors_logged | Counter | Total errors logged |
primus.request_duration | Histogram | Request duration in ms |
Record metrics from your code:
using PrimusSaaS.Logging.Diagnostics;
PrimusActivitySource.RecordRequestProcessed();
PrimusActivitySource.RecordErrorLogged();
PrimusActivitySource.RecordRequestDuration(142.5);
256 KB Entry Guard
CloudWatch Logs enforces a 256 KB per-entry limit. The CloudWatch target automatically truncates oversized log entries before submission, preventing silent write failures.
IAM Permissions
The application identity needs these CloudWatch Logs permissions:
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:log-group:/app/my-app/*"
}
AWS X-Ray Integration
Create properly annotated Activities that appear as segments in AWS X-Ray:
dotnet add package OpenTelemetry.Extensions.AWS
dotnet add package OpenTelemetry.Contrib.Extensions.AWSXRay
Configure OpenTelemetry
using PrimusSaaS.Logging.Diagnostics;
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddSource(PrimusActivitySource.SourceName)
.AddAWSInstrumentation()
.AddOtlpExporter());
Create X-Ray Segments
using PrimusSaaS.Logging.Tracing;
using var activity = XRayIntegration.StartXRaySegment("ProcessOrder", tenantId: "tenant-42");
try
{
await ProcessOrderAsync();
}
catch (Exception ex)
{
XRayIntegration.RecordFault(activity, ex);
throw;
}
Trace ID Conversion
Convert between X-Ray and W3C trace ID formats:
// X-Ray -> W3C
var w3cId = XRayIntegration.ConvertXRayToW3CTraceId("1-5759e988-bd862e3fe1be46a994272793");
// W3C -> X-Ray
var xrayId = XRayIntegration.ConvertW3CToXRayTraceId("5759e988bd862e3fe1be46a994272793");