Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to start exometer graphite reporter via app.config file #481

Merged
merged 7 commits into from
Aug 7, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions apps/ejabberd/src/ejabberd_app.erl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ start(normal, _Args) ->
maybe_start_alarms(),
connect_nodes(),
{ok, _} = Sup = ejabberd_sup:start_link(),
init_metrics(),
mongoose_metrics:init(),
ejabberd_system_monitor:add_handler(),
ejabberd_rdbms:start(),
ejabberd_auth:start(),
Expand Down Expand Up @@ -240,10 +240,3 @@ load_drivers([Driver | Rest]) ->
[erl_ddll:format_error(Reason)]),
exit({driver_loading_failed, Driver, Reason})
end.

init_metrics() ->
mongoose_metrics:create_global_metrics(),
lists:foreach(
fun(Host) ->
mongoose_metrics:init_predefined_host_metrics(Host)
end, ?MYHOSTS).
86 changes: 33 additions & 53 deletions apps/ejabberd/src/mongoose_metrics.erl
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
-include("ejabberd.hrl").

%% API
-export([update/2,
start_graphite_reporter/1,
start_graphite_reporter/2,
-export([init/0,
update/2,
start_host_metrics_subscriptions/3,
start_vm_metrics_subscriptions/2,
start_global_metrics_subscriptions/2,
Expand All @@ -41,39 +40,40 @@
remove_host_metrics/1,
remove_all_metrics/0]).

-spec init() -> ok.
init() ->
create_global_metrics(),
lists:foreach(
fun(Host) ->
mongoose_metrics:init_predefined_host_metrics(Host)
end, ?MYHOSTS),
Reporters = exometer_report:list_reporters(),
lists:foreach(
fun({Name, _ReporterPid}) ->
Interval = application:get_env(exometer, mongooseim_report_interval, 60000),
subscribe_to_all(Name, Interval)
end, Reporters).

-spec update({term(), term()}, term()) -> no_return().
update(Name, Change) when is_tuple(Name)->
update(tuple_to_list(Name), Change);
update(Name, Change) ->
exometer:update(Name, Change).

start_graphite_reporter(GraphiteHost) ->
start_graphite_reporter(GraphiteHost, []).
start_graphite_reporter(GraphiteHost, Opts) ->
GraphiteOpts = [{prefix, "exometer." ++ atom_to_list(node())},
{host, GraphiteHost}]
++ merge_opts(Opts),
case exometer_report:add_reporter(exometer_report_graphite, GraphiteOpts) of
ok ->
{ok, exometer_report_graphite};
Error ->
Error
end.

start_host_metrics_subscriptions(Reporter, Host, Interval) ->
do_start_metrics_subscriptions(check_reporter(Reporter), Interval, [Host]).
do_start_metrics_subscriptions(Reporter, Interval, [Host]).

start_vm_metrics_subscriptions(Reporter, Interval) ->
do_start_vm_metrics_subscriptions(check_reporter(Reporter), Interval).
do_start_vm_metrics_subscriptions(Reporter, Interval).

start_global_metrics_subscriptions(Reporter, Interval) ->
do_start_global_metrics_subscriptions(check_reporter(Reporter), Interval).
do_start_global_metrics_subscriptions(Reporter, Interval).

start_data_metrics_subscriptions(Reporter, Interval) ->
do_start_metrics_subscriptions(check_reporter(Reporter), Interval, [data]).
do_start_metrics_subscriptions(Reporter, Interval, [data]).

start_backend_metrics_subscriptions(Reporter, Interval) ->
do_start_metrics_subscriptions(check_reporter(Reporter), Interval, [backends]).
do_start_metrics_subscriptions(Reporter, Interval, [backends]).

get_host_metric_names(Host) ->
[MetricName || {[_Host, MetricName | _], _, _} <- exometer:find_entries([Host])].
Expand Down Expand Up @@ -401,34 +401,17 @@ get_vm_stats() ->
get_counters(Host, Counters) ->
[{Host, Counter} || Counter <- Counters].

check_reporter(Reporter) ->
Reporters = exometer_report:list_reporters(),
case lists:keyfind(Reporter, 1, Reporters) of
{Reporter, _} ->
{ok, Reporter};
_ ->
{error, {no_such_reporter}}
end.


do_start_vm_metrics_subscriptions({ok, Reporter}, Interval) ->
do_start_vm_metrics_subscriptions(Reporter, Interval) ->
[exometer_report:subscribe(Reporter, Metric, DataPoints, Interval)
|| {Metric, _, DataPoints} <- get_vm_stats()];
do_start_vm_metrics_subscriptions(Error, _) ->
Error.
|| {Metric, _, DataPoints} <- get_vm_stats()].

do_start_global_metrics_subscriptions({ok, Reporter}, Interval) ->
do_start_global_metrics_subscriptions(Reporter, Interval) ->
[exometer_report:subscribe(Reporter, Metric, default, Interval)
|| {Metric, _} <- ?GLOBAL_COUNTERS];
do_start_global_metrics_subscriptions(Error, _) ->
Error.
|| {Metric, _} <- ?GLOBAL_COUNTERS].

