![]() |
VOOZH | about |
dotnet add package Davasorus.Utility.DotNet.SQS --version 2026.2.3.3
NuGet\Install-Package Davasorus.Utility.DotNet.SQS -Version 2026.2.3.3
<PackageReference Include="Davasorus.Utility.DotNet.SQS" Version="2026.2.3.3" />
<PackageVersion Include="Davasorus.Utility.DotNet.SQS" Version="2026.2.3.3" />Directory.Packages.props
<PackageReference Include="Davasorus.Utility.DotNet.SQS" />Project file
paket add Davasorus.Utility.DotNet.SQS --version 2026.2.3.3
#r "nuget: Davasorus.Utility.DotNet.SQS, 2026.2.3.3"
#:package Davasorus.Utility.DotNet.SQS@2026.2.3.3
#addin nuget:?package=Davasorus.Utility.DotNet.SQS&version=2026.2.3.3Install as a Cake Addin
#tool nuget:?package=Davasorus.Utility.DotNet.SQS&version=2026.2.3.3Install as a Cake Tool
Davasorus.Utility.DotNet.SQS provides utilities for publishing to and consuming from Amazon SQS from .NET applications. It handles message serialization, content-based deduplication, optional anonymization, optional location enrichment, OpenTelemetry tracing, and W3C trace-context propagation through SQS message attributes.
The package multi-targets net8.0 and net10.0.
ISqsPublisher — typed publish, SqsResult<T> returns, CancellationToken everywhere, content-based deduplication that actually works (fixes a v1 bug).ISqsConsumer — typed ReceiveAsync<T> with partial-batch tolerance, DeleteAsync, ChangeVisibilityAsync, DeleteBatchAsync.traceparent injection on publish, extraction on receive — end-to-end OpenTelemetry traces flow through SQS message attributes automatically.IAmazonSQS.ipify.org + ipinfo.io over HTTPS with Polly resilience, or supply your own ILocationProvider.IAnonymizationPolicy + IReportedErrorTracker replace v1's reads of MasterUiObj.AnonErrorReporting and TrelloErrorReportingObjs.Collection.IAmazonSQS with cached queue URLs — fixes the v1 perf bug of building a new client per request.SqsResult<T> instead of "error" sentinel returns. v1 ISqsService shim preserves the old sentinel for back-compat.[Obsolete] shims for v1 — existing ISqsService / ISqsClient / ILocationService / ILocationClient callers compile unchanged with migration warnings.// Defaults: decrypted-key credentials, location enrichment OFF, anonymization OFF.
services.AddSqsLogging();
// Inject the publisher in your app code:
public class MyService(ISqsPublisher sqs)
{
public async Task LogAsync(string message, CancellationToken ct)
{
var model = new TrelloMessageQueueModel { Message = message };
var result = await sqs.SendLoggingMessageAsync(model, ct);
if (!result.IsSuccess)
// result.Error has the exception
;
}
}
services.AddSqsLogging(sqs => sqs
.WithCredentialChain() // AWS SDK default chain
.WithRegion("us-west-2")
.WithQueues(q => q
.Message("myapp-messages.fifo")
.Response("myapp-responses.fifo"))
.WithIpInfoLocation(l => l // opt in to enrichment
.CacheLocation(TimeSpan.FromHours(1))
.CacheIpAddress(TimeSpan.FromHours(4)))
.WithAnonymization(a => a
.Enabled(true)
.MaxErrorCollectionSize(500))
.WithResilience(r => r
.LocationRetryCount(3)));
appsettings.jsonservices.AddSqsLogging(builder.Configuration.GetSection("SqsOptions"));
{
"SqsOptions": {
"Aws": {
"Region": "us-east-1",
"CredentialMode": "CredentialChain",
"QueueUrlCacheTtl": "00:00:00"
},
"Queues": {
"Message": "myapp-messages.fifo",
"Response": "myapp-responses.fifo"
},
"Location": {
"EnableEnrichment": true,
"ProviderMode": "IpInfo",
"LocationCacheTtl": "01:00:00",
"IpAddressCacheTtl": "04:00:00"
},
"Anonymization": {
"Enabled": true,
"MaxErrorCollectionSize": 500
}
}
}
services.AddSqsLogging(
builder.Configuration.GetSection("SqsOptions"),
sqs => sqs.WithRegion("ap-southeast-2")); // fluent overrides config
IAmazonSQSservices.AddSingleton<IAmazonSQS>(_ => new AmazonSQSClient(creds, myConfig));
services.AddSqsLogging(sqs => sqs.WithCustomClient());
ILocationProviderservices.AddSingleton<ILocationProvider, MyInternalLocationProvider>();
services.AddSqsLogging(sqs => sqs.WithCustomLocationProvider());
| Type | Lifetime | Purpose |
|---|---|---|
ISqsPublisher |
Scoped | Publish messages. Returns SqsResult<string> (the SQS message id). |
ISqsConsumer |
Scoped | Receive / delete / change-visibility primitives. |
ILocationProvider |
Singleton | Default NullLocationProvider; opt in to IpInfoLocationProvider. |
IAnonymizationPolicy |
Singleton | Owns the anonymous-reporting flag and username scrubbing. |
IReportedErrorTracker |
Singleton | Process-wide bounded dedup set. |
ISqsTransport |
Singleton | Thin IAmazonSQS wrapper with tracing + traceparent injection. |
IAmazonSQS |
Singleton | DI-owned; lifetime resolved via AwsCredentialMode. |
IQueueUrlCache |
Singleton | Memoizes GetQueueUrlAsync per queue name. |
SqsOptions (and the nested groups Aws, Queues, Location, Resilience, Anonymization) are bindable from IConfiguration and mutable via the fluent SqsOptionsBuilder.
Location enrichment is off by default in v2. Outgoing error reports will have empty UserCity / UserState unless you opt in. When enabled, this feature sends the host's public IP to https://api.ipify.org and https://ipinfo.io to resolve the city and region, and includes that information in error reports published to SQS.
You are responsible for disclosing this to end users in your application's privacy policy. Do not enable this feature in products subject to privacy regulations (GDPR, CCPA, HIPAA) without legal review.
services.AddSqsLogging(sqs => sqs.WithIpInfoLocation());
Activities are emitted on the following sources:
SQS.Transport — raw publish/receive/delete/change-visibility operations.SQS.Publisher — high-level publish methods (PublishAsync, SendLoggingMessageAsync, etc.).SQS.Consumer — high-level receive operations.Location.IpInfo — when location enrichment is opted in.The following metric instruments are emitted via System.Diagnostics.Metrics. All durations are in milliseconds.
| Instrument | Type | Source meter | Tags |
|---|---|---|---|
sqs.publish.duration |
Histogram<double> |
Davasorus.Utility.SQS.Transport |
messaging.destination.name, outcome (ok/fail), error.type (fail only) |
sqs.receive.duration |
Histogram<double> |
Davasorus.Utility.SQS.Transport |
same as above |
sqs.receive.batch_size |
Histogram<int> |
Davasorus.Utility.SQS.Transport |
messaging.destination.name |
sqs.queue_url_cache.hit |
Counter<long> |
Davasorus.Utility.SQS.Transport |
— |
sqs.queue_url_cache.miss |
Counter<long> |
Davasorus.Utility.SQS.Transport |
— |
sqs.dedup.skipped |
Counter<long> |
Davasorus.Utility.SQS.Publisher |
messaging.destination.name |
sqs.deserialize.failed |
Counter<long> |
Davasorus.Utility.SQS.Consumer |
messaging.destination.name, error.type |
error.type carries the fully-qualified exception type name. AWS SDK exception types are bounded, so cardinality stays low even when split per failure mode.
When OpenTelemetry.Instrumentation.AWS is enabled (via TelemetryOptions.Tracing.EnableAws = true in the Davasorus.Utility.DotNet.Telemetry package), the AWS SDK emits its own spans for SQS HTTP calls. These appear as children of the SQS.Transport spans this package emits — package-level spans carry semantic context (queue, dedup id, message group), AWS spans carry wire-level detail (HTTP method, retries, response codes). No configuration is needed; AWS instrumentation parents to Activity.Current automatically.
When TelemetryOptions.Logging.Enabled = true, OpenTelemetry's ILogger provider attaches TraceId, SpanId, and TraceFlags to every LogRecord emitted while an Activity is current. No scope wiring is required — _logger.LogError(...) calls inside SQS publish/receive paths are correlated automatically.
Outbound SQS messages carry traceparent (and tracestate when present) message attributes. On receive, ISqsConsumer.ReceiveAsync<T> parses the producer's traceparent into an ActivityContext and exposes it on ReceivedMessage<T>.ProducerActivityContext. To link your handler's spans to the producer's trace, pass that context as the parent when starting your activity:
foreach (var msg in result.Value!)
{
using var activity = MyActivitySource.StartActivity(
"Handle message",
ActivityKind.Consumer,
msg.ProducerActivityContext ?? default);
// ... process msg.Body, publish follow-ups, etc.
// Spans started inside this `using` block — including any ISqsPublisher.PublishAsync call —
// will be parented to the producer's trace.
await consumer.DeleteAsync(queueName, msg.ReceiptHandle, ct);
}
ReceiveOptions.ContinueTraceContext = false skips the parse and leaves ProducerActivityContext null.
DeleteBatchAsync accepts any number of receipt handles and chunks them internally to SQS's 10-entry-per-request limit. Per-handle outcomes are aggregated into a single BatchDeleteOutcome with Successful and Failed lists that preserve the caller's input order.
| v1 | v2 |
|---|---|
ISqsService.SendLoggingMessage(msg) |
ISqsPublisher.SendLoggingMessageAsync(msg, ct) |
ISqsService.PublishMessage(msg, groupId) |
ISqsPublisher.PublishMessageAsync(msg, new SqsPublishOptions { MessageGroupId = groupId }, ct) |
ISqsClient.PublishAsync(q, msg, groupId) |
ISqsPublisher.PublishAsync(q, msg, new SqsPublishOptions { MessageGroupId = groupId }, ct) |
ILocationService.GetLocationInformation("city") |
ILocationProvider.GetAsync(LocationField.City, ct).ValueOrEmpty() |
MasterUiObj.AnonErrorReporting = true |
SqsOptions.Anonymization.Enabled = true (or register a custom IAnonymizationPolicy) |
new SqsOptionsBuilder().WithLocationCache(ts) |
new SqsOptionsBuilder().WithIpInfoLocation(l => l.CacheLocation(ts)) |
Check return == "error" |
Check result.IsSuccess, inspect result.Error |
UserCity/UserState populated, call .WithIpInfoLocation() during DI setup."error" sentinel preserved on the v1 ISqsService shim — old call sites compile and behave exactly as before. New code should use ISqsPublisher and SqsResult<T>." " to "[user]". Any log parsers searching for the single-space pattern need updating.messaging.url tag is no longer emitted on SQS.Send spans. Dashboards that read queue URLs from spans must derive them from messaging.destination.name plus AWS region.messaging.message_group_id tag is renamed to messaging.aws_sqs.message_group_id. This aligns with OTel v1.28's vendor-specific attribute prefix convention. Dashboards keying off the old name need updating.Every v1 interface is preserved as an [Obsolete] shim over the new API, declared in its v1 namespace. Existing using statements compile unchanged with deprecation warnings pointing at the v2 replacements. Migrate at your own pace.
A hosted-service consumer (long-poll loop, IMessageHandler<T> dispatch, automatic ack/nack with optional DLQ routing) will sit on top of the ISqsConsumer primitives in a future release. The current primitives are designed to be stable under that addition.
AwsCredentialMode.DecryptedKeys)MIT.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 5 NuGet packages that depend on Davasorus.Utility.DotNet.SQS:
| Package | Downloads |
|---|---|
|
Davasorus.Utility.DotNet.Api
API Interaction for TEPS Utilities with generic deserialization, configurable error reporting, and improved DI configuration. Supports REST, GraphQL, gRPC, WebSocket, SignalR, and SSE protocols. |
|
|
Davasorus.Utility.DotNet.SQL
SQL interaction code for TEPS Utilities |
|
|
Davasorus.Utility.DotNet.Services
Windows Service management (start, stop, enable, disable, enumerate) for TEPS Utilities, with OpenTelemetry tracing and DI-based wiring. Targets .NET 8 and .NET 10. |
|
|
Davasorus.Utility.DotNet.Config
Manipulating config file for TEPS Utilities |
|
|
Davasorus.Utility.DotNet.Caching
UCaching for TEPS Utilities |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2026.2.3.3 | 458 | 6/13/2026 |
| 2026.2.3.2 | 657 | 6/12/2026 |
| 2026.2.3.1 | 211 | 6/11/2026 |
| 2026.2.2.9 | 1,671 | 5/31/2026 |
| 2026.2.2.8 | 885 | 5/29/2026 |
| 2026.2.2.7 | 1,033 | 5/25/2026 |
| 2026.2.2.6 | 1,327 | 5/23/2026 |
| 2026.2.2.4 | 1,340 | 5/15/2026 |
| 2026.2.2.3 | 954 | 5/5/2026 |
| 2026.2.2.2 | 1,056 | 5/1/2026 |
| 2026.2.2.1 | 114 | 5/1/2026 |
| 2026.2.1.4 | 149 | 4/30/2026 |
| 2026.2.1.3 | 204 | 4/16/2026 |
| 2026.2.1.2 | 5,558 | 4/9/2026 |
| 2026.2.1.1 | 1,251 | 4/1/2026 |
| 2026.1.3.6 | 691 | 3/29/2026 |
| 2026.1.3.5 | 862 | 3/24/2026 |
| 2026.1.3.4 | 234 | 3/18/2026 |
| 2026.1.3.3 | 1,333 | 3/12/2026 |
| 2026.1.3.2 | 113 | 3/12/2026 |