├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── doc ├── README.md ├── edoc-info ├── erlang.png ├── metrics.md ├── metrics_dummy.md ├── metrics_exometer.md ├── metrics_folsom.md ├── metrics_noop.md ├── metrics_process_tracker.md ├── metrics_sup.md ├── overview.edoc └── stylesheet.css ├── rebar.config ├── rebar.lock ├── src ├── metrics.app.src ├── metrics.erl ├── metrics_exometer.erl ├── metrics_folsom.erl ├── metrics_noop.erl ├── metrics_process_tracker.erl └── metrics_sup.erl ├── support └── rebar3 └── test └── metrics_tests.erl /.gitignore: -------------------------------------------------------------------------------- 1 | .rebar3 2 | _* 3 | .eunit 4 | *.o 5 | *.beam 6 | *.plt 7 | *.swp 8 | *.swo 9 | .erlang.cookie 10 | ebin 11 | log 12 | erl_crash.dump 13 | .rebar 14 | _rel 15 | _deps 16 | _plugins 17 | _tdeps 18 | logs 19 | _build -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: erlang 2 | otp_release: 3 | - 21.0.2 4 | - 20.3 5 | - 20.2 6 | - 19.3 7 | script: 8 | - ./support/rebar3 eunit 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, benoitc . 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | * The names of its contributors may not be used to endorse or promote 16 | products derived from this software without specific prior written 17 | permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # metrics: A generic interface to different metrics systems in Erlang. # 4 | 5 | Copyright (c) 2017-2018 Benoît Chesneau. 6 | 7 | __Version:__ 2.5.0 8 | 9 | # metrics 10 | 11 | A generic interface to folsom, exometer, grapherl or any compliant interface. This 12 | application has been extracted from 13 | [hackney](https://github.com/benoitc/hackney). 14 | 15 | Currently supported backend are: 16 | 17 | - [Folsom](https://github.com/folsom-project/folsom): `metrics_folsom` 18 | - [Exometer](https://github.com/Feuerlabs/exometer): `metrics_exometer` 19 | 20 | > If you need the support for another backend, please [open a ticket](https://github.com/benoitc/erlang-metrics/issues). 21 | 22 | [![Hex pm](http://img.shields.io/hexpm/v/metrics.svg?style=flat)](https://hex.pm/packages/metrics) 23 | 24 | ## Usage 25 | 26 | ### Set a backend 27 | 28 | The backend can be set in the application environment using the `metrics_mod` setting or using `metrics:backend/1`. 29 | 30 | ### register a new metric: 31 | 32 | ``` 33 | metrics:new(counter, "c"). 34 | ``` 35 | 36 | Depending on the backend the following metrics types can be passed: counter | histogram | gauge | meter | spiral 37 | 38 | ### update a metric 39 | 40 | A counter can simply be incremented by 1 using `metrics:update/1`. or by passing a positive or negative integer like this: 41 | 42 | ``` 43 | metrics:update("c", {c, 1}). 44 | ``` 45 | 46 | Other metrics are updated via `metrics:update/2`. 47 | 48 | ## Example: 49 | 50 | ```erlang 51 | 52 | 1> application:ensure_all_started(metrics). 53 | {ok,[metrics]} 54 | 2> application:ensure_all_started(folsom). 55 | {ok,[bear,folsom]} 56 | 3> metrics:backend(metrics_folsom). 57 | ok 58 | 4> metrics:new(counter, "c"). 59 | ok 60 | 5> metrics:update("c"). 61 | ok 62 | 6> folsom_metrics:get_metric_value("c"). 63 | 1 64 | 7> metrics:update("c", {c, 1}). 65 | ok 66 | 8> folsom_metrics:get_metric_value("c"). 67 | 2 68 | 69 | ``` 70 | 71 | ## Documentation 72 | 73 | Full doc is available in the [`metrics`](http://github.com/benoitc/erlang-metrics/blob/master/doc/metrics.md) module. 74 | 75 | ## Build 76 | 77 | ``` 78 | $ rebar3 compile 79 | ``` 80 | 81 | 82 | 83 | ## Modules ## 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 |
metrics
metrics_exometer
metrics_folsom
metrics_noop
metrics_process_tracker
metrics_sup
93 | 94 | -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # metrics: A generic interface to different metrics systems in Erlang. # 4 | 5 | Copyright (c) 2017-2018 Benoît Chesneau. 6 | 7 | __Version:__ 2.5.0 8 | 9 | # metrics 10 | 11 | A generic interface to folsom, exometer, grapherl or any compliant interface. This 12 | application has been extracted from 13 | [hackney](https://github.com/benoitc/hackney). 14 | 15 | Currently supported backend are: 16 | 17 | - [Folsom](https://github.com/folsom-project/folsom): `metrics_folsom` 18 | - [Exometer](https://github.com/Feuerlabs/exometer): `metrics_exometer` 19 | 20 | > If you need the support for another backend, please [open a ticket](https://github.com/benoitc/erlang-metrics/issues). 21 | 22 | [![Hex pm](http://img.shields.io/hexpm/v/metrics.svg?style=flat)](https://hex.pm/packages/metrics) 23 | 24 | ## Usage 25 | 26 | ### Set a backend 27 | 28 | The backend can be set in the application environment using the `metrics_mod` setting or using `metrics:backend/1`. 29 | 30 | ### register a new metric: 31 | 32 | ``` 33 | metrics:new(counter, "c"). 34 | ``` 35 | 36 | Depending on the backend the following metrics types can be passed: counter | histogram | gauge | meter | spiral 37 | 38 | ### update a metric 39 | 40 | A counter can simply be incremented by 1 using `metrics:update/1`. or by passing a positive or negative integer like this: 41 | 42 | ``` 43 | metrics:update("c", {c, 1}). 44 | ``` 45 | 46 | Other metrics are updated via `metrics:update/2`. 47 | 48 | ## Example: 49 | 50 | ```erlang 51 | 52 | 1> application:ensure_all_started(metrics). 53 | {ok,[metrics]} 54 | 2> application:ensure_all_started(folsom). 55 | {ok,[bear,folsom]} 56 | 3> metrics:backend(metrics_folsom). 57 | ok 58 | 4> metrics:new(counter, "c"). 59 | ok 60 | 5> metrics:update("c"). 61 | ok 62 | 6> folsom_metrics:get_metric_value("c"). 63 | 1 64 | 7> metrics:update("c", {c, 1}). 65 | ok 66 | 8> folsom_metrics:get_metric_value("c"). 67 | 2 68 | 69 | ``` 70 | 71 | ## Documentation 72 | 73 | Full doc is available in the [`metrics`](metrics.md) module. 74 | 75 | ## Build 76 | 77 | ``` 78 | $ rebar3 compile 79 | ``` 80 | 81 | 82 | 83 | ## Modules ## 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 |
metrics
metrics_exometer
metrics_folsom
metrics_noop
metrics_process_tracker
metrics_sup
93 | 94 | -------------------------------------------------------------------------------- /doc/edoc-info: -------------------------------------------------------------------------------- 1 | %% encoding: UTF-8 2 | {application,metrics}. 3 | {modules,[metrics,metrics_exometer,metrics_folsom,metrics_noop, 4 | metrics_process_tracker,metrics_sup]}. 5 | -------------------------------------------------------------------------------- /doc/erlang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/erlang-metrics/3ea572b5b6ca4a3e5dfc12009058f8771baf5789/doc/erlang.png -------------------------------------------------------------------------------- /doc/metrics.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module metrics # 4 | * [Data Types](#types) 5 | * [Function Index](#index) 6 | * [Function Details](#functions) 7 | 8 | __Behaviours:__ [`application`](application.md), [`gen_server`](gen_server.md). 9 | 10 | 11 | 12 | ## Data Types ## 13 | 14 | 15 | 16 | 17 | ### metric() ### 18 | 19 | 20 |

 21 | metric() = counter | histogram | gauge | meter | spiral | duration
 22 | 
