• Stars
    star
    295
  • Rank 135,437 (Top 3 %)
  • Language
    Elixir
  • License
    MIT License
  • Created over 6 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simple and Fast metrics for Elixir

Instruments: Simple, powerful and fast metrics for Statsd and DataDog

CI Hex.pm Version Hex.pm License HexDocs

You're blind without metrics. Metrics should also be easy to add to you application and have little performance impact. This module allows you to define metrics with ease and see inside your application.

Instruments has the following types of metrics that closely mirror statsd.

  • Counters: Allow you to increment or decrement a value.
  • Gauges: Allow you to report a single value that changes over time
  • Histograms: Values are grouped into percentiles
  • Timings: Report a timed value in milliseconds
  • Measurements: Measure the execution time of a function
  • Sets: Add a value to a statsd set
  • Events: Report an event like a deploy using arbitrary keys and values

Basic Usage

Reporting a metric is extremely simple; just use the Instruments module and call the appropriate function:

defmodule ModuleThatNeedsMetrics do
  use Instruments

  def other_function() do
    Process.sleep(150)
  end

  def metrics_function() do
    Instruments.increment("my.counter", 3)
    Instruments.measure("metrics_function.other_fn_call", &other_function/0)
  end
end

Custom Namespaces

Often, all metrics inside a module have namespaced metrics. This is easy to accomplish using CustomFunctions

defmodule RpcHandler do
  use Instruments.CustomFunctions, prefix: "my_service.rpc"

  def handle(:get, "/foo/bar") do
    increment("foo.bar")
  end
end

The above example will increment the "my_service.rpc.foo.bar" metric by one.

Probes

A probe is a metric that's periodically updated, like memory usage. It can be tedious to define these on your own, so Instruments automates this process. There are several different ways to define a probe:

The first, and easiest is to use the :mfa key, which takes a tuple of {Module, function, arguments}

Probe.define!("erlang.process_count", :gauge,
  mfa: {:erlang, :system_info, [:process_count]})

The above will report the process count every ten seconds. You can also select keys from a value. For example, when reporting memory usage:

Probe.define("erlang.memory", :gauge,
  mfa: {:erlang, :memory, []},
  keys: [:total, :processes])

In the above example, the :erlang.memory() function will be called, and it returns a keyword list like:

[total: 19371280, processes: 4638128, processes_used: 4633792, system: 14733152,
 atom: 264529, atom_used: 250724, binary: 181960, code: 5843599, ets: 383504]

From this, the probe extracts the :total and :processes keys, creates two metrics, erlang.memory.total and erlang.memory.processes and reports them.

You can also define probes via a passed in zero argument function.

Probe.define!("erlang.memory", :gauge,
  function: &:erlang.memory/0,
  keys: [:total, :processes])

The above function simplifies the earlier mfa example, above, calling :erlang.memory() and extracting the :total and :processes keys.

Finally, if this isn't enough flexibility, you can implement the Probe behaviour and pass in the module of your probe:

defmodule MyProbe do
  @behaviour Instruments.Probe
  # implementation of the callbacks
end

Probe.define!("my.probe", :gauge, module: MyProbe)

Your probe module will now experience lifecycle callbacks and can keep its own state. More information on the Probe behaviour is in the Instruments.Probe moduledoc.

Probes also have two other options:

  • report_interval: (milliseconds) How often the probe is reported to the underlying stats package.

  • sample_interval: (milliseconds) How often the probe's data is collected. If not set, this defaults to the report_interval.

Performance

There are a couple optimizations that keep Instruments fast.

ETS backed counters

Probe counters actually increment or decrement a value in an ETS table, every fast_counter_report_interval milliseconds, the aggregated values are flushed to statsd. Because of this, counters are effectively free and with a conservative flush interval, will put little pressure on your statsd server.

IOData metric names

Instruments uses macros to implement the metric names, and automatically converts interpolated strings into IOLists. This means you can have many generated names without increasing the amount of binary memory you're using. For example:

def increment_rpc(rpc_name),
  do: Instruments.increment("my_module.rpc.#{rpc_name}")

will be rewritten to the call:

def increment_rpc(rpc_name),
  do: Instruments.increment(["my_module.rpc.", Kernel.to_string(rpc_name)])

If you wish, you may pass any IOData as the name of a metric.

Sample Rates

For histograms, measure calls and timings, the default sample rate is pegged to 0.1. This is so you don't accidentally overload your metrics collector. It can be overridden by passing sample_rate: float_value to your metrics call in the options.

More Repositories

1

discord-api-docs

Official Discord API Documentation
Markdown
5,543
star
2

lilliput

Resize images and animated GIFs in Go
C++
1,923
star
3

manifold

Fast batch message passing between nodes for Erlang/Elixir.
Elixir
1,618
star
4

sorted_set_nif

Elixir SortedSet backed by a Rust-based NIF
Elixir
1,532
star
5

discord-open-source

List of open source communities living on Discord
JavaScript
1,319
star
6

focus-rings

A centralized system for displaying and stylizing focus indicators anywhere on a webpage.
TypeScript
1,120
star
7

fastglobal

Fast no copy globals for Elixir & Erlang.
Elixir
1,097
star
8

discord-rpc

C++
983
star
9

airhornbot

The only bot for Discord you'll ever need.
TypeScript
851
star
10

semaphore

Fast semaphore using ETS.
Elixir
718
star
11

react-dnd-accessible-backend

