Server Telemetry
Client-side numbers tell you what users experience under load; server telemetry tells you why. Install the TestVibe agent in the application you are testing and your results gain live server-side CPU, memory, session, and custom metrics — rendered next to the client-side charts.
The metrics appear in two places:
- Load test results — server vitals next to the client-side charts.
- Dashboard → Live Servers — the same vitals streaming in real time while you watch.
The agent only sends data while one of your load runs is active or someone is watching the Dashboard — there is no idle traffic, and it is always best-effort so it can never disturb your application.
What you'll need
- A TestVibe API key (
tvb_…, workspace-scoped) — TestVibe → Settings → CLI & API keys. See API keys. The agent discovers your projects from the key. - The agent for your stack (below). The .NET agent is the
TestVibe.TelemetryNuGet package; it discovers your projects from the API key, so you don't even need a project id.
.NET
Install the package:
dotnet add package TestVibe.Telemetry
It targets netstandard2.0, so it runs on .NET Framework 4.6.1+, .NET Core 2.0+,
and .NET 5–10+. Register it once at startup. The optional SessionCount callback
unlocks Sessions and Memory / session; wire it to whatever represents an
active session in your app.
- ASP.NET Core
- Worker / Generic Host
- Console / daemon
- WinForms / WPF
- Wisej.NET
// Program.cs
using TestVibe;
var builder = WebApplication.CreateBuilder(args);
// ... services ...
var app = builder.Build();
Telemetry.Register(
builder.Configuration["TestVibe:Server"] ?? "https://app.testvibe.com",
builder.Configuration["TestVibe:ApiKey"], // tvb_… from Settings → CLI & API keys
new TelemetryOptions
{
// Optional: report a live count (e.g. active SignalR connections or signed-in users).
SessionCount = () => MyConnectionCounter.Current,
});
app.Run();
// Program.cs (Worker Service, or any Generic Host)
using TestVibe;
var host = Host.CreateApplicationBuilder(args).Build();
Telemetry.Register("https://app.testvibe.com", Environment.GetEnvironmentVariable("TESTVIBE_API_KEY"));
host.Run();
using TestVibe;
class Program
{
static async Task Main()
{
TestVibe.Telemetry.Register("https://app.testvibe.com", "tvb_…");
await RunForeverAsync();
}
}
// Program.cs / App startup
using TestVibe;
[STAThread]
static void Main()
{
TestVibe.Telemetry.Register("https://app.testvibe.com", "tvb_…");
Application.Run(new MainForm());
}
// Program.cs — register once in the static constructor
using TestVibe;
static Program()
{
Telemetry.Register("https://app.testvibe.com", "tvb_…", new TelemetryOptions
{
// Wisej tracks live sessions for you — report the built-in count.
SessionCount = () => Wisej.Web.Application.SessionCount,
});
}
Custom metrics, info & errors
Anywhere in your app:
// Gauges — chart alongside CPU/memory (latest value wins, up to 20 metrics).
TestVibe.Telemetry.ReportMetric("Orders/min", ordersPerMinute);
// Static facts shown in the server card header.
TestVibe.Telemetry.ReportInfo("Region", "westeurope");
// Errors — grouped + persisted under Dashboard → Telemetry → Errors & exceptions.
// Unhandled exceptions are captured automatically; report handled ones too:
try { DoWork(); }
catch (Exception ex) { TestVibe.Telemetry.ReportError(ex); throw; }
Node.js
Node services use the
testvibe-telemetry npm
package (Node 18+, zero dependencies):
npm install testvibe-telemetry
Start it once at boot:
const { startTestVibeLoadAgent } = require('testvibe-telemetry');
const telemetry = startTestVibeLoadAgent({
server: 'https://app.testvibe.com',
apiKey: 'tvb_…', // Settings → CLI & API keys
project: '<your-project-id>', // Settings → Telemetry
sessions: () => myActiveSessions, // optional
});
Uncaught exceptions are captured automatically; report handled errors with
telemetry.reportError(err).
No npm? Copy the single-file agent shown in Settings → Telemetry
(testvibe-load-agent.js — the same file the package installs) into your app
and require './testvibe-load-agent' instead.
Reading server metrics
- CPU climbing toward saturation while latency p95 rises is the classic capacity ceiling — scale up or optimize before raising thresholds.
- Memory growing run-over-run without recovering suggests a leak the load test is exposing; Memory / session isolates whether it's per-session.
- Sessions confirms the load actually produced the concurrency you configured.