23 | 24 | 25 | 26 | 27 | ### metric_name() ### 28 | 29 | 30 |

 31 | metric_name() = list()
 32 | 
33 | 34 | 35 | 36 | 37 | ### probe() ### 38 | 39 | 40 |

 41 | probe() = {c, integer()} | timer_start | timer_end | {duration_fun, function()} | value()
 42 | 
43 | 44 | 45 | 46 | 47 | ### value() ### 48 | 49 | 50 |

 51 | value() = any()
 52 | 
53 | 54 | 55 | 56 | ## Function Index ## 57 | 58 | 59 |
backend/0retrieve the current backend name.
backend/1set the backend to use.
code_change/3
delete/1delete a metric.
handle_call/3
handle_cast/2
handle_info/2
init/1
new/2 initialise a metric.
start/2
start_link/0
stop/1
terminate/2
update/1increment a counter with 1.
update/2update a metric.
update_or_create/3update a metric and create it if it doesn't exists.
60 | 61 | 62 | 63 | 64 | ## Function Details ## 65 | 66 | 67 | 68 | ### backend/0 ### 69 | 70 |

 71 | backend() -> atom()
 72 | 
73 |
74 | 75 | retrieve the current backend name 76 | 77 | 78 | 79 | ### backend/1 ### 80 | 81 |

 82 | backend(Mod::atom()) -> ok
 83 | 
84 |
85 | 86 | set the backend to use 87 | 88 | 89 | 90 | ### code_change/3 ### 91 | 92 | `code_change(OldVsn, State, Extra) -> any()` 93 | 94 | 95 | 96 | ### delete/1 ### 97 | 98 |

 99 | delete(Name) -> Result
100 | 
101 | 102 | 103 | 104 | delete a metric 105 | 106 | 107 | 108 | ### handle_call/3 ### 109 | 110 | `handle_call(X1, From, State) -> any()` 111 | 112 | 113 | 114 | ### handle_cast/2 ### 115 | 116 | `handle_cast(Msg, State) -> any()` 117 | 118 | 119 | 120 | ### handle_info/2 ### 121 | 122 | `handle_info(Info, State) -> any()` 123 | 124 | 125 | 126 | ### init/1 ### 127 | 128 | `init(X1) -> any()` 129 | 130 | 131 | 132 | ### new/2 ### 133 | 134 |

135 | new(Metric, Name) -> Result
136 | 
137 | 138 | 139 | 140 | initialise a metric 141 | 142 | 143 | 144 | ### start/2 ### 145 | 146 |

147 | start(StartType::application:start_type(), StartArgs::any()) -> {ok, pid()}
148 | 
149 |
150 | 151 | 152 | 153 | ### start_link/0 ### 154 | 155 |

156 | start_link() -> {ok, pid()}
157 | 
158 |
159 | 160 | 161 | 162 | ### stop/1 ### 163 | 164 |

165 | stop(State::atom()) -> ok
166 | 
167 |
168 | 169 | 170 | 171 | ### terminate/2 ### 172 | 173 | `terminate(Reason, State) -> any()` 174 | 175 | 176 | 177 | ### update/1 ### 178 | 179 |

180 | update(Name) -> Result
181 | 
182 | 183 | 184 | 185 | increment a counter with 1 186 | 187 | 188 | 189 | ### update/2 ### 190 | 191 |

192 | update(Name, Probe) -> Result
193 | 
194 | 195 | 196 | 197 | update a metric 198 | 199 | 200 | 201 | ### update_or_create/3 ### 202 | 203 |

