Skip to content

Pulse v0.2.0-indev.5

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 28 Sep 10:40
· 183 commits to main since this release
7738506

Everything merged since v0.2.0-indev.4. Three points need your attention before or after upgrading; the rest works as it did.

If you followed the Docker commands from an earlier README

The docker run commands in earlier versions of contrib/grafana/README.md and contrib/alerts/README.md started Grafana and Prometheus with host networking, without binding them to loopback, and Grafana with anonymous admin access. That Grafana answers on every interface of the machine, to anyone who can reach port 3000, as an administrator, and Prometheus serves your server's metrics on port 9090 the same way. Stop both containers (docker stop pulse-graf pulse-prom) and start them again with the new commands or the new docker-compose.yml, which bind both to 127.0.0.1 only. To view a remote server's dashboard, use an SSH tunnel; the guide shows how.

Nine runtime series have new names

They now match the standard names Prometheus and Grafana derive from the same .NET instruments over OTLP, so one name serves both paths. If a panel or alert of yours queries one of them, update it:

Before From this version
dotnet_process_memory_working_set dotnet_process_memory_working_set_bytes
dotnet_gc_heap_total_allocated_total dotnet_gc_heap_allocated_bytes_total
dotnet_gc_last_collection_memory_committed_size dotnet_gc_last_collection_memory_committed_size_bytes
dotnet_gc_last_collection_heap_size dotnet_gc_last_collection_heap_size_bytes
dotnet_gc_last_collection_heap_fragmentation_size dotnet_gc_last_collection_heap_fragmentation_size_bytes
dotnet_gc_pause_time_total dotnet_gc_pause_time_seconds_total
dotnet_jit_compiled_il_size_total dotnet_jit_compiled_il_size_bytes_total
dotnet_jit_compilation_time_total dotnet_jit_compilation_time_seconds_total
dotnet_process_cpu_time_total dotnet_process_cpu_time_seconds_total

No pulse_* series changed. The bundled dashboard reads both names for the whole 0.2 line, so it keeps working while you upgrade servers one at a time.

Attribution costs more than earlier notes said

The notes for indev.2 to indev.4 quoted about 0.3% of the tick budget, amortised. That was an estimate from counting profiler marks, and it was too low. Measured on a server with 4000 entities, a profiled tick costs about 26% of the budget. At the new default burst of 10 ticks every 10 seconds, that comes to about 0.9%; the old default of 30 ticks comes to about 2.5%. A pulse.json written by an earlier version keeps its BurstTicks of 30: set it to 10 and run /pulse reload to get the new default. Attribution is still off unless you turn it on.

Metrics endpoint

It is now served from a plain socket instead of .NET's HttpListener:

  • http://localhost:9464/metrics works, whatever Host header the client sends. Linux and macOS used to answer 404 to anything but the exact bind address.
  • On Windows, no administrator rights or netsh reservation are needed.
  • Bind set to 0.0.0.0 works on Linux.
  • Several scrapes are served at once, and each connection has a hard 5 second deadline, so one stalled client no longer holds up the others.
  • If you widen Bind beyond loopback, add a firewall rule limiting the port to your scraper: the endpoint has no authentication, and anyone who can reach it can occupy its connection slots.

Pulse OTLP

  • Export failures are logged now: one Warning per kind of failure, repeated at most every 10 minutes, including the backend's answer when there is one (a wrong Grafana Cloud token shows the 401 and its message). Configured header values and anything shaped like a bearer or basic credential are masked in that line, but treat the log as sensitive when you share it. The first successful export logs one line too, and so does the first one after a failure, so you can see it working and see it recover.
  • Five counter families (engine warnings, player deaths, suspends, suspend seconds, worldgen columns) no longer stay missing from an OTLP-fed dashboard on an idle server.
  • An Endpoint with a query string keeps it; the metrics path used to be appended after the query. The startup line no longer prints credentials or the query string.
  • OpenTelemetry .NET 1.19.1.

Config and attribution

  • A pulse.json or pulse-otlp.json that does not parse (a doubled comma, a missing quote) no longer stops the mod. It logs the file's path and the parser's message, leaves the file as it is, and runs on built-in defaults for that session.
  • The per-mod share no longer keeps showing the last burst's values once attribution stops.
  • The dashboard has an attribution row, and contrib/alerts has a rule for a mod taking more than half of the busy tick time for 10 minutes while the server runs above 80% of its tick budget.

Getting started

docs/getting-started.md walks a server owner from installing the mod to a first dashboard, either locally with Prometheus and Grafana or on Grafana Cloud over OTLP.

Same game support: Vintage Story 1.22.x, dedicated server, .NET 10. Test bar for this tag: 407 tests including 39 embedded-server scenarios, 79 mutations killed, quality gate green, and an end-to-end run of both release zips on a Vintage Story 1.22.7 dedicated server with the bundled Prometheus, Grafana, alert rules and an OTLP receiver.