do_start_metrics_subscriptions({ok, Reporter}, Interval, MetricPrefix) ->
do_start_metrics_subscriptions(Reporter, Interval, MetricPrefix) ->
[subscribe_metric(Reporter, Metric, Interval)
|| Metric <- exometer:find_entries(MetricPrefix)];
do_start_metrics_subscriptions(Error, _, _) ->
Error.

|| Metric <- exometer:find_entries(MetricPrefix)].

subscribe_metric(Reporter, {Name, counter, _}, Interval) ->
exometer_report:subscribe(Reporter, Name, [value], Interval);
Expand All @@ -437,12 +420,9 @@ subscribe_metric(Reporter, {Name, histogram, _}, Interval) ->
subscribe_metric(Reporter, {Name, _, _}, Interval) ->
exometer_report:subscribe(Reporter, Name, default, Interval).

merge_opts(Opts) ->
Defaults = [{connect_timeout, 5000},
{port, 2003},
{api_key, ""}],

MergeFun = fun(_, _, V2) -> V2 end,
orddict:to_list(orddict:merge(MergeFun,
orddict:from_list(Defaults),
orddict:from_list(Opts))).
subscribe_to_all(Reporter, Interval) ->
start_global_metrics_subscriptions(Reporter, Interval),
lists:foreach(
fun(Host) ->
start_host_metrics_subscriptions(Reporter, Host, Interval)
end, ?MYHOSTS).
2 changes: 1 addition & 1 deletion doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
* [Reloading configuration on a running system](operation-and-maintenance/Reloading-configuration-on-a-running-system.md)
* For developers
* [Hooks and handlers](developers-guide/Hooks-and-handlers.md)
* [Folsom Metrics](developers-guide/REST-interface-to-metrics.md)
* [REST Interface to Metrics](developers-guide/REST-interface-to-metrics.md)
* [mod_amp developer's guide](developers-guide/mod_amp_developers_guide.md)

2 changes: 1 addition & 1 deletion doc/advanced-configuration/Listener-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Currently it is not possible to use different ports e.g. for BOSH and Websockets
* `modules` (list of tuples: `{Host, Path, Modules}`) - List of enabled HTTP-based modules. `"_"` equals any host.
* `mod_bosh` - BOSH connections handler. Default declaration: `{"_", "/http-bind", mod_bosh}`
* `mod_websockets` - Websocket connections, both [old](http://xmpp.org/extensions/xep-0206.html) and [new](http://datatracker.ietf.org/doc/draft-ietf-xmpp-websocket/?include_text=1) type. Default declaration: `{"_", "/ws-xmpp", mod_websockets}`
* `mod_metrics` - REST API for accessing internal MongooseIM metrics. Please refer to [REST interface to metrics](../developers-guide/REST-interface-to-metrics.md) for more information. Default declaration: `{"localhost", "/metrics", mod_metrics}`.
* `mongoose_api` - REST API for accessing internal MongooseIM metrics. Please refer to [REST interface to metrics](../developers-guide/REST-interface-to-metrics.md) for more information. Default declaration: `{"localhost", "/api", mongoose_api, [{handlers, [mongoose_api_metrics]}]}`.

## ejabberd_s2s_in

Expand Down
12 changes: 0 additions & 12 deletions doc/modules/mod_metrics.md

This file was deleted.

56 changes: 49 additions & 7 deletions doc/operation-and-maintenance/Logging-&-monitoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ Logs
---

It is a good idea to store logs in one centralized place when working in a clustered environment.
MongooseIM uses Lager - the logging framework. Its backend can be easy replaced.
MongooseIM uses Lager - the logging framework. Its backend can be easily replaced.
Some of the recommended backends are:

- https://github.com/basho/lager_syslog to use syslog and
- https://github.com/basho/lager_syslog to use syslog and
- https://github.com/mhald/lager_logstash_backend for logstash (http://logstash.net/).

To change the backend you have to edit `rel/files/app.config`. Before that you need
Expand Down Expand Up @@ -33,17 +33,59 @@ To monitor MongooseIM during load testing we recommend the following open source
- Graphite (http://graphite.wikidot.com/) is used for data presentation
- collectd (http://collectd.org/) is a daemon running on monitored nodes capturing data related to CPU and Memory usage, IO etc.

### mod_metrics
### mod_api_metrics

It provides REST interface for Mongoose's metrics, so it can be easily integrated
with other services.

You can read more about it here:

https://github.com/esl/MongooseIM/wiki/REST-interface-to-folsom-metrics
You can read more about it here: [REST interface to metrics](/developers-guide/REST-interface-to-metrics)

### Wombat OAM

WombatOAM is an operations and maintenance framework for Erlang based systems. Its Web Dashboard displays this data in an aggregated manner and provides interfaces to feed the data to other OAM tools such as Graphite, Nagios or Zabbix.

For more information see:
https://www.erlang-solutions.com/products/wombat
https://www.erlang-solutions.com/products/wombat

### Built-in Exometer reporters

MongooseIM uses the Exometer libary for collecting the metrics. Exometer has many
build-in reporters that can send metrics to external services like:

* graphite
* amqp
* statsd
* snmp
* opentsdb

It is possible to enable them in Moongoose via the `app.config` file. The file sits next
to the `ejabberd.cfg` file and both files are located in the `rel/files` and `_REL_DIR_/etc` directories.
For more details, please visit the Exometer's project page: [ExometerProject](https://github.com/Feuerlabs/exometer).

**Note that we are using the 1.1 version.**

Below you can find sample configuration, it setups graphite reporter which connects
to graphite running on localhost.

You can see an additional option not listed in the Exometer docs - `mongooseim_report_interval`.
That option sets metrics resolution - in other words: how often Exometer gathers and sends metrics
through reporters. By default that is 60 seconds.

```erl
...
{exometer, [
{mongooseim_report_interval, 60000}, %% 60 seconds
{report, [
{reporters, [
{exometer_report_graphite, [
{prefix, "mongooseim"},
{connect_timeout, 5000},
{host, "127.0.0.1"},
{port, 2003},
{api_key, ""}
]}
]}
]}
]}
...
```
1 change: 0 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ pages:
- 'mod_disco': 'modules/mod_disco.md'
- 'mod_last': 'modules/mod_last.md'
- 'mod_mam': 'modules/mod_mam.md'
- 'mod_metrics': 'modules/mod_metrics.md'
- 'mod_muc': 'modules/mod_muc.md'
- 'mod_muc_log': 'modules/mod_muc_log.md'
- 'mod_offline': 'modules/mod_offline.md'
Expand Down
14 changes: 14 additions & 0 deletions rel/files/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@
{lager_file_backend, [{file, "log/ejabberd.log"}, {level, info}, {size, 2097152}, {date, "$D0"}, {count, 5}]}
]}
]}
%{exometer, [
% {mongooseim_report_interval, 60000}, %% 60 seconds
% {report, [
% {reporters, [
% {exometer_report_graphite, [
% {prefix, "mongooseim"},
% {connect_timeout, 5000},
% {host, "127.0.0.1"},
% {port, 2003},
% {api_key, ""}
% ]}
% ]}
% ]}
% ]}
].

%% vim: filetype=erlang