Valkyrie.Observability 0.1.4

dotnet add package Valkyrie.Observability --version 0.1.4
                    
NuGet\Install-Package Valkyrie.Observability -Version 0.1.4
                    
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="Valkyrie.Observability" Version="0.1.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Valkyrie.Observability" Version="0.1.4" />
                    
Directory.Packages.props
<PackageReference Include="Valkyrie.Observability" />
                    
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 Valkyrie.Observability --version 0.1.4
                    
#r "nuget: Valkyrie.Observability, 0.1.4"
                    
#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 Valkyrie.Observability@0.1.4
                    
#: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=Valkyrie.Observability&version=0.1.4
                    
Install as a Cake Addin
#tool nuget:?package=Valkyrie.Observability&version=0.1.4
                    
Install as a Cake Tool

Valkyrie .NET SDK

Official .NET SDK for Valkyrie observability platform.

Supports logs, errors, metrics, and distributed tracing for ASP.NET Core applications.

Requirements

  • .NET 10.0+

Installation

dotnet add package Valkyrie.Observability

Quick Start

using Valkyrie;

var client = new ValkyrieClient(new ValkyrieOptions
{
    ProjectKey = "sk_your_project_key",
    BaseUrl = "https://api.vlkry.io",
    Environment = "production",
});

// Send logs
client.Log("info", "User logged in", new() { ["user_id"] = 42 });

// Capture exceptions
try { RiskyOperation(); }
catch (Exception ex) { client.CaptureException(ex); }

// Send metrics
client.Metric("api.response_time", 142.5, new() { ["endpoint"] = "/users" });

// Send trace spans
client.Span("GET /api/users", durationMs: 142.5, serviceName: "user-service", statusCode: 200);

// Flush on shutdown
await client.FlushAllAsync();

Tracing Configuration

SDK users can configure tracking behavior:

using Valkyrie;

// Scenario 1: Initial Setup - Track Everything
var client = new ValkyrieClient(new ValkyrieOptions
{
    ProjectKey = "sk_your_project_key",
    BaseUrl = "https://api.vlkry.io",
    Tracing = new TracingConfig
    {
        Enabled = true,
        SampleRate = 1.0,              // Track 100% of requests
        MinDurationMs = 0,            // Track all requests
        SqlMinDurationMs = 0,          // Track all SQL queries
    },
});

// Scenario 2: Production - Track Only Slow Requests
var client = new ValkyrieClient(new ValkyrieOptions
{
    ProjectKey = "sk_your_project_key",
    BaseUrl = "https://api.vlkry.io",
    Tracing = new TracingConfig
    {
        Enabled = true,
        SampleRate = 0.1,              // Track 10% of requests (sampling)
        MinDurationMs = 100,           // Only requests slower than 100ms
        SqlMinDurationMs = 50,        // Only SQL queries slower than 50ms
    },
});

// Scenario 3: High Traffic - Selective Tracking
var client = new ValkyrieClient(new ValkyrieOptions
{
    ProjectKey = "sk_your_project_key",
    BaseUrl = "https://api.vlkry.io",
    Tracing = new TracingConfig
    {
        Enabled = true,
        SampleRate = 0.01,             // Track 1% of requests (very high traffic)
        MinDurationMs = 500,           // Only track very slow requests
        SqlMinDurationMs = 100,        // Only track very slow SQL queries
    },
});

TracingConfig Properties

  • Enabled (bool): Enable/disable tracing. Default: true
  • SampleRate (double): 0.0 to 1.0 (1.0 = 100% of requests tracked). Default: 1.0
  • MinDurationMs (double): Only track requests slower than this (in milliseconds). 0 = track all. Default: 0
  • SqlMinDurationMs (double): Only track SQL queries slower than this (in milliseconds). 0 = track all. Default: 0

ASP.NET Core Integration

// Program.cs
using Valkyrie;

var builder = WebApplication.CreateBuilder(args);

// 1. Create and register client with tracing config
var vlkryClient = new ValkyrieClient(new ValkyrieOptions
{
    ProjectKey = builder.Configuration["Valkyrie:ProjectKey"]!,
    BaseUrl = builder.Configuration["Valkyrie:BaseUrl"]!,
    Environment = builder.Environment.EnvironmentName,
    Tracing = new TracingConfig
    {
        Enabled = true,
        SampleRate = builder.Environment.IsProduction() ? 0.1 : 1.0,
        MinDurationMs = builder.Environment.IsProduction() ? 100 : 0,
        SqlMinDurationMs = builder.Environment.IsProduction() ? 50 : 0,
    },
});
builder.Services.AddSingleton(vlkryClient);

// 2. Add ILogger integration
// Default minimum level is Information — framework Debug/Trace noise is filtered out.
// Raise to Warning if you still see too many logs, or lower to Debug for troubleshooting.
builder.Logging.AddProvider(new ValkyrieLoggerProvider(vlkryClient));
// Optional: send only warnings and above
// builder.Logging.AddProvider(new ValkyrieLoggerProvider(vlkryClient, LogLevel.Warning));

// 3. Auto-trace outgoing HTTP requests
DiagnosticListener.AllListeners.Subscribe(new ValkyrieDiagnosticObserver(vlkryClient));

var app = builder.Build();

// 4. Trace incoming requests as spans
app.UseMiddleware<ValkyrieMiddleware>();

