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
<PackageReference Include="Ripteq.Ledger.Client" Version="1.1.0" />
<PackageVersion Include="Ripteq.Ledger.Client" Version="1.1.0" />
<PackageReference Include="Ripteq.Ledger.Client" />
paket add Ripteq.Ledger.Client --version 1.1.0
#r "nuget: Ripteq.Ledger.Client, 1.1.0"
#:package Ripteq.Ledger.Client@1.1.0
#addin nuget:?package=Ripteq.Ledger.Client&version=1.1.0
#tool nuget:?package=Ripteq.Ledger.Client&version=1.1.0
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 | Versions 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. |
-
net10.0
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options (>= 8.0.2)
-
net8.0
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options (>= 8.0.2)
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.