rkallos
Peep is a new TelemetryMetrics reporter that supports both StatsD (and Dogstatsd) and Prometheus.
While load testing a new Websocket-based API gateway written in Elixir, I encountered performance issues with TelemetryMetricsPrometheus.Core and TelemetryMetricsStatsd. This prompted me to write Peep, which makes different choices about storing and sending TelemetryMetrics data.
- Instead of sampling or on-demand aggregation, Peep uses histograms (backed by
:ets.update_counter/*) to store distributions, copying the approach taken by DDSketch. - Instead of sending StatsD packets for each telemetry event, StatsD data is periodically sent in a small(er) number of large(r) packets.
This library is currently running in production, in a service handling >1 million requests per minute. With a moderate number of metrics defined, the service emits StatsD data at a rate of 4KiB/s, with no observed packet drops (we use Unix Domain Sockets to send Dogstatsd lines to Datadog agents, so it’s possible for :gen_udp to return :eagain when attempting to send packets).
Here’s an image showing a drop in CPU use after replacing TelemetryMetricsPrometheus.Core and TelemetryMetricsStatsd with Peep:
Here’s another dashboard for the same period of time, showing a slight (but not unwelcome!) drop in memory usage:
Feedback and contributions welcome!
Trending in Announcing
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #hex
- #security












Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
rkallos
Peep v2.0.0 has been released!
This version fixes an issue with exposing data for Prometheus. If you use Peep with Prometheus, you should upgrade to this version.
Changes
distribution_bucket_variabilityoption was removed.Custom bucket boundaries
With Peep 2.0.0, the default log-linear bucketing strategy becomes an implementation of the new
Peep.Bucketsbehavior.You can use the
Peep.Buckets.Custommodule to define your own bucket boundaries. This compiles to efficient pattern matching with function heads, which ought to scale better than traversing a list.Here’s an example of using
Peep.Buckets.Custom:If you want something more involved, you can implement the callbacks for the
Peep.Bucketsbehaviour. For an example, look atPeep.Buckets.Exponential.hauleth
Thank you for that project. It allowed me to give Supavisor ~30x boost in latency (measured by
pgbench) over usingtelemetry_metrics_prometheus_core. I also have prepared PR forprom_exto be able to usepeepas a metrics store.v0idpwn
That’s awesome!
I’m curious about how much impact it would have in my application, but I think can’t afford to test it right now, as it would be a pretty big change (we have a lot of
Telemetry.Metrics.summary/2), which Peep doesn’t support.Did you measure the impact of
Telemetry.Metricsbeforehand? Something like fprof? If you could please share, it could help me a lotrkallos
Peep v3.0.0 has been released!
This version introduces a slight change in how Peep is configured (replacing keyword lists for maps in the
global_tagsoption) that is not backwards compatible. Upgrading from v2.x.y will require making some small changes.Thanks @hauleth for your contributions!
Changes
:math.log(gamma)for a slight performance boost inPeep.Buckets.Exponentialrkallos
Peep v3.1.0 has been released!
Thanks to another contribution by @hauleth, it is now possible to override the type of a ‘sum’ or ‘last value’ metric in the Prometheus exposition.
For example, if you want to track socket statistics, which are often pre-summed, you could store the data in peep with
last_value/2, but report it as acounter-type metric in the Prometheus output.rkallos
I haven’t made many announcements here in a while, but I’ve published a few new Peep versions. Thank you to @aloukissas and @mjm for your contributions!
Peep v3.2.0
@aloukissas added Peep.Plug, an easy way to expose Peep metrics.
Peep v3.2.1
While encountering an issue with Peep receiving unexpected messages when sending StatsD data via Unix Domain Sockets, @mjm changed Peep processes to ignore unxpected messages, and ignore the shutdown reason when terminating.
Peep v3.3.0
Upon request by my employer, I introduced a new storage engine for Peep metrics that trades reduced lock contention for increased memory usage;
:striped. Rather than storing all metrics in a single ETS table,:stripeduses one ETS table for each scheduler thread.I don’t exactly recommend that users switch to this storage method unless they are noticing lock contention, which may happen when handling thousands and thousands of metrics of telemetry executions.
Here’s some :lcnt output from a bidder service for RTB ads:
Before:
After:
firesidewing
Sorry if this is the wrong place to put this but I feel like I’m doing something dumb when setting this up.
Whenever I have the plug in my endpoint.ex file for a phoenix project before my router, only the metrics route matches and all the other routes show 404. If I put it after my router, all my routes show but I get a 404 for /metrics. I feel like I have the worker set up fine and everything else but setting up the plug I feel like I’m missing something.
rkallos
Hey! Not at all the wrong place to post. You found a bug in Peep
When adding Peep.Plug to a Phoenix project, I find myself using the following:
Note that, for the time being, you may need to specify the path twice if you want to use a path other than “/metrics”:
That should address your immediate issue.
I’ll improve the documentation in Peep.Plug to reflect this, and I might change some of the code in there, such as not responding with 404 when the URL path does not match the metrics endpoint. While that code is easier to test, and makes sense when serving the metrics endpoint on a different port, the default behavior is confusing.
firesidewing
Hey, thanks for the fast reply! I’ll give that a go when I can but makes sense to me
rkallos
I missed posting a few minor releases of Peep in the past few months, but today, Peep 4.0.0 was released.
Upgrading from 3.x should be straightforward, as the only backwards-incompatible change made is that you can no longer store non-integer values in last-value metrics. You may have somehow gotten away with it in earlier versions of Peep, but it won’t work anymore.
Here’s a changelog of releases from Peep 3.3.1 to 4.0.0:
v3.3.1
:on_unmatched_pathto Peep.Plug, allowing for users to decide the behaviour when Plug.Peep is called with an unexpected path. In short, you probably want:continueif serving Peep metrics from the same HTTP server as your application (e.g. in a Phoenix-based service), and:haltwhen serving Peep metrics from a separate listener (e.g. when you want to serve metrics on a different port)v3.4.0
:bucket_calculatoroption to Peep, making it possible to globally specify a Peep.Buckets implementation for all distribution metrics.v3.4.1
v3.4.2
v3.5.0
Peep.prune_tags/2, which deletes metrics based on matching tag values. This is useful for metrics with unavoidable high cardinality, but may not be all that useful for more typical users of Peep.v4.0.0
:tagsfor every metric. Thanks to @yordisprieto for pointing this out, and pointing out the fix.Peep v4.0.0 appears to be quite a bit faster than v3.x. Here’s a chart showing p50, p95, and p99 latency before and after deployment of Peep 4.0.0 in an application that uses Peep heavily:
Thanks to those who contributed to Peep these past few months. With your help, Peep is now better than ever!