Ripteq.Ledger.Client 1.1.0

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

Ripteq.Ledger.Client

Report unattended work to Ripteq Ledger: overnight jobs, scheduled functions, background processes. Ledger raises an incident when a run fails and when a run that should have happened did not — the job that should have run at 02:00 and wrote nothing to any log.

The rule this package is built on

The SDK never throws into your job, and it never blocks it. A Ledger outage, a network failure, a revoked key: every one of them goes to your own ILogger and nowhere else. Nothing on your code's path waits for the network — every call enqueues and returns, and one background pump does the rest.

An outage is also quiet. After five failures in a row the sender pauses, so a Ledger that is down does not turn into a failed dependency per event in your telemetry or a warning a minute in your logs. It resumes by itself: the first event after the cooldown is the probe.

Install

dotnet add package Ripteq.Ledger.Client

Use it

With a container:

services.AddLedgerClient(o =>
{
    o.BaseAddress = configuration["Ledger:BaseAddress"];   // https://ledger.example.com
    o.ApiKey      = configuration["Ledger:ApiKey"] ?? "";  // issued per application + environment
});

Without one — a console application with no IHostBuilder:

await using var ledger = new LedgerClient(
    new HttpClient(),
    new LedgerClientOptions { BaseAddress = "https://ledger.example.com", ApiKey = key });

Wrap the work

TrackAsync is the shortest form, and the only one that reads the outcome from your code:

await ledger.TrackAsync("tm.datawarehouse.nightly", async ct =>
{
    await LoadStagingAsync(ct);
});

No exception is Success, an OperationCanceledException is Cancelled, anything else is Failure with the message — and the exception is always rethrown, so your own behaviour does not change.

Or hold the scope

await using var run = await ledger.StartRunAsync("tm.datawarehouse.nightly");

run.Metric("RowsProcessed", 1523);
run.Log(RunLogLevel.Information, "Staging complete", new { batch = "2026-08-29" });

run.Succeeded();          // dispose assumes Success; say otherwise with Failed(ex) or Cancelled()

Dispose cannot see an in-flight exception — C# gives IAsyncDisposable no view of one — so a scope that ends untold reports Success. Use TrackAsync when you want the outcome inferred.

Start-and-finish, rather than one call, is right for anything that could be long: Ledger needs a Running row to notice a job that hangs.

Short jobs, and processes with no runs

ledger.CompleteRun("tm.exports.hourly", RunOutcome.Success, startedUtc);   // reported after the fact
ledger.Heartbeat("tm.listener");                                          // liveness, no run

Capture your own log lines

Opt in, and every line your job writes inside a run scope travels with the run:

builder.Logging.AddLedgerLogCapture();

Azure Functions

Ripteq.Ledger.Client.Functions reports every invocation with no per-function code:

builder.UseLedger();

What it does when Ledger is not there

Situation What happens
Server unreachable, 5xx, or a timeout 3 attempts with jittered backoff, then one log line and the event is dropped
429 Retried, honouring Retry-After
400 or any other 4xx Not retried. One log line
401 The sender stops. One log line. Nothing further is sent, so a revoked key cannot become a flood
5 failures in a row The sender pauses for 30 seconds, doubling to at most 5 minutes. One log line. Events are dropped and counted rather than attempted, so a long outage costs your process nothing. The first event after the cooldown probes, and a success resumes it
No BaseAddress configured The sender stops before it opens a socket. One log line, and no HTTP call is ever made
Queue full The oldest item is dropped and counted. Your job is never blocked
Shutdown Flushed for at most 5 seconds, then abandoned. A shutdown never waits on Ledger
A run's start is lost Its finish is re-sent as a one-shot with the same externalRunId, so the outcome still arrives

ListFunctionsAsync is the only call that waits on your thread, because it returns a value. It has a 15-second budget of its own and answers with an empty list rather than throwing.

The events dropped during a pause are not a gap in your monitoring. Ledger watches for silence, so a client that stops reporting is exactly what raises an incident — once Ledger is answering again.

ILedgerClient.Diagnostics carries Sent, Dropped, Failed, Stopped and PausedUntil. Log it if a client that has quietly stopped reporting would matter to you.

Targets

net8.0 and net10.0.

Licence

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

Showing the top 1 NuGet packages that depend on Ripteq.Ledger.Client:

Package Downloads
Ripteq.Ledger.Client.Functions

Azure Functions isolated-worker middleware for Ripteq Ledger. Register it once and every invocation reports a run, with no per-function code.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 105 9/1/2026
1.0.0 101 9/1/2026