Davasorus.Utility.DotNet.SQS 2026.2.2.7

There is a newer version of this package available.
See the version list below for details.
dotnet add package Davasorus.Utility.DotNet.SQS --version 2026.2.2.7
                    
NuGet\Install-Package Davasorus.Utility.DotNet.SQS -Version 2026.2.2.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Davasorus.Utility.DotNet.SQS" Version="2026.2.2.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Davasorus.Utility.DotNet.SQS" Version="2026.2.2.7" />
                    
Directory.Packages.props
<PackageReference Include="Davasorus.Utility.DotNet.SQS" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Davasorus.Utility.DotNet.SQS --version 2026.2.2.7
                    
#r "nuget: Davasorus.Utility.DotNet.SQS, 2026.2.2.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Davasorus.Utility.DotNet.SQS@2026.2.2.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Davasorus.Utility.DotNet.SQS&version=2026.2.2.7
                    
Install as a Cake Addin
#tool nuget:?package=Davasorus.Utility.DotNet.SQS&version=2026.2.2.7
                    
Install as a Cake Tool

Davasorus.Utility.DotNet.SQS

Overview

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.

Features

  • 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.
  • W3C traceparent injection on publish, extraction on receive — end-to-end OpenTelemetry traces flow through SQS message attributes automatically.
  • Three AWS credential modes — decrypted-key (v1 behavior), AWS SDK credential chain (modern default for new apps), or supply your own IAmazonSQS.
  • Three location-enrichment modes — off (default), ipify.org + ipinfo.io over HTTPS with Polly resilience, or supply your own ILocationProvider.
  • Owned anonymization & dedup stateIAnonymizationPolicy + IReportedErrorTracker replace v1's reads of MasterUiObj.AnonErrorReporting and TrelloErrorReportingObjs.Collection.
  • Singleton 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.

Quick start

// 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
            ;
    }
}

Configuration

Fluent

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.json

services.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
    }
  }
}

Hybrid

services.AddSqsLogging(
    builder.Configuration.GetSection("SqsOptions"),
    sqs => sqs.WithRegion("ap-southeast-2"));   // fluent overrides config

Custom IAmazonSQS

services.AddSingleton<IAmazonSQS>(_ => new AmazonSQSClient(creds, myConfig));
services.AddSqsLogging(sqs => sqs.WithCustomClient());

Custom ILocationProvider

services.AddSingleton<ILocationProvider, MyInternalLocationProvider>();
services.AddSqsLogging(sqs => sqs.WithCustomLocationProvider());

Public surface

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.

Enabling Location Enrichment (opt-in)

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());

Telemetry

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.

Metrics

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.

AWS SDK instrumentation parenting

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.

Log/trace correlation

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.

Batch-delete behavior

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.

Migration from v1

Mapping table

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

Behavior changes to verify after upgrade

  1. Location enrichment defaults to off. If error reports need UserCity/UserState populated, call .WithIpInfoLocation() during DI setup.
  2. "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>.
  3. Scrubbed username replacement changed from " " to "[user]". Any log parsers searching for the single-space pattern need updating.
  4. The 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.
  5. The 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.

Continuing to use the v1 surface

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.

Future work

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.

Dependencies

  • AWSSDK.SQS
  • Davasorus.Utility.DotNet.Contracts.Types / .Collections
  • Davasorus.Utility.DotNet.Encryption (only used by AwsCredentialMode.DecryptedKeys)
  • Davasorus.Utility.DotNet.Telemetry
  • Microsoft.Extensions.{Caching.Memory, Http, Http.Resilience, Logging.Abstractions, Options}

License

MIT.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (6)

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

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2026.2.2.9 0 5/31/2026
2026.2.2.8 163 5/29/2026
2026.2.2.7 395 5/25/2026
2026.2.2.6 1,014 5/23/2026
2026.2.2.4 1,336 5/15/2026
2026.2.2.3 952 5/5/2026
2026.2.2.2 1,049 5/1/2026
2026.2.2.1 110 5/1/2026
2026.2.1.4 146 4/30/2026
2026.2.1.3 198 4/16/2026
2026.2.1.2 4,653 4/9/2026
2026.2.1.1 1,246 4/1/2026
2026.1.3.6 687 3/29/2026
2026.1.3.5 859 3/24/2026
2026.1.3.4 229 3/18/2026
2026.1.3.3 1,330 3/12/2026
2026.1.3.2 109 3/12/2026
2026.1.3.1 595 3/10/2026
2026.1.2.4 1,630 2/17/2026
2026.1.2.2 743 2/13/2026
Loading failed