Official .NET SDK for LogTide with automatic batching, retry logic, circuit breaker, W3C distributed tracing, span tracking, breadcrumbs, and ASP.NET Core middleware support.
- Automatic batching with configurable size and interval
- Retry logic with exponential backoff
- Circuit breaker pattern for fault tolerance
- W3C traceparent distributed tracing
- Span tracking with OpenTelemetry-compatible export
- AsyncLocal scope for ambient trace context
- Breadcrumbs for event tracking within a scope
- Composable transport layer (LogTide HTTP, OTLP)
- Integration system (global error handler, extensible)
- Serilog sink (
LogTide.SDK.Serilog) - DSN connection string support
- ASP.NET Core middleware with sensitive header filtering
- Query API for searching and filtering logs
- Dependency injection with
IHttpClientFactory - Full async/await support
- Thread-safe
- .NET 8.0 or .NET 9.0
dotnet add package LogTide.SDKFor Serilog integration:
dotnet add package LogTide.SDK.Serilogusing LogTide.SDK.Core;
using LogTide.SDK.Models;
// Create client with DSN
await using var client = LogTideClient.FromDsn("https://lp_your_key@api.logtide.dev");
// Send logs
client.Info("api-gateway", "Server started", new() { ["port"] = 3000 });
client.Error("database", "Connection failed", new Exception("Timeout"));
// Use scoped tracing
using (var scope = LogTideScope.Create())
{
client.Info("api", "Request received"); // automatically gets W3C trace ID
client.Info("db", "Query executed"); // same trace ID
}using LogTide.SDK.Core;
using LogTide.SDK.Middleware;
using LogTide.SDK.Models;
var builder = WebApplication.CreateBuilder(args);
// Register LogTide with IHttpClientFactory
builder.Services.AddLogTide(new ClientOptions
{
ApiUrl = builder.Configuration["LogTide:ApiUrl"]!,
ApiKey = builder.Configuration["LogTide:ApiKey"]!,
ServiceName = "my-api",
GlobalMetadata = new() { ["env"] = builder.Environment.EnvironmentName }
});
var app = builder.Build();
// Catch unhandled exceptions
app.UseLogTideErrors();
// Auto-log HTTP requests with W3C traceparent support
app.UseLogTide(o => o.ServiceName = "my-api");
app.MapGet("/", (ILogTideClient logger) =>
{
logger.Info("my-api", "Hello!");
return Results.Ok();
});
app.Run();The middleware automatically:
- Parses incoming
traceparentheaders (W3C standard) - Creates a
LogTideScopeper request - Starts and finishes a span per request
- Emits
traceparentresponse header - Filters sensitive headers (
Authorization,Cookie, etc.)
using var scope = LogTideScope.Create();
var span = client.StartSpan("process-order");
span.SetAttribute("order.id", "ORD-123");
// ... do work ...
span.AddEvent("validation-complete");
client.FinishSpan(span, SpanStatus.Ok);Spans are exported in OTLP format to /v1/otlp/traces.
using var scope = LogTideScope.Create();
client.AddBreadcrumb(new Breadcrumb { Message = "User clicked button", Type = "ui" });
client.AddBreadcrumb(new Breadcrumb { Message = "API call started", Type = "http" });
// Breadcrumbs are automatically attached to logs within this scope
client.Error("app", "Something failed");using LogTide.SDK.Serilog;
await using var logtideClient = LogTideClient.FromDsn("https://lp_key@api.logtide.dev");
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.LogTide(logtideClient, serviceName: "my-service")
.CreateLogger();
Log.Information("User {UserId} logged in", 42); // forwarded to LogTide| Option | Type | Default | Description |
|---|---|---|---|
ApiUrl |
string |
required | Base URL of your LogTide instance |
ApiKey |
string |
required | Project API key (starts with lp_) |
Dsn |
string? |
null |
DSN string (alternative to ApiUrl + ApiKey) |
ServiceName |
string |
"app" |
Service name for tracing |
BatchSize |
int |
100 |
Logs to batch before sending |
FlushIntervalMs |
int |
5000 |
Auto-flush interval in ms |
MaxBufferSize |
int |
10000 |
Max buffer size (drop policy) |
MaxRetries |
int |
3 |
Retry attempts on failure |
RetryDelayMs |
int |
1000 |
Initial retry delay (exponential backoff) |
CircuitBreakerThreshold |
int |
5 |
Failures before opening circuit |
CircuitBreakerResetMs |
int |
30000 |
Time before retrying after circuit opens |
TracesSampleRate |
double |
1.0 |
Sample rate for traces |
Integrations |
List<IIntegration> |
[] |
Integrations to register |
GlobalMetadata |
Dictionary |
{} |
Metadata added to all logs |
Debug |
bool |
false |
Enable debug logging to console |
SetTraceId(),GetTraceId(),WithTraceId(),WithNewTraceId()removed — useLogTideScope.Create(traceId)LogTideMiddlewareOptions.Clientremoved — client resolved from DI- Default trace header:
X-Trace-Idreplaced by W3Ctraceparent - Target frameworks:
net8.0;net9.0(dropped net6/net7) LogTideClientis nowsealed, implementsILogTideClientLogEntryhas new optional fieldsSpanId,SessionId
See the examples/ directory for complete working examples.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
MIT License - see LICENSE for details.