204 | update_or_create(Name, Probe, Metric) -> Result
205 | 
206 | 207 | 208 | 209 | update a metric and create it if it doesn't exists 210 | 211 | -------------------------------------------------------------------------------- /doc/metrics_dummy.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module metrics_dummy # 4 | * [Description](#description) 5 | * [Function Index](#index) 6 | * [Function Details](#functions) 7 | 8 | dummy metric module. 9 | 10 | 11 | 12 | ## Function Index ## 13 | 14 | 15 |
decrement_counter/1
decrement_counter/2
decrement_spiral/1
decrement_spiral/2
delete/1
get_value/1
increment_counter/1
increment_counter/2
increment_spiral/1
increment_spiral/2
new/2
sample/1
update_gauge/2
update_histogram/2
update_meter/2
16 | 17 | 18 | 19 | 20 | ## Function Details ## 21 | 22 | 23 | 24 | ### decrement_counter/1 ### 25 | 26 | `decrement_counter(X1) -> any()` 27 | 28 | 29 | 30 | ### decrement_counter/2 ### 31 | 32 | `decrement_counter(X1, X2) -> any()` 33 | 34 | 35 | 36 | ### decrement_spiral/1 ### 37 | 38 | `decrement_spiral(X1) -> any()` 39 | 40 | 41 | 42 | ### decrement_spiral/2 ### 43 | 44 | `decrement_spiral(X1, X2) -> any()` 45 | 46 | 47 | 48 | ### delete/1 ### 49 | 50 | `delete(X1) -> any()` 51 | 52 | 53 | 54 | ### get_value/1 ### 55 | 56 | `get_value(X1) -> any()` 57 | 58 | 59 | 60 | ### increment_counter/1 ### 61 | 62 | `increment_counter(X1) -> any()` 63 | 64 | 65 | 66 | ### increment_counter/2 ### 67 | 68 | `increment_counter(X1, X2) -> any()` 69 | 70 | 71 | 72 | ### increment_spiral/1 ### 73 | 74 | `increment_spiral(X1) -> any()` 75 | 76 | 77 | 78 | ### increment_spiral/2 ### 79 | 80 | `increment_spiral(X1, X2) -> any()` 81 | 82 | 83 | 84 | ### new/2 ### 85 | 86 | `new(X1, X2) -> any()` 87 | 88 | 89 | 90 | ### sample/1 ### 91 | 92 | `sample(X1) -> any()` 93 | 94 | 95 | 96 | ### update_gauge/2 ### 97 | 98 | `update_gauge(X1, X2) -> any()` 99 | 100 | 101 | 102 | ### update_histogram/2 ### 103 | 104 | `update_histogram(X1, Fun) -> any()` 105 | 106 | 107 | 108 | ### update_meter/2 ### 109 | 110 | `update_meter(X1, X2) -> any()` 111 | 112 | -------------------------------------------------------------------------------- /doc/metrics_exometer.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module metrics_exometer # 4 | * [Description](#description) 5 | * [Function Index](#index) 6 | * [Function Details](#functions) 7 | 8 | exometer backend. 9 | 10 | 11 | 12 | ## Function Index ## 13 | 14 | 15 |
delete/2
new/3
update/3
update_or_create/4
16 | 17 | 18 | 19 | 20 | ## Function Details ## 21 | 22 | 23 | 24 | ### delete/2 ### 25 | 26 | `delete(Name, Config) -> any()` 27 | 28 | 29 | 30 | ### new/3 ### 31 | 32 |

33 | new(X1::atom(), Name::any(), Config::map()) -> ok | {error, metric_exists | unsupported_type}
34 | 
35 |
36 | 37 | 38 | 39 | ### update/3 ### 40 | 41 | `update(Name, Val, Config) -> any()` 42 | 43 | 44 | 45 | ### update_or_create/4 ### 46 | 47 | `update_or_create(Name, Val, Type, Config) -> any()` 48 | 49 | -------------------------------------------------------------------------------- /doc/metrics_folsom.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module metrics_folsom # 4 | * [Description](#description) 5 | * [Function Index](#index) 6 | * [Function Details](#functions) 7 | 8 | folsom backend. 9 | 10 | 11 | 12 | ## Function Index ## 13 | 14 | 15 |
delete/2
new/3
update/3
update_or_create/4
16 | 17 | 18 | 19 | 20 | ## Function Details ## 21 | 22 | 23 | 24 | ### delete/2 ### 25 | 26 | `delete(Name, Config) -> any()` 27 | 28 | 29 | 30 | ### new/3 ### 31 | 32 |

33 | new(X1::atom(), Name::any(), Config::map()) -> ok | {error, term()}
34 | 
35 |
36 | 37 | 38 | 39 | ### update/3 ### 40 | 41 | `update(Name, Val, Config) -> any()` 42 | 43 | 44 | 45 | ### update_or_create/4 ### 46 | 47 | `update_or_create(Name, Probe, Type, Config) -> any()` 48 | 49 | -------------------------------------------------------------------------------- /doc/metrics_noop.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module metrics_noop # 4 | * [Description](#description) 5 | * [Function Index](#index) 6 | * [Function Details](#functions) 7 | 8 | noop backend. 9 | 10 | 11 | 12 | ## Function Index ## 13 | 14 | 15 |
delete/2
new/3
update/3
update_or_create/4
16 | 17 | 18 | 19 | 20 | ## Function Details ## 21 | 22 | 23 | 24 | ### delete/2 ### 25 | 26 | `delete(Name, Config) -> any()` 27 | 28 | 29 | 30 | ### new/3 ### 31 | 32 | `new(Name, Type, Config) -> any()` 33 | 34 | 35 | 36 | ### update/3 ### 37 | 38 | `update(Name, Probe, Config) -> any()` 39 | 40 | 41 | 42 | ### update_or_create/4 ### 43 | 44 | `update_or_create(Name, Probe, Type, Config) -> any()` 45 | 46 | -------------------------------------------------------------------------------- /doc/metrics_process_tracker.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module metrics_process_tracker # 4 | * [Description](#description) 5 | * [Function Index](#index) 6 | * [Function Details](#functions) 7 | 8 | module to track processes associated to a counter. 9 | 10 | __Behaviours:__ [`gen_server`](gen_server.md). 11 | 12 | 13 | 14 | ## Function Index ## 15 | 16 | 17 |
code_change/3
handle_call/3
handle_cast/2
handle_info/2
init/1
start_link/0
terminate/2
track/1track the number of processes for a name 18 | this add the current process.
track/2track the number of processes for a name.
19 | 20 | 21 | 22 | 23 | ## Function Details ## 24 | 25 | 26 | 27 | ### code_change/3 ### 28 | 29 | `code_change(OldVsn, State, Extra) -> any()` 30 | 31 | 32 | 33 | ### handle_call/3 ### 34 | 35 | `handle_call(Msg, From, State) -> any()` 36 | 37 | 38 | 39 | ### handle_cast/2 ### 40 | 41 | `handle_cast(X1, State) -> any()` 42 | 43 | 44 | 45 | ### handle_info/2 ### 46 | 47 | `handle_info(X1, State) -> any()` 48 | 49 | 50 | 51 | ### init/1 ### 52 | 53 | `init(X1) -> any()` 54 | 55 | 56 | 57 | ### start_link/0 ### 58 | 59 | `start_link() -> any()` 60 | 61 | 62 | 63 | ### terminate/2 ### 64 | 65 | `terminate(Reason, State) -> any()` 66 | 67 | 68 | 69 | ### track/1 ### 70 | 71 |

