2024-03-01 12:47:09 -03:00
chroprof - Profiling for [Chronos ](https://github.com/status-im/nim-chronos )
============================================================================
2024-03-01 18:55:09 -03:00
This repo contains a usable profiler for [Chronos ](https://github.com/status-im/nim-chronos ). For the time being, it requires [a modified version of Chronos V4 ](https://github.com/codex-storage/nim-chronos/tree/feature/profiler-v4 ) which has profiling hooks enabled. Some of the rationale for the design and implementation of the profiler [can be found here ](https://hackmd.io/eQ_ouNV4QZe0TG334_gkFg ).
2024-03-01 12:47:09 -03:00
2024-03-01 13:23:41 -03:00
1. [Enabling profiling ](#enabling-profiling )
2. [Looking at metrics ](#looking-at-metrics )
2. [Enabling profiling with Prometheus metrics ](#enabling-profiling-with-prometheus-metrics )
3. [Limitations ](#limitations )
2024-03-01 12:47:09 -03:00
## Enabling Profiling
2024-03-01 15:09:10 -03:00
**Compile-time flag.** Profiling requires the `-d:chronosProfiling` compile-time
flag. If you do not pass it, importing `chroprof` will fail.
**Enabling the profiler.** The profiler must be enabled per event loop thread.
To enable it, you need to call, from the thread that will run your event loop:
2024-03-01 12:47:09 -03:00
```nim
import chroprof
enableProfiling()
```
## Looking at Metrics
At any time during execution, you can get a snapshot of the profiler metrics
2024-03-01 15:09:10 -03:00
by calling `getMetrics()` . This will return a [`MetricsTotals` ](https://github.com/codex-storage/nim-chroprof/blob/master/chroprof/profiler.nim#L61 ) object which
2024-03-01 13:23:41 -03:00
is a table mapping [`FutureType` ](https://github.com/codex-storage/nim-chroprof/blob/master/chroprof/profiler.nim#L13 )s to
[`AggregateMetrics` ](https://github.com/codex-storage/nim-chroprof/blob/master/chroprof/profiler.nim#L17 ). You may then
print, log, or do whatever you like with those, including [export them to Prometheus ](#enabling-profiling-with-prometheus-metrics ).
2024-03-01 12:47:09 -03:00
`getMetrics()` will return the metrics for the event loop that is running
(or ran) on the calling thread.
## Enabling profiling with Prometheus metrics
You can export metrics on the top-`k` async procs that are occupying the event
2024-03-01 13:23:41 -03:00
loop thread the most by enabling the profiler's [nim-metrics ](https://github.com/status-im/nim-metrics/ ) collector:
2024-03-01 12:47:09 -03:00
```nim
import chroprof/collector
# Exports metrics for the 50 heaviest procs
enableProfilerMetrics(50)
```
2024-03-01 13:23:41 -03:00
with the help of [Grafana ](https://grafana.com/ ), one can visualize and readily identify bottlenecks:

the cumulative chart on the left shows that two procs (with the bottom one
turning out to be a child of the top one) were dominating execution time at a
certain point, whereas the one on the right shows a number of peaks and anomalies
which, in the context of a bug, may help identify the cause.
## Limitations
* Nested `waitFor` calls are not supported;
* Prometheus metrics only work with `refc` because nim-metrics only works with `refc` ;
* the Prometheus metrics collector can only be enabled for one event loop; i.e.,
you cannot have multiple loops in different threads publishing metrics to Prometheus.