app.MapGet("/", () => "Hello World");
app.Run();

appsettings.json:

{
  "Valkyrie": {
    "ProjectKey": "sk_your_project_key",
    "BaseUrl": "https://api.vlkry.io"
  }
}

Trace Propagation

Trace context is automatically propagated via X-Trace-Id, X-Span-Id, and X-Parent-Span-Id headers.

// Access current trace context
var ctx = ValkyrieContext.Current;
Console.WriteLine(ctx?.TraceId);

// Create child span context
var child = ctx?.NewChild();

// Get headers for outgoing requests
var headers = ctx?.ToHeaders();

SQL Query Tracking

If you are implementing your own SQL query tracking:

var stopwatch = System.Diagnostics.Stopwatch.StartNew();
// ... SQL query execution ...
stopwatch.Stop();
var durationMs = stopwatch.Elapsed.TotalMilliseconds;

// SQL query tracking (tracing config is automatically applied)
client.Span(
    operationName: "db.query",
    durationMs: durationMs,
    serviceName: "postgres",
    tags: new Dictionary<string, string>
    {
        ["db.system"] = "postgresql",
        ["db.query"] = "SELECT * FROM users WHERE id = @id",
    }
);

Log Filtering

ValkyrieLoggerProvider accepts an optional minimumLevel parameter (default: LogLevel.Information).

Framework namespaces (Microsoft.*, System.*, Grpc.*, Hangfire.*, StackExchange.*) are automatically suppressed at Debug/Trace level even when the global minimum is lower. This prevents ASP.NET Core and EF Core internals from flooding the Valkyrie log buffer and hiding your own application logs.

// Default — Information and above; framework noise filtered below Warning
builder.Logging.AddProvider(new ValkyrieLoggerProvider(vlkryClient));

// Only warnings and above from all categories
builder.Logging.AddProvider(new ValkyrieLoggerProvider(vlkryClient, LogLevel.Warning));

// Debug and above (framework namespaces still capped at Warning)
builder.Logging.AddProvider(new ValkyrieLoggerProvider(vlkryClient, LogLevel.Debug));

Structured log properties from message templates are automatically captured as context fields:

// The UserId and OrderId values are captured in Valkyrie's context field
_logger.LogInformation("Order {OrderId} placed by user {UserId}", orderId, userId);

Flush behavior

Data is buffered and sent in batches. By default:

  • BatchSize: 50 (flush when buffer reaches 50 items).
  • FlushIntervalSeconds: 10 (flush every 10 seconds even if the buffer is not full).

So with low traffic, data still appears in Valkyrie within about 10 seconds. Set FlushIntervalSeconds = 0 to disable periodic flush (only flush when the batch is full or on shutdown).

Troubleshooting: no data in Valkyrie

  1. Logs not appearing in the dashboard

    • Make sure ValkyrieLoggerProvider is registered: builder.Logging.AddProvider(new ValkyrieLoggerProvider(vlkryClient));
    • The default minimum level is Information. Logs below this level are dropped. Lower it if you need Debug logs: new ValkyrieLoggerProvider(vlkryClient, LogLevel.Debug).
    • Framework logs (Microsoft.*, System.*, etc.) are intentionally suppressed below Warning to prevent buffer flooding. This is expected behavior.
  2. Configuration not loaded (e.g. .env)

    • ASP.NET Core does not read .env files by default. Configuration["Valkyrie:ProjectKey"] will be null if you only set VALKYRIE__PROJECT_KEY in a .env file.
    • Options: Put Valkyrie:ProjectKey in appsettings.json (or appsettings.Development.json), or load .env at startup (e.g. DotNetEnv: DotNetEnv.Env.Load(); before WebApplication.CreateBuilder(args)), or set real environment variables (systemd, Docker, export).
    • Check: Log at startup whether the client was created, e.g. if (valkyrieClient != null) Log.Information("Valkyrie enabled"); else Log.Warning("Valkyrie disabled (no ProjectKey)");
  3. Tracing filters (Production)

    • If Tracing.MinDurationMs > 0 or Tracing.SampleRate < 1.0, many spans are dropped. For testing, use MinDurationMs = 0 and SampleRate = 1.0.
  4. Low traffic and no periodic flush

    • With older SDK versions, data was only sent when the buffer reached BatchSize (50) or on app shutdown. The SDK now flushes every FlushIntervalSeconds (default 10). Update to the latest SDK or set FlushIntervalSeconds = 10 (or 5) so data appears within a few seconds.
  5. Network / API

    • Ensure the app can reach BaseUrl (e.g. https://api.vlkry.io) and that X-Project-Key is valid. Failed flush is logged to stderr: [Valkyrie] Failed to flush logs: ....

Performance Tips

  1. Initially: Start with SampleRate: 1.0 and MinDurationMs: 0
  2. As traffic increases: Lower SampleRate (e.g., 0.1 or 0.01)
  3. Find slow queries: Set a threshold like SqlMinDurationMs: 50
  4. Production: Typically use SampleRate: 0.1 and MinDurationMs: 100

License

MIT

Product Compatible and additional computed target framework versions.
.NET 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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.4 114 2/19/2026
0.1.3 111 2/17/2026
0.1.2 107 2/17/2026
0.1.1 111 2/12/2026
0.1.0 114 2/8/2026