Skip to main content
Version: 2026.04.0

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

OptionDefaultDescription
MetricsLogGroupName(required)CloudWatch Logs group for EMF entries
MetricsLogStreamNameauto-generatedLog stream name
MetricsNamespace"PrimusSaaS"CloudWatch metric namespace
FlushIntervalMs60000Flush interval in milliseconds

Built-in Metrics

MetricTypeDescription
primus.requests_processedCounterTotal requests processed
primus.errors_loggedCounterTotal errors logged
primus.request_durationHistogramRequest 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");