72 | track(Name::any()) -> ok | {error, term()}
73 | 
74 |
75 | 76 | track the number of processes for a name 77 | this add the current process 78 | 79 | 80 | 81 | ### track/2 ### 82 | 83 |

84 | track(Name::any(), Pid::pid()) -> ok | {error, term()}
85 | 
86 |
87 | 88 | track the number of processes for a name 89 | 90 | -------------------------------------------------------------------------------- /doc/metrics_sup.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module metrics_sup # 4 | * [Function Index](#index) 5 | * [Function Details](#functions) 6 | 7 | __Behaviours:__ [`supervisor`](supervisor.md). 8 | 9 | 10 | 11 | ## Function Index ## 12 | 13 | 14 |
init/1
start_link/0
15 | 16 | 17 | 18 | 19 | ## Function Details ## 20 | 21 | 22 | 23 | ### init/1 ### 24 | 25 |

26 | init(X1::any()) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}
27 | 
28 |
29 | 30 | 31 | 32 | ### start_link/0 ### 33 | 34 |

35 | start_link() -> {ok, pid()} | {error, term()}
36 | 
37 |
38 | 39 | -------------------------------------------------------------------------------- /doc/overview.edoc: -------------------------------------------------------------------------------- 1 | @copyright 2017-2018 Benoît Chesneau. 2 | @version 2.5.0 3 | @title: metrics: A generic interface to different metrics systems in Erlang. 4 | 5 | @doc 6 | 7 | # metrics 8 | 9 | A generic interface to folsom, exometer, grapherl or any compliant interface. This 10 | application has been extracted from 11 | [hackney](https://github.com/benoitc/hackney). 12 | 13 | Currently supported backend are: 14 | 15 | - [Folsom](https://github.com/folsom-project/folsom): `metrics_folsom' 16 | - [Exometer](https://github.com/Feuerlabs/exometer): `metrics_exometer' 17 | 18 | > If you need the support for another backend, please [open a ticket](https://github.com/benoitc/erlang-metrics/issues). 19 | 20 | 21 | [![Hex pm](http://img.shields.io/hexpm/v/metrics.svg?style=flat)](https://hex.pm/packages/metrics) 22 | 23 | ## Usage 24 | 25 | ### Set a backend 26 | 27 | The backend can be set in the application environment using the `metrics_mod' setting or using `metrics:backend/1'. 28 | 29 | ### register a new metric: 30 | 31 | ``` 32 | metrics:new(counter, "c"). 33 | ''' 34 | 35 | Depending on the backend the following metrics types can be passed: counter | histogram | gauge | meter | spiral 36 | 37 | ### update a metric 38 | 39 | A counter can simply be incremented by 1 using `metrics:update/1'. or by passing a positive or negative integer like this: 40 | 41 | ``` 42 | metrics:update("c", {c, 1}). 43 | ''' 44 | 45 | Other metrics are updated via `metrics:update/2'. 46 | 47 | 48 | ## Example: 49 | 50 |
51 | 1> application:ensure_all_started(metrics).
52 | {ok,[metrics]}
53 | 2> application:ensure_all_started(folsom).
54 | {ok,[bear,folsom]}
55 | 3> metrics:backend(metrics_folsom).
56 | ok
57 | 4> metrics:new(counter, "c").
58 | ok
59 | 5> metrics:update("c").
60 | ok
61 | 6> folsom_metrics:get_metric_value("c").
62 | 1
63 | 7> metrics:update("c", {c, 1}).
64 | ok
65 | 8> folsom_metrics:get_metric_value("c").
66 | 2
67 | 
68 | 69 | 70 | 71 | 72 | 73 | ## Documentation 74 | 75 | Full doc is available in the {@link metrics} module. 76 | 77 | ## Build 78 | 79 | ``` 80 | $ rebar3 compile 81 | ''' 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /doc/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* standard EDoc style sheet */ 2 | body { 3 | font-family: Verdana, Arial, Helvetica, sans-serif; 4 | margin-left: .25in; 5 | margin-right: .2in; 6 | margin-top: 0.2in; 7 | margin-bottom: 0.2in; 8 | color: #000000; 9 | background-color: #ffffff; 10 | } 11 | h1,h2 { 12 | margin-left: -0.2in; 13 | } 14 | div.navbar { 15 | background-color: #add8e6; 16 | padding: 0.2em; 17 | } 18 | h2.indextitle { 19 | padding: 0.4em; 20 | background-color: #add8e6; 21 | } 22 | h3.function,h3.typedecl { 23 | background-color: #add8e6; 24 | padding-left: 1em; 25 | } 26 | div.spec { 27 | margin-left: 2em; 28 | background-color: #eeeeee; 29 | } 30 | a.module { 31 | text-decoration:none 32 | } 33 | a.module:hover { 34 | background-color: #eeeeee; 35 | } 36 | ul.definitions { 37 | list-style-type: none; 38 | } 39 | ul.index { 40 | list-style-type: none; 41 | background-color: #eeeeee; 42 | } 43 | 44 | /* 45 | * Minor style tweaks 46 | */ 47 | ul { 48 | list-style-type: square; 49 | } 50 | table { 51 | border-collapse: collapse; 52 | } 53 | td { 54 | padding: 3 55 | } 56 | -------------------------------------------------------------------------------- /rebar.config: -------------------------------------------------------------------------------- 1 | {erl_opts, [debug_info]}. 2 | {deps, []}. 3 | 4 | 5 | {profiles, [ 6 | {test, [ 7 | {deps, [{exometer_core, "1.5.2"}]} 8 | ]}, 9 | 10 | {docs, 11 | [{deps, [ 12 | {edown, 13 | {git, "https://github.com/uwiger/edown.git", 14 | {tag, "0.8"}}} 15 | ]}, 16 | 17 | {edoc_opts, [{doclet, edown_doclet}, 18 | {packages, false}, 19 | {subpackages, true}, 20 | {top_level_readme, 21 | {"./README.md", "http://github.com/benoitc/erlang-metrics"}}]} 22 | ]}]}. 23 | -------------------------------------------------------------------------------- /rebar.lock: -------------------------------------------------------------------------------- 1 | []. 2 | -------------------------------------------------------------------------------- /src/metrics.app.src: -------------------------------------------------------------------------------- 1 | {application, 'metrics', 2 | [{description, "A generic interface to different metrics systems in Erlang."}, 3 | {vsn, "2.5.0"}, 4 | {registered, []}, 5 | {mod, {metrics, []}}, 6 | {applications, 7 | [kernel, 8 | stdlib 9 | ]}, 10 | {env,[{verify_directories, false}]}, 11 | {modules, []}, 12 | 13 | {maintainers, ["Benoit Chesneau"]}, 14 | {licenses, ["BSD"]}, 15 | {links, [{"Github", "https://github.com/benoitc/erlang-metrics"}]} 16 | ]}. 17 | -------------------------------------------------------------------------------- /src/metrics.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2016-2018, Benoit Chesneau. 2 | %% 3 | %% This file is part of erlang-metrics released under the BSD license. 4 | %% See the NOTICE for more information. 5 | 6 | -module(metrics). 7 | -author("Benoit Chesneau"). 8 | -behaviour(gen_server). 9 | -behaviour(application). 10 | 11 | %% API 12 | -export([new/2]). 13 | -export([update/1, update/2]). 14 | -export([update_or_create/3]). 15 | -export([backend/0, backend/1]). 16 | -export([delete/1]). 17 | 18 | -export([start_link/0]). 19 | 20 | %% application callbacks 21 | 22 | -export([start/2, stop/1]). 23 | 24 | 25 | %% gen_server callbacks 26 | -export([init/1, handle_call/3, handle_cast/2,handle_info/2,terminate/2, code_change/3]). 27 | 28 | -include_lib("syntax_tools/include/merl.hrl"). 29 | 30 | -define(SERVER, ?MODULE). 31 | 32 | -define(TAB, metrics). 33 | 34 | -record(state, {mod}). 35 | 36 | %%%=================================================================== 37 | %%% Types 38 | %%%=================================================================== 39 | 40 | -type metric_name() :: list(). 41 | -type metric() :: counter | histogram | gauge | meter | spiral | duration. 42 | -type value() :: any(). 43 | -type probe() :: {c, integer()} | timer_start | timer_end | {duration_fun, fun()} | value(). 44 | 45 | %%%=================================================================== 46 | %%% API 47 | %%%=================================================================== 48 | 49 | %% @doc initialise a metric 50 | -spec new(Metric, Name) -> Result when 51 | Metric :: metric(), 52 | Name :: metric_name(), 53 | Result :: ok. 54 | new(Type, Name) -> 55 | metrics_mod:new(Type, Name). 56 | 57 | %% @doc increment a counter with 1 58 | -spec update(Name) -> Result when 59 | Name :: metric_name(), 60 | Result :: ok | any(). 61 | update(Name) -> 62 | update(Name, {c, 1}). 63 | 64 | %% @doc update a metric 65 | -spec update(Name, Probe) -> Result when 66 | Name :: metric_name(), 67 | Probe :: probe(), 68 | Result :: ok | any(). 69 | update(Name, Probe) -> 70 | metrics_mod:update(Name, Probe). 71 | 72 | %% @doc update a metric and create it if it doesn't exists 73 | -spec update_or_create(Name, Probe, Metric) -> Result when 74 | Name :: metric_name(), 75 | Probe :: probe(), 76 | Metric :: metric(), 77 | Result :: ok | any(). 78 | update_or_create(Name, Probe, Type) -> 79 | metrics_mod:update_or_create(Name, Probe, Type). 80 | 81 | %% @doc delete a metric 82 | -spec delete(Name) -> Result when 83 | Name :: metric_name(), 84 | Result :: ok | any(). 85 | delete(Name) -> 86 | metrics_mod:delete(Name). 87 | 88 | 89 | %% @doc retrieve the current backend name 90 | -spec backend() -> atom(). 91 | backend() -> gen_server:call(?MODULE, get_backend). 92 | 93 | %% @doc set the backend to use 94 | -spec backend(atom()) -> ok. 95 | backend(Mod) -> 96 | _ = code:ensure_loaded(Mod), 97 | case erlang:function_exported(Mod, update, 3) of 98 | true -> ok; 99 | false -> erlang:error(bad_modmetric) 100 | end, 101 | gen_server:call(?MODULE, {set_backend, Mod}). 102 | 103 | 104 | 105 | -spec start_link() -> {ok, pid()}. 106 | start_link() -> 107 | gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). 108 | 109 | %%%=================================================================== 110 | %%% application callbacks 111 | %%%=================================================================== 112 | %%% 113 | -spec start(application:start_type(), any()) -> {ok, pid()}. 114 | start(_StartType, _StartArgs) -> 115 | 'metrics_sup':start_link(). 116 | 117 | -spec stop(atom()) -> ok. 118 | stop(_State) -> 119 | ok. 120 | 121 | 122 | %%%=================================================================== 123 | %%% gen_server callbacks 124 | %%%=================================================================== 125 | %%% 126 | 127 | init([]) -> 128 | Mod = metrics_mod(), 129 | Config = init_mod(Mod), 130 | ok = build_metrics_mod(Mod, Config), 131 | 132 | {ok, #state{mod=Mod}}. 133 | 134 | 135 | 136 | handle_call(get_backend, _From, State) -> 137 | {reply, State#state.mod, State}; 138 | handle_call({set_backend, Mod}, _From, State) -> 139 | if 140 | State#state.mod /= Mod -> 141 | Config = init_mod(Mod), 142 | build_metrics_mod(Mod, Config); 143 | true -> ok 144 | end, 145 | {reply, ok, State}. 146 | 147 | 148 | handle_cast(_Msg, State) -> {noreply, State}. 149 | 150 | 151 | handle_info(_Info, State) -> {noreply, State}. 152 | 153 | 154 | terminate(_Reason, _State) -> ok. 155 | 156 | code_change(_OldVsn, State, _Extra) -> {ok, State}. 157 | 158 | %%%=================================================================== 159 | %%% Internal functions 160 | %%%=================================================================== 161 | 162 | 163 | metrics_mod() -> 164 | Mod = application:get_env(metrics, metrics_mod, metrics_noop), 165 | _ = code:ensure_loaded(Mod), 166 | case erlang:function_exported(Mod, update, 3) of 167 | false -> 168 | error_logger:error_msg("bad metric module"), 169 | erlang:error(bad_modmetric); 170 | true -> 171 | Mod 172 | end. 173 | 174 | init_mod(Mod) -> 175 | case erlang:function_exported(Mod, init, 0) of 176 | false -> #{}; 177 | true -> Mod:init() 178 | end. 179 | 180 | build_metrics_mod(Mod, Config) when is_atom(Mod), is_map(Config) -> 181 | error_logger:info_msg("build metrics module: ~s~n", [Mod]), 182 | Module = ?Q("-module('metrics_mod')."), 183 | Exported = ?Q("-export(['new'/2, 'update'/2, 'update_or_create'/3, 'delete'/1])."), 184 | Functions = ?Q([ 185 | "new(Type, Name) -> _@Mod@:new(Type, Name, _@Config@).", 186 | 187 | "update(Name, Probe) -> _@Mod@:update(Name, Probe, _@Config@).", 188 | 189 | "update_or_create(Name, Probe, Type) ->", 190 | " _@Mod@:update_or_create(Name, Probe, Type, _@Config@).", 191 | 192 | "delete(Name) -> _@Mod@:delete(Name, _@Config@)." 193 | ]), 194 | Forms = lists:flatten([Module, Exported, Functions]), 195 | merl:compile_and_load(Forms, [verbose]), 196 | ok. 197 | -------------------------------------------------------------------------------- /src/metrics_exometer.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2016-2018, Benoit Chesneau. 2 | %% 3 | %% This file is part of erlang-metrics released under the BSD license. 4 | %% See the NOTICE for more information. 5 | %% 6 | %% @doc exometer backend 7 | 8 | 9 | -module(metrics_exometer). 10 | -author("Benoit Chesneau"). 11 | 12 | %% API 13 | -export([new/3, update/3, update_or_create/4, delete/2]). 14 | 15 | -spec new(atom(), any(), map()) -> ok | {error, metric_exists | unsupported_type}. 16 | new(counter, Name, _Config) -> 17 | ensure(Name, counter); 18 | new(histogram, Name, _Config) -> 19 | ensure(Name, histogram); 20 | new(gauge, Name, _Config) -> 21 | ensure(Name, gauge); 22 | new(meter, Name, _Config) -> 23 | ensure(Name, meter); 24 | new(spiral, Name, _Config) -> 25 | ensure(Name, spiral); 26 | new(duration, Name, _Config) -> 27 | ensure(Name, duration); 28 | new(_, _, _) -> 29 | {error, unsupported_type}. 30 | 31 | 32 | ensure(Name, Type) -> 33 | M = module(), 34 | M:ensure(Name, Type, []). 35 | 36 | 37 | update(Name, {c, I}, _Config) when is_integer(I) -> update(Name, I); 38 | update(Name, {duration_fun, Fun}, _Config) when is_function(Fun) -> 39 | update(Name, timer_start), 40 | try Fun() 41 | after update(Name, timer_end) 42 | end; 43 | update(Name, Val, _Config) -> update(Name, Val). 44 | 45 | update(Name, Val) -> 46 | M = module(), 47 | M:update(Name, Val). 48 | 49 | update_or_create(Name, {c, I}, Type, _Config) when is_integer(I) -> 50 | update_or_create(Name, I, Type); 51 | update_or_create(Name, {duration_fun, Fun}, Type, Config) when is_function(Fun) -> 52 | _ = ensure(Name, Type), 53 | update_or_create(Name, {duration_fun, Fun}, Config); 54 | update_or_create(Name, Val, Type, _Config) -> 55 | update_or_create(Name, Val, Type). 56 | 57 | 58 | update_or_create(Name, Val, Type) -> 59 | M = module(), 60 | M:update_or_create(Name, Val, Type, []). 61 | 62 | 63 | delete(Name, _Config) -> 64 | M = module(), 65 | M:delete(Name). 66 | 67 | module() -> exometer. 68 | -------------------------------------------------------------------------------- /src/metrics_folsom.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2016-2018, Benoit Chesneau. 2 | %% 3 | %% This file is part of erlang-metrics released under the BSD license. 4 | %% See the NOTICE for more information. 5 | 6 | %% @doc folsom backend 7 | 8 | -module(metrics_folsom). 9 | -author("Benoit Chesneau"). 10 | 11 | %% API 12 | -export([new/3, update/3, update_or_create/4, delete/2]). 13 | 14 | -spec new(atom(), any(), map()) -> ok | {error, term()}. 15 | new(counter, Name, _Config) -> 16 | M = module(), 17 | M:new_counter(Name); 18 | new(histogram, Name, _Config) -> 19 | M = module(), 20 | M:new_histogram(Name); 21 | new(gauge, Name, _Config) -> 22 | M = module(), 23 | M:new_gauge(Name); 24 | new(meter, Name, _Config) -> 25 | M = module(), 26 | M:new_meter(Name); 27 | new(spiral, Name, _Config) -> 28 | M = module(), 29 | M:new_spiral(Name); 30 | new(duration, Name, _Config) -> 31 | M = module(), 32 | M:new_duration(Name); 33 | new(_, _, _) -> 34 | {error, unsupported_type}. 35 | 36 | update(Name, {c, I}, _Config) when I >= 0 -> 37 | notify(Name, {inc, I}); 38 | update(Name, {c, I}, _Config) when I < 0 -> 39 | notify(Name, {dec, abs(I)}); 40 | update(Name, {duration_fun, Fun}, _Config) -> 41 | notify(Name, timer_start), 42 | try Fun() 43 | after notify(Name, timer_end) 44 | end; 45 | update(Name, Val, _Config) -> 46 | notify(Name, Val). 47 | 48 | notify(Name, Val) -> 49 | M = module(), 50 | M:notify(Name, Val). 51 | 52 | update_or_create(Name, Probe, Type, Config) -> 53 | case update(Name, Probe, Config) of 54 | ok -> ok; 55 | {error, Name, nonexistent_metric} -> 56 | new(Type, Name, Config), 57 | update(Name, Probe, Config); 58 | Error -> 59 | Error 60 | end. 61 | 62 | delete(Name, _Config) -> 63 | M = module(), 64 | M:delete_metric(Name). 65 | 66 | module() -> folsom_metrics. 67 | -------------------------------------------------------------------------------- /src/metrics_noop.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2016-2018, Benoit Chesneau. 2 | %% 3 | %% This file is part of barrel_metrics released under the BSD license. 4 | %% See the NOTICE for more information. 5 | %% 6 | %% @doc noop backend 7 | 8 | 9 | -module(metrics_noop). 10 | -author("Benoit Chesneau"). 11 | 12 | %% API 13 | -export([new/3, update/3, update_or_create/4, delete/2]). 14 | 15 | new(_Name, _Type, _Config) -> ok. 16 | update(_Name, _Probe, _Config) -> ok. 17 | update_or_create(_Name, _Probe, _Type, _Config) -> ok. 18 | delete(_Name, _Config) -> ok. 19 | -------------------------------------------------------------------------------- /src/metrics_process_tracker.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2016-2018, Benoit Chesneau. 2 | %% 3 | %% This file is part of erlang-metrics released under the BSD license. 4 | %% See the NOTICE for more information. 5 | 6 | 7 | %% @doc module to track processes associated to a counter 8 | 9 | -module(metrics_process_tracker). 10 | -behaviour(gen_server). 11 | 12 | %% public API 13 | -export([track/1, track/2]). 14 | 15 | %% internal API 16 | -export([start_link/0]). 17 | 18 | %% gen_server call backs 19 | -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, 20 | terminate/2]). 21 | 22 | -include_lib("stdlib/include/ms_transform.hrl"). 23 | 24 | -define(TAB, metrics). 25 | -record(state, {}). 26 | 27 | %% @doc track the number of processes for a name 28 | %% this add the current process 29 | -spec track(any()) -> ok | {error, term()}. 30 | track(Name) -> 31 | track(Name, self()). 32 | 33 | %% @doc track the number of processes for a name 34 | -spec track(any(), pid()) -> ok | {error, term()}. 35 | track(Name, Pid) -> 36 | %% we only increment once the value 37 | case ets:insert_new(?TAB, {{Pid, Name}, Name}) of 38 | true -> metrics:update(Name); 39 | false -> ok 40 | end, 41 | 42 | %% maybe monitor the pid 43 | case ets:insert_new(?TAB, {Pid, m}) of 44 | true -> gen_server:cast(?MODULE, {monitor, Pid}); 45 | false -> ok 46 | end. 47 | 48 | % ---------------------------------------------------------- 49 | % - internal api 50 | % ---------------------------------------------------------- 51 | start_link() -> 52 | _ = create_tabs(), 53 | gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). 54 | 55 | 56 | create_tabs() -> 57 | case ets:info(?TAB, name) of 58 | undefined -> 59 | ?TAB = ets:new(?TAB, [named_table, ordered_set, public, 60 | {write_concurrency, true}, 61 | {read_concurrency, true}]); 62 | _ -> 63 | true 64 | end. 65 | 66 | % ---------------------------------------------------------- 67 | % - gen_server api 68 | % ---------------------------------------------------------- 69 | init(_) -> 70 | init_monitors(), 71 | {ok, #state{}}. 72 | 73 | handle_call(_Msg, _From, State) -> 74 | {reply, bad_call, State}. 75 | 76 | handle_cast({monitor, Pid}, State) -> 77 | _ = erlang:monitor(process, Pid), 78 | {noreply, State}. 79 | 80 | handle_info({'DOWN', _, _, Pid, _}, State) -> 81 | _ = process_is_down(Pid), 82 | {noreply, State}. 83 | 84 | terminate(_Reason, _State) -> 85 | ok. 86 | 87 | code_change(_OldVsn, State, _Extra) -> 88 | {ok, State}. 89 | 90 | 91 | % ---------------------------------------------------------- 92 | % - private api 93 | % ---------------------------------------------------------- 94 | 95 | %% @private 96 | process_is_down(Pid) -> 97 | case ets:take(?TAB, Pid) of 98 | [] -> 99 | ok; 100 | [{Pid, m}] -> 101 | Cond = ets:fun2ms(fun({{A, B}, _}) when A =:= Pid -> B end), 102 | Names = ets:select(?TAB, Cond), 103 | case Names of 104 | [] -> ok; 105 | _ -> 106 | lists:foreach(fun(Name) -> 107 | metrics:update(Name, {c, -1}), 108 | ets:delete(?TAB, {Pid, Name}) 109 | end, Names) 110 | end 111 | end. 112 | 113 | init_monitors() -> 114 | Cond = ets:fun2ms(fun({A, B}) when B =:= m -> A end), 115 | Pids = ets:select(?TAB, Cond), 116 | [erlang:monitor(process, Pid) || Pid <- Pids]. 117 | -------------------------------------------------------------------------------- /src/metrics_sup.erl: -------------------------------------------------------------------------------- 1 | 2 | %% Created by benoitc on 26/06/16. 3 | 4 | -module(metrics_sup). 5 | -author("Benoit Chesneau"). 6 | 7 | -behaviour(supervisor). 8 | 9 | %% API 10 | -export([start_link/0]). 11 | 12 | %% Supervisor callbacks 13 | -export([init/1]). 14 | 15 | -define(SERVER, ?MODULE). 16 | 17 | %%%=================================================================== 18 | %%% API functions 19 | %%%=================================================================== 20 | 21 | -spec start_link() -> {ok, pid()} | {error, term()}. 22 | start_link() -> 23 | supervisor:start_link({local, ?SERVER}, ?MODULE, []). 24 | 25 | %%%=================================================================== 26 | %%% Supervisor callbacks 27 | %%%=================================================================== 28 | 29 | -spec init(any()) -> 30 | {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. 31 | init([]) -> 32 | Metrics = {metrics, 33 | {metrics, start_link, []}, 34 | permanent, brutal_kill, worker,[metrics]}, 35 | 36 | ProcessTracker = {metrics_process_tracker, 37 | {metrics_process_tracker, start_link, []}, 38 | permanent, brutal_kill, worker,[metrics_process_tracker]}, 39 | 40 | 41 | {ok, {{one_for_one, 4, 3600}, [Metrics, ProcessTracker]}}. 42 | 43 | %%%=================================================================== 44 | %%% Internal functions 45 | %%%=================================================================== 46 | 47 | -------------------------------------------------------------------------------- /support/rebar3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/erlang-metrics/3ea572b5b6ca4a3e5dfc12009058f8771baf5789/support/rebar3 -------------------------------------------------------------------------------- /test/metrics_tests.erl: -------------------------------------------------------------------------------- 1 | %% Copyright (c) 2016, Benoit Chesneau. 2 | %% 3 | %% This file is part of barrel_metrics released under the BSD license. 4 | %% See the NOTICE for more information. 5 | 6 | %% Created by benoitc on 26/06/16. 7 | 8 | -module(metrics_tests). 9 | -author("Benoit Chesneau"). 10 | 11 | 12 | -include_lib("eunit/include/eunit.hrl"). 13 | 14 | setup() -> 15 | {ok, _} = application:ensure_all_started(metrics), 16 | {ok, _} = application:ensure_all_started(folsom), 17 | {ok, _} = application:ensure_all_started(exometer_core), 18 | ok. 19 | 20 | teardown(_) -> 21 | application:stop(folsom), 22 | application:stop(exometer_core), 23 | application:stop(metrics), 24 | ok. 25 | 26 | 27 | folsom_test_() -> 28 | { 29 | "Folsom backend test", 30 | {foreach, 31 | fun setup/0, fun teardown/1, 32 | [ 33 | 34 | fun folsom_counter_test_/1, 35 | fun folsom_counter_test_inc_/1, 36 | fun folsom_counter_test_mul_/1, 37 | fun folsom_gauge_test_/1, 38 | fun folsom_update_or_create_/1, 39 | fun folsom_delete_/1 40 | ] 41 | } 42 | }. 43 | 44 | 45 | exometer_test_() -> 46 | { 47 | "Exometer backend test", 48 | {foreach, 49 | fun setup/0, fun teardown/1, 50 | [ 51 | 52 | fun exometer_counter_test_/1, 53 | fun exometer_counter_test_inc_/1, 54 | fun exometer_counter_test_mul_/1, 55 | fun exometer_gauge_test_/1, 56 | fun exometer_update_or_create_/1, 57 | fun exometer_delete_/1 58 | ] 59 | } 60 | }. 61 | 62 | folsom_counter_test_(_) -> 63 | ok = metrics:backend(metrics_folsom), 64 | ok = metrics:new(counter, "c"), 65 | metrics:update("c"), 66 | ?_assertEqual(1, folsom_metrics:get_metric_value("c")). 67 | 68 | folsom_counter_test_inc_(_) -> 69 | ok = metrics:backend(metrics_folsom), 70 | ok = metrics:new(counter, "c"), 71 | metrics:update("c", {c, 1}), 72 | ?_assertEqual(1, folsom_metrics:get_metric_value("c")). 73 | 74 | folsom_counter_test_mul_(_) -> 75 | ok = metrics:backend(metrics_folsom), 76 | ok = metrics:new(counter, "c"), 77 | metrics:update("c", {c, 1}), 78 | metrics:update("c", {c, 1}), 79 | metrics:update("c", {c, 4}), 80 | metrics:update("c", {c, -1}), 81 | ?_assertEqual(5, folsom_metrics:get_metric_value("c")). 82 | 83 | folsom_gauge_test_(_) -> 84 | ok = metrics:backend(metrics_folsom), 85 | ok = metrics:new(gauge, "g"), 86 | metrics:update("g", 1), 87 | ?_assertEqual(1, folsom_metrics:get_metric_value("g")). 88 | 89 | folsom_update_or_create_(_) -> 90 | ok = metrics:backend(metrics_folsom), 91 | metrics:update_or_create("new_counter", {c, 1}, counter), 92 | ?_assertEqual(1, folsom_metrics:get_metric_value("new_counter")). 93 | 94 | folsom_delete_(_) -> 95 | ok = metrics:backend(metrics_folsom), 96 | ok = metrics:new(gauge, "g"), 97 | ok = metrics:new(counter, "c"), 98 | ok = metrics:delete("g"), 99 | ?_assertEqual(["c"], folsom_metrics:get_metrics()). 100 | 101 | exometer_counter_test_(_) -> 102 | ok = metrics:backend(metrics_exometer), 103 | ok = metrics:new(counter, "c1"), 104 | metrics:update("c1"), 105 | ?_assertMatch({ok, [{value, 1}, _]}, exometer:get_value("c1")). 106 | 107 | exometer_counter_test_inc_(_) -> 108 | ok = metrics:backend(metrics_exometer), 109 | ok = metrics:new(counter, "c1"), 110 | metrics:update("c1", {c, 1}), 111 | ?_assertMatch({ok, [{value, 1}, _]}, exometer:get_value("c1")). 112 | 113 | exometer_counter_test_mul_(_) -> 114 | ok = metrics:backend(metrics_exometer), 115 | ok = metrics:new(counter, "c1"), 116 | metrics:update("c1", {c, 1}), 117 | metrics:update("c1", {c, 1}), 118 | metrics:update("c1", {c, 4}), 119 | metrics:update("c1", {c, -1}), 120 | ?_assertMatch({ok, [{value, 5}, _]}, exometer:get_value("c1")). 121 | 122 | exometer_gauge_test_(_) -> 123 | ok = metrics:backend(metrics_exometer), 124 | ok = metrics:new(gauge, "g1"), 125 | metrics:update("g1", 1), 126 | ?_assertMatch({ok, [{value, 1}, _]}, exometer:get_value("g1")). 127 | 128 | exometer_update_or_create_(_) -> 129 | ok = metrics:backend(metrics_exometer), 130 | metrics:update_or_create("new_exo_counter", {c, 1}, counter), 131 | ?_assertMatch({ok, [{value, 1}, _]}, exometer:get_value("new_exo_counter")). 132 | 133 | exometer_delete_(_) -> 134 | ok = metrics:backend(metrics_exometer), 135 | ok = metrics:new(gauge, "g"), 136 | ok = metrics:new(counter, "c"), 137 | ok = metrics:delete("g"), 138 | ?_assertEqual(undefined, exometer:info("g", status)). 139 | --------------------------------------------------------------------------------