fiber_metrics
Fiber metrics
Track run time, wait time or memory allocations per Fiber
, method or block.
- Designed for low overhead use in production
- Fast. Shared nothing (when possible)
- Simple. 0 configuration
This shard is modular
| require
| |
| --- | --- |
| fiber_metrics/all
| Batteries included. Start here |
| fiber_metrics
| Requires the minimum necessary to run with the lowest overhead |
TODO
- [x]
Channel.send,recv
- [ ]
sleep
- [x]
Mutex
- [x]
IO
- [ ] Hook in to
Scheduler
- [ ] ENV to control printing
Installation
-
Add the dependency to your
shard.yml
:dependencies: fiber_metrics: github: didactic-drunk/fiber_metrics.cr
-
Run
shards install
Usage
require "fiber_metrics/all"
class Example
# Must be included in each class containing a `@[Measure]` annotation **including subclasses**
include Fiber::Metrics
@[Measure]
def foo
bar
sleep 0.2
Bytes.new 16384
end
@[Measure]
def bar
baz
sleep 0.2
Bytes.new 32768
end
@[Measure]
def baz
sleep 0.2
Bytes.new 65536
end
end
e = Example.new
e.foo
Fiber.print_stats
Example Output
┌───────┬───────┬───────┬───────┬───────┬───────┬───────┐
│ Calls │ IdleT │ BlkT │ RunT │ Total │ Mem │ Name │
├───────┼───────┼───────┼───────┼───────┼───────┼───────┤
│ 1 │ │ │ 0.209 │ 0.209 │ 64K │ C.baz │
│ 1 │ │ │ 0.205 │ 0.414 │ 32K │ C.bar │
│ 1 │ │ │ 0.204 │ 0.622 │ 16K │ C.foo │
└───────┴───────┴───────┴───────┴───────┴───────┴───────┘
Output is best viewed with [less -RS
, bat --wrap=never
]
| Column | Description |
| --- | --- |
| IdleT | Time idle. Channel.recv
, IO.read
, etc |
| BlkT | Time blocked. Channel.send
, IO.write
, etc |
| RunT | RunTime: Time spent within the measured method - [idle, blk], but not sub measured methods |
| Total | Total elapsed time including sub measured methods |
| Mem | Memory Allocated |
How it works
@[Measure]
wraps each method in (2) Time.monotonic
calls and records the difference.
The collected metrics use Fiber local storage (no locking) until the first measured call returns after which the local metrics are merged with a global set of metrics wrapped in a Mutex.
This means metrics are unavailable via Fiber.stats
until the first measured method foo
returns.
This is ideal for
- Applications that show/record stats before exit
- Request/response (HTTP, message queue, etc) type servers that want periodic snapshots of activity
@[Measure] Logic
@[Measure]
def foo
# Time.monotonic
bar
# Time.monotonic
# Store metrics in fiber local storage
# Merge fiber local metrics with global metrics
# Reset fiber local metrics
end
@[Measure]
def bar
# Time.monotonic
baz
# Time.monotonic
# Store metrics in fiber local storage
end
@[Measure]
def baz
# Time.monotonic
...
# Time.monotonic
# Store metrics in fiber local storage
end
More options to control the merging process may appear after use cases are discussed. Open a discussion if the current behavior doesn't fit your needs.
Contributing
- Fork it (https://github.com/didactic-drunk/fiber_metrics.cr/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Contributors
- Didactic Drunk - creator and maintainer