NetCrunch Telemetry SDK
Technology Preview. Client libraries for PowerShell, Node.js, Python, Go and .NET that let an application report its own counters, statuses and events to NetCrunch, instead of NetCrunch having to poll for them.
Technology Preview. The libraries are version 0.1 and still developing: interfaces may change between releases, and nothing is published to a package registry yet.
The wire format underneath is not new. It is the format NetCrunch has accepted for years, and changes to it are expected to be additions rather than breaks - so data you send today keeps working.
Why an Application Reports Itself
Polling answers questions from the outside: is the port open, what does this counter read. It cannot answer whether last night's billing run finished, how many connections are open right now, or which phase an importer is in. A job that runs for four minutes at 3am cannot be polled at all - but it can report.
The libraries send to a Telemetry sensor, so everything that arrives inherits the node's alerting, dependencies and dashboards like any other counter. See Węzeł telemetryczny to create the node and its sensor, and @data-sensor for the REST interface the libraries are built on.
The libraries are not an OpenTelemetry replacement. If a system already speaks OTLP, use the OTLP gateway described in Telemetria w NetCrunchu. Use these libraries for the things OTLP cannot express - above all a state, which is what NetCrunch alerts on.
What an Application Can Send
- Counters
- Numbers. Queue depth, requests served, bytes written.
- Statuses
- A state with a message, such as
ErrorwithService not responding. This is what alerting acts on. A counter on its own raises nothing. - Events
- Discrete things that happened, each with a message.
- Data objects
- A table or chart rendered on the sensor page, with no dashboard to configure.
The Dead Man's Switch
This is the main reason to instrument a scheduled job, and it needs no code.
Retain time tells NetCrunch how long values stay live after they arrive. Set it longer than the job's interval. If the job runs and reports, the status refreshes. If the job never runs at all - the scheduler was disabled, the machine was down, the script died early - nothing arrives, the status expires, and NetCrunch alerts on its own.
A polling monitor cannot see this. It has nothing to poll.
For a nightly job, a retain time of 1500 minutes (25 hours) gives a one-hour grace period before the alert.
Installing
Version 0.1.0, Technology Preview. The libraries are not published to npm, PyPI, NuGet or the PowerShell Gallery yet, so install them from the repository: github.com/adremsoft/netcrunch-telemetry
| Language | Requires | Install |
|---|---|---|
| PowerShell | Windows PowerShell 5.1 or PowerShell 7+ | Import-Module .\netcrunch-telemetry\powershell\NetCrunch.Telemetry\NetCrunch.Telemetry.psd1 |
| Node.js | Node 20+, ESM | npm install ./netcrunch-telemetry/js |
| Python | 3.9+ | pip install "git+https://github.com/adremsoft/netcrunch-telemetry#subdirectory=python" |
| Go | 1.21+ | go get github.com/adremsoft/netcrunch-telemetry/go |
| .NET | net8.0, or netstandard2.0 for Framework 4.6.1+ | dotnet add reference <path>\netcrunch-telemetry\dotnet\src\NetCrunch.Telemetry\NetCrunch.Telemetry.csproj |
Go resolves straight from the repository. The others are installed from a local clone, except Python, which pip can fetch from the subdirectory directly.
Every library is dependency-free, apart from .NET on netstandard2.0, and all five pass a shared conformance suite - so each one sends an identical payload.
Quick Start
Each example assumes the sensor endpoint is in the NC_TELEMETRY_URL environment variable. Copy it from the Telemetry sensor form.
PowerShell
Import-Module NetCrunch.Telemetry Connect-NCTelemetry -Endpoint $env:NC_TELEMETRY_URL -RetainMinutes 1500 try { $files = Copy-Backup Set-NCCounter -Object 'Backup' -Counter 'Files Copied' -Value $files Set-NCStatus -Key 'Nightly Backup' -Value 'OK' -Message "$files files" Add-NCEvent -Message 'Nightly backup completed' } catch { Set-NCStatus -Key 'Nightly Backup' -Value 'Error' -Message $_.Exception.Message -Critical } finally { Send-NCTelemetry }
Node.js
import { Telemetry } from "@netcrunch/telemetry"; const stats = new Telemetry({ endpoint: process.env.NC_TELEMETRY_URL, flushSeconds: 60, }); const pending = stats.counter("Queue", "Depth", "inbound"); pending.inc(); stats.status("Importer", "OK", { message: "batch 41/120" }); stats.event("Nightly import completed"); await stats.close();
Python
from netcrunch_telemetry import Telemetry with Telemetry(os.environ["NC_TELEMETRY_URL"], retain_minutes=1500) as stats: stats.counter("HTTP", "Requests").inc() stats.status("Importer", "OK", message="batch 41/120") stats.event("Nightly import completed")
An AsyncTelemetry class provides the same interface for asyncio. Staging is identical because none of it does I/O - only flushing differs.
Go
import telemetry "github.com/adremsoft/netcrunch-telemetry/go" stats, err := telemetry.New(telemetry.Options{ Endpoint: os.Getenv("NC_TELEMETRY_URL"), FlushInterval: time.Minute, }) if err != nil { log.Fatal(err) } defer stats.Close(context.Background()) requests := stats.MustCounter("HTTP", "Requests", "") requests.Inc() stats.Status("Importer", "OK", telemetry.StatusOptions{Message: "batch 41/120"}) stats.Event("Nightly import completed")
.NET
using NetCrunch.Telemetry; await using var stats = new Telemetry(new TelemetryOptions { Endpoint = Environment.GetEnvironmentVariable("NC_TELEMETRY_URL")!, FlushInterval = TimeSpan.FromMinutes(1), }); var requests = stats.Counter("HTTP", "Requests"); requests.Increment(); stats.Status("Importer", "OK", message: "batch 41/120"); stats.Event("Nightly import completed");
await using matters here: disposing asynchronously stops the flush loop and sends what is still staged, while the synchronous Dispose only stops the loop.
Authentication
If the Telemetry sensor has a bearer token set, pass it when you connect and the library sends it on every request:
| Language | Option |
|---|---|
| PowerShell | Connect-NCTelemetry -Token <token> |
| Node.js | new Telemetry({ endpoint, token }) |
| Python | Telemetry(url, token=token) |
| Go | telemetry.Options{ Token: ... } |
| .NET | TelemetryOptions { Token = ... } |
The token belongs in the configuration, never in the endpoint URL. See @data-sensor for how to set it on the sensor and what the server returns when it is wrong.
How Sending Works
A counter is a handle, not a call. Resolving a counter returns a handle you keep, and resolving the same one again returns the same handle. The hot path is a numeric mutation - no name lookup, no allocation per observation. Instrumentation that costs more than that gets removed again.
Instrumentation only touches memory. A separate flush takes a snapshot and sends absolute current values, so nothing in a request path does I/O.
Sending is idempotent. A payload carries absolute values rather than increments, so a retry after a timeout cannot double-count. The libraries retry transport failures and 5xx responses automatically, and never retry a 4xx, because repeating a rejected request cannot change the answer. See @data-sensor for what each response code means.
One payload carries everything. The receiver caps pending payloads per sensor and discards the overflow silently, so a program that posted once per value would lose data without being told. Stage values and let the flush send them together.
Zero is a measurement. Once a counter is resolved it keeps appearing in every payload, including at zero, until you discard it. An absent counter is how NetCrunch expires data - so omitting zeroes would make an idle pool look identical to a crashed one.
Lifetime-Bound Aggregates
Available in Node.js, Python, Go and .NET, these answer "how many X are currently in state Y" correctly by construction, because the decrement is tied to an object's lifetime rather than to a line someone has to remember to write:
- SelfCount
- Adds 1 when created, subtracts 1 when disposed.
- PartCount
- Contributes a movable amount, and withdraws exactly its own contribution on disposal, whatever the counter has done in the meantime.
- CategoryCount
- Holds 1 against one instance of a counter at a time, so moving a worker from
parsingtowritingdecrements one bucket and increments the other in a single call.
They rely on the deterministic disposal each language offers: defer in Go, IDisposable in .NET, context managers in Python, using in JavaScript. Disposal is idempotent, and disposing an aggregate leaves its counter reporting zero rather than removing it.
Specification and Conformance
The wire format is specified in spec/v1.md, and the in-memory behavior every library shares in spec/client-model.md. The conformance suite under conformance/ is the executable version of both - each language runs the same fixtures, which is what keeps the payloads identical.
Known gaps are listed per language in the README of each folder.
- Natywne Format Data NetCrunch
Jak NetCrunch przetwarza dane telemetryczne zewnętrzne i konwertuje je na liczniki i obiekty statusu, używając natywnych formatów JSON, XML i CSV
- Monitoring with Telegraf
Use Telegraf, the open-source metrics agent, to collect from systems NetCrunch does not poll directly and push the results into NetCrunch as ordinary counters and statuses.
- Monitorowanie Linux Sysctl Filesystem za pomocą Telegraf w NetCrunch
Ten temat wyjaśnia, jak monitorować parametry systemu plików jądra Linux za pomocą Telegraf i wysyłać zebrane metryki do NetCrunch Telemetry Nodes. Wtyczka wejściowa Linux Sysctl Filesystem odczytuje wartości z katalogu proc sys fs i przekazuje je do NetCrunch za pomocą wtyczki wyjściowej HTTP.
- Telemetria MQTT za pośrednictwem Telegraf w NetCrunch
Ten temat wyjaśnia, jak zbierać metryki systemowe publikowane za pośrednictwem MQTT, przetwarzać je przy użyciu Telegraf oraz przekazywać do punktu końcowego NetCrunch Telemetry Node jako dane telemetryczne w formacie JSON.
- Monitorowanie SQL Server za pośrednictwem Telegraf w NetCrunch
Ten temat wyjaśnia, jak skonfigurować Telegraf do zbierania metryk Microsoft SQL Server i przekazywania ich do punktu końcowego NetCrunch Telemetry Node przy użyciu danych telemetrycznych opartych na JSON. Obejmuje konfigurację logowania do SQL Server, parametry połączeń, konfigurację wejścia Telegraf oraz obsługiwane typy metryk.
- Monitorowanie zasobów Azure za pomocą Telegraf w NetCrunch
Ten dokument opisuje sposób konfigurowania Telegraf w celu zbierania metryk z różnych zasobów Azure (takich jak Virtual Machines, Storage Accounts i Databases) oraz wysyłania ich do NetCrunch za pośrednictwem punktu końcowego Telemetry Node.