Skip to content

Commit

Permalink
improve docs
Browse files Browse the repository at this point in the history
  • Loading branch information
deadtrickster committed Sep 17, 2016
1 parent 442122f commit 6dd56bf
Show file tree
Hide file tree
Showing 64 changed files with 2,489 additions and 2,817 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.rebar3
rebar3.crashdump
_*
.eunit
*.o
Expand Down
192 changes: 128 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,67 @@
# Prometheus.erl


# Prometheus.io client for Erlang #

Copyright (c) 2016 Ilya Khaprov <<[email protected]>>.

__Version:__ 3.0.0

[![Hex.pm](https://img.shields.io/hexpm/v/prometheus.svg?maxAge=2592000?style=plastic)](https://hex.pm/packages/prometheus) [![Build Status](https://travis-ci.org/deadtrickster/prometheus.erl.svg?branch=version-3)](https://travis-ci.org/deadtrickster/prometheus.erl) [![Coverage Status](https://coveralls.io/repos/github/deadtrickster/prometheus.erl/badge.svg?branch=version-3)](https://coveralls.io/github/deadtrickster/prometheus.erl?branch=version-3)

[Prometheus.io](https://prometheus.io) monitoring system and time series database client in Erlang.

![RabbitMQ Dashboard](https://raw.githubusercontent.com/deadtrickster/prometheus_rabbitmq_exporter/master/priv/dashboards/RabbitMQErlangVM.png)

### Metrics
#### Standard
- [x] Counter
- [x] Gauge
- [x] Summary
- [x] Histogram

#### Custom Collectors
- `erlang_vm_memory_collector` - Collects information about Erlang VM memory usage mainly using `erlang:memory/0`
- `erlang_vm_statistics_collector` - Collects Erlang VM statistics using `erlang:statistics/1`

You can write custom collector/exporter for any library/app you'd like. For example here is [Queue info collector](https://github.com/deadtrickster/prometheus_rabbitmq_exporter/blob/master/src/collectors/prometheus_rabbitmq_queues_collector.erl) from [RabbitMQ Exporter](https://github.com/deadtrickster/prometheus_rabbitmq_exporter).
## Integrations
- [Ecto Instrumenter](https://hex.pm/packages/prometheus_ecto)
- [Elixir client](https://github.com/deadtrickster/prometheus.ex)
- [Elixir plugs Instrumenters and Exporter](https://hex.pm/packages/prometheus_plugs)
- [Fuse plugin](https://github.com/jlouis/fuse#fuse_stats_prometheus)
- [OS process info Collector](https://hex.pm/packages/prometheus_process_collector) (linux-only)
- [Phoenix Instrumenter](https://hex.pm/packages/prometheus_phoenix)
- [RabbitMQ Exporter](https://github.com/deadtrickster/prometheus_rabbitmq_exporter).

### Integrations / Collectors / Instrumenters
- [Ecto collector](https://github.com/deadtrickster/prometheus-ecto)
- [Elixir client](https://github.com/deadtrickster/prometheus.ex)
- [Plugs Instrumenter/Exporter](https://github.com/deadtrickster/prometheus-plugs)
- [Elli middleware](https://github.com/elli-lib/elli_prometheus)
- [Fuse plugin](https://github.com/jlouis/fuse#fuse_stats_prometheus)
- [Phoenix instrumenter](https://github.com/deadtrickster/prometheus-phoenix)
- [Process Info Collector](https://github.com/deadtrickster/prometheus_process_collector.erl)
- [RabbitMQ Exporter](https://github.com/deadtrickster/prometheus_rabbitmq_exporter)
## Erlang VM Collectors
- [Memory Collector](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_vm_memory_collector.md)
- [Statistics Collector](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_vm_statistics_collector.md)
- [System Information Collector](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_vm_system_info_collector.md).

### Example Console Session
## Example Console Session

Run shell with compiled and loaded app:

```erlang-repl
$ rebar3 shell
```

Start prometheus app:
``` erlang

```erlang-repl
prometheus:start().
```

Register metrics:

```erlang

prometheus_gauge:new([{name, pool_size}, {help, "MongoDB Connections pool size"}]),
prometheus_counter:new([{name, http_requests_total}, {help, "Http request count"}]).
prometheus_summary:new([{name, orders}, {help, "Track orders count/total sum"}]).
prometheus_histogram:new([{name, http_request_duration_milliseconds},
{labels, [method]},
{bounds, [100, 300, 500, 750, 1000]},
{help, "Http Request execution time"}]).

```

Use metrics:

```erlang

prometheus_gauge:set(pool_size, 365),
prometheus_counter:inc(http_requests_total).
prometheus_summary:observe(orders, 10).
Expand All @@ -69,13 +81,19 @@ prometheus_histogram:observe(http_request_duration_milliseconds, [post], 450).
prometheus_histogram:observe(http_request_duration_milliseconds, [post], 850).
prometheus_histogram:observe(http_request_duration_milliseconds, [post], 750).
prometheus_histogram:observe(http_request_duration_milliseconds, [post], 1650).

```

Export metrics as text:

```erlang

io:format(prometheus_text_format:format()).

```

->

```
# TYPE http_requests_total counter
# HELP http_requests_total Http request count
Expand Down Expand Up @@ -105,76 +123,122 @@ http_request_duration_milliseconds_bucket{method="get",le="1000"} 9
http_request_duration_milliseconds_bucket{method="get",le="+Inf"} 9
http_request_duration_milliseconds_count{method="get"} 9
http_request_duration_milliseconds_sum{method="get"} 2622
```

### Bucket generators
## API

```erlang
prometheus_buckets:linear(-15, 5, 6) produces [-15, -10, -5, 0, 5, 10]
API can be grouped like this:

prometheus_buckets:exponential(100, 1.2, 3) produces [100, 120, 144]
```
### Standard Metrics & Registry

### Implementation Note
- [`prometheus_counter`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_counter.md) - counter metric, to track counts of events or running totals;
- [`prometheus_gauge`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_gauge.md) - gauge metric, to report instantaneous values;
- [`prometheus_histogram`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_histogram.md) - histogram metric, to track distributions of events;
- [`prometheus_summary`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_summary.md) - summary metric, to track the size of events;
- [`prometheus_registry`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_registry.md) - working with Prometheus registries.

Prometheus.erl exports two API sets.
- For Integers: `prometheus_coutner:inc`, `prometheus_summary:observe` and `prometheus_histogram:observe`. Implementation is based on `ets:update_counter`. While this is expected to be much faster than using processes for synchronization it restricts us to integers-only while Prometheus expects series values to be double.
ETS-based metrics are optimistic - for basic metrics such as counters/gauges it first tries to increment and iff series doesn't exist it queries ETS to check if metric actually registered and if so it inserts series. For histograms at least one lookup is required - we need buckets to compute bucket counter position.
- For Floats: `prometheus_coutner:dinc`, `prometheus_summary:dobserve` and `prometheus_histogram:dobserve`. Implementation is based on `gen_server` which is used for synchronizations (ets doesn't support float atomic increments).

***NOTE***: you can use float APIs after integer but not vice-versa.
All metrics created via `new/1` or `declare/1`. The difference is that `new/1` actually wants metric to be
new and raises `{mf_already_exists, {Registry, Name}, Message}` error if it isn't.

### Configuration
Both `new/1` and `declare/1` accept options as [proplist](http://erlang.org/doc/man/proplists.html).
Common options are:

- name - metric name, can be an atom or a string (required);
- help - metric help, string (required);
- labels - metric labels, label can be an atom or a string (default is []);
- registry - Prometheus registry for the metric, can be any term. (default is default)

Histogram also accepts `buckets` option. Please refer to respective modules docs for the more information.

### Exposition Formats

- [`prometheus_text_format`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_text_format.md) - renders metrics for a given registry (default is `default`) in text format;
- [`prometheus_protobuf_format`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_protobuf_format.md) - renders metrics for a given registry (default is `default`) in protobuf v2 format.

### General Helpers

- [`prometheus_buckets`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_buckets.md) - linear or exponential bucket generators;
- [`prometheus_http`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_http.md) - helpers for HTTP instrumenters.

### Advanced

You will need this modules only if you're writing custom collector for app/lib that can't be instrumented directly.

- [`prometheus_collector`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_collector.md) - common interface for collectors;
- [`prometheus_format`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_format.md) - common interface for exposition formats;
- [`prometheus_model_helpers`](https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_model_helpers.md) - provides API for working with underlying Prometheus models.
You'll use that if you want to create custom collector.

## Build

```
$ rebar3 compile
```

## Configuration

Prometheus.erl supports standard Erlang app configuration.
- `default_collectors` - List of custom collectors modules to be registered automatically. If undefined list of all modules implementing `prometheus_collector` behaviour will be used.
- `default_metrics` - List of metrics to be registered during app startup. Metric format: `{Registry, Metric, Spec}` where `Registry` is registry name, `Metric` is metric type (prometheus_counter, prometheus_gauge ... etc), `Spec` is a list to be passed to `Metric:register/2`.
- `default_collectors` - List of custom collectors modules to be registered automatically. If undefined list of all modules implementing `prometheus_collector` behaviour will be used.
- `default_metrics` - List of metrics to be registered during app startup. Metric format: `{Registry, Metric, Spec}` where `Registry` is registry name, `Metric` is metric type (prometheus_counter, prometheus_gauge ... etc), `Spec` is a list to be passed to `Metric:register/2`.

### Collectors & Exporters Conventions
## Collectors & Exporters Conventions

#### Configuration
### Configuration

All 3d-party libraries should be configured via `prometheus` app env.

Exproters are responsible for maintianing scrape endpoint. Exporters usually tightly coupled with web server and are singletons. They should understand these keys:
Exproters are responsible for maintianing scrape endpoint.
Exporters usually tightly coupled with web server and are singletons. They should understand these keys:
- `path` - url for scraping;
- `format` - scrape format as module name i.e. `prometheus_text_format` or `prometheus_protobuf_format`.
Exporter-specific options should be under `<exporter_name>_exporter` for erlang or `<Exporter_name>Exporter` for Elixir i.e. `PlugsExporter` or `elli_exporter`

Collectors collect integration specific metrics i.e. ecto timings, process informations and so on.
Their configuration should be under `<collector_name>_collector`for erlang or `<Collector_name>Collector` for Elixir i.e. `process_collector`, `EctoCollector` and so on.

#### Naming
### Naming

For Erlang: `prometheus_<name>_collector`/`prometheus_<name>_exporter`.

For Elixir: `Prometheus.Collectors.<name>`/`Prometheus.Exporters.<name>`.
For Elixir: `Prometheus.<name>Collector`/`Prometheus.<name>Exporter`.

### TODO
## Contributing

- [x] Floats support
- [x] Tests
- [x] Bucket generators
- [x] Protobuf format
- [ ] Full summary implementation
- [ ] Extend custom collectors collection?
Sections order:

`Types -> Macros -> Callbacks -> Public API -> Deprecations -> Private Parts`

### Build
install git precommit hook:

$ rebar3 compile
### Contributing
```
./bin/pre-commit.sh install
```

Types -> Macros -> Callbacks -> Public API -> Deprecations -> Private Parts
Pre-commit check can be skipped passing `--no-verify` option to git commit.

install git precommit hook:

./bin/pre-commit.sh install

Pre-commit check can be skipped passing `--no-verify` option to git commit.

### License
## License

MIT


## Modules ##


<table width="100%" border="0" summary="list of modules">
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_buckets.md" class="module">prometheus_buckets</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_collector.md" class="module">prometheus_collector</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_counter.md" class="module">prometheus_counter</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_format.md" class="module">prometheus_format</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_gauge.md" class="module">prometheus_gauge</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_histogram.md" class="module">prometheus_histogram</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_http.md" class="module">prometheus_http</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_model_helpers.md" class="module">prometheus_model_helpers</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_protobuf_format.md" class="module">prometheus_protobuf_format</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_registry.md" class="module">prometheus_registry</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_summary.md" class="module">prometheus_summary</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_text_format.md" class="module">prometheus_text_format</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_time.md" class="module">prometheus_time</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_vm_memory_collector.md" class="module">prometheus_vm_memory_collector</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_vm_statistics_collector.md" class="module">prometheus_vm_statistics_collector</a></td></tr>
<tr><td><a href="https://github.com/deadtrickster/prometheus.erl/blob/version-3/doc/prometheus_vm_system_info_collector.md" class="module">prometheus_vm_system_info_collector</a></td></tr></table>

Loading

0 comments on commit 6dd56bf

Please sign in to comment.