An add-on backend for `react-dnd` that provides support for keyboards and screenreaders by default.
TypeScript
576
star
12

ex_hash_ring

A fast consistent hash ring implementation in Elixir.
Elixir
475
star
13

discord-example-app

Basic Discord app with examples
JavaScript
434
star
14

OverlappingPanels

Overlapping Panels is a gestures-driven navigation UI library for Android
Kotlin
420
star
15

SimpleAST

Extensible Android library for both parsing text into Abstract Syntax Trees and rendering those trees as rich text.
Kotlin
360
star
16

discord-interactions-js

JS/Node helpers for Discord Interactions
TypeScript
345
star
17

focus-layers

Tiny React hooks for isolating focus within subsections of the DOM.
TypeScript
292
star
18

discord-api-spec

OpenAPI specification for Discord APIs
237
star
19

discord-oauth2-example

Discord OAuth2 Example
Python
225
star
20

loqui

RPC Transport Layer - with minimal bullshit.
Rust
220
star
21

erlpack

High Performance Erlang Term Format Packer
Cython
211
star
22

cloudflare-sample-app

Example discord bot using Cloudflare Workers
JavaScript
197
star
23

use-memo-value

Reuse the previous version of a value unless it has changed
TypeScript
170
star
24

zen_monitor

Efficient Process.monitor replacement
Elixir
167
star
25

deque

Fast bounded deque using two rotating lists.
Elixir
141
star
26

avatar-remix-bot

TypeScript
127
star
27

linked-roles-sample

JavaScript
119
star
28

punt

Punt is a tiny and lightweight daemon which helps ship logs to Elasticsearch.
Go
113
star
29

embedded-app-sdk

🚀 The Discord Embedded App SDK lets you build rich, multiplayer experiences as Activities inside Discord.
TypeScript
109
star
30

sample-game-integration

An example using Discord's API and local RPC socket to add Voice and Text chat to an instance or match based multiplayer game.
JavaScript
105
star
31

endanger

Build Dangerfiles with ease.
TypeScript
96
star
32

discord-interactions-python

Useful tools for building interactions in Python
Python
93
star
33

react-base-hooks

Basic utility React hooks
TypeScript
77
star
34

dynamic-pool

a lock-free, thread-safe, dynamically-sized object pool.
Rust
76
star
35

itsdangerous-rs

A rust port of itsdangerous!
Rust
72
star
36

gen_registry

Simple and efficient local Process Registry
Elixir
71
star
37

confetti-cannon

Launch Confetti
TypeScript
45
star
38

discord-react-forms

Forms... in React
JavaScript
43
star
39

discord-interactions-php

PHP utilities for building Discord Interaction webhooks
PHP
40
star
40

babel-plugin-define-patterns

Create constants that replace various expressions at build-time
JavaScript
39
star
41

eslint-traverse

Create a sub-traversal of an AST node in your ESLint plugin
JavaScript
30
star
42

rapidxml

Mirror of rapidxml from http://rapidxml.sourceforge.net/
C++
29
star
43

memory_size

Elixir
29
star
44

gamesdk-and-dispatch

Public issue tracker for the Discord Game SDK and Dispatch
22
star
45

dispenser

Elixir library to buffer and send events to subscribers.
Elixir
17
star
46

eslint-plugin-discord

Custom ESLint rules for Discord
JavaScript
16
star
47

chromium-build

Python
15
star
48

hash_ring

hash_ring
C
14
star
49

limited_queue

Simple Elixir queue, with a constant-time `size/1` and a maximum capacity
Elixir
13
star
50

perceptual

A smarter volume slider scale
TypeScript
13
star
51

discord_vigilante

12
star
52

heroku-sample-app

Example discord bot using Heroku
JavaScript
11
star
53

postcss-theme-shorthand

Converts `light-` and `dark-` prefixed CSS properties into corresponding light/dark theme globals
JavaScript
11
star
54

babel-plugin-strip-object-freeze

Replace all instances of Object.freeze(value) with value
JavaScript
10
star
55

libyuv

our fork of libyuv for webrtc
C++
10
star
56

lilliput-rs

Lilliput, in Rust!
Rust
9
star
57

lilliput-bench

Benchmarker for lilliput
Python
8
star
58

sqlite3

Mirror of sqlite amalgamation from https://www.sqlite.org/
C
7
star
59

openh264

C++
6
star
60

slate-react-package-fork

TypeScript
6
star
61

rlottiebinding-ios

rlottie ios submodule
Starlark
5
star
62

jemalloc_info

A small library for exporting jemalloc allocation data in Elixir
Elixir
5
star
63

libnice

Fork of https://nice.freedesktop.org/wiki/
C
5
star
64

libvpx

C
4
star
65

libsrtp

Fork of libsrtp
C
4
star
66

RLottieAndroid

C++
4
star
67

opentelemetry-rust-datadog

Rust
4
star
68

slate-package-fork

JavaScript
4
star
69

lilliput-dep-source

Convenient source repo for Lilliput's dependencies
3
star
70

slate-hotkeys-package-fork

3
star
71

YYText

Powerful text framework for iOS to display and edit rich text.
Objective-C
3
star
72

rules_ios

Bazel rules for building iOS applications and frameworks
Starlark
2
star
73

cocoapods-bazel

A Cocoapods plugin for automatically generating Bazel BUILD files
Ruby
2
star
74

eslint-plugin-react-discord

Fork of eslint-plugin-react
JavaScript
1
star