Megatron library sends Terracotta statistics and notifications to a management backend through REST, StatsD and other means
This project is maintained by mathieucarbou
Megatron is a Terracotta server plugin that enables to query or stream statistics and notifications from the platform and clients to an external monitoring system like NewRelic, Librato, Datadog, Graphite, any StatsD collector, etc.
Installation of megatron on a clustered Terracotta server allows to collect all server-side statistics plus all client-side statistics as long as the client application has enabled management.
server/plugins/lib
directory into your Terracotta Ehcache Kit (http://www.ehcache.org/downloads/).tc-config.xml
file to add one or several properties to enable plugins. See server/tc-config-sample.xml
as an example.Note: some platforms, like Librato, NewRelix, Datadog, etc, require a StatsD server to be used. The official StatsD server can be found at https://github.com/etsy/statsd
After installation, just edit the properties for the plugins you want to activate.
Megatron is only enabled on active servers.
Passive servers always send their data to the current active. So in case of a failover, it will change nothing for the plugins streaming data to some servers: the emitter will just change. But for plugins like the REST plugin, then you’ll gave to connect to the newly active server.
Your applciation needs to depend on the libraries in client/lib
, specifically:
megatron-api
megatron-ehcache
Programmatic configuration
CacheManager cacheManager = newCacheManagerBuilder()
// management config
.using(new DefaultManagementRegistryConfiguration()
.addTags("webapp-1", "server-node-1")
.setCacheManagerAlias("cm1"))
// Megatron config
.using(new DefaultMegatronServiceConfiguration()
.setStatisticCollectorInterval(5, TimeUnit.SECONDS)
.loadProperties(ProgrammaticExample.class.getResource("/megatron.properties"))
.setProperty("megatron.console.enable", "true"))
//[...]
.build(true);
XML configuration
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xmlns:mnm='http://www.ehcache.org/v3/management'
xmlns:m='https://mathieucarbou.github.io/megatron/ehcache/v1'>
<service>
<mnm:management cache-manager-alias="cm1">
<mnm:tags>
<mnm:tag>webapp-1</mnm:tag>
<mnm:tag>server-node-1</mnm:tag>
</mnm:tags>
</mnm:management>
</service>
<service>
<m:megatron>
<m:statisticCollectorInterval unit="seconds">5</m:statisticCollectorInterval>
<m:properties>
<!-- Console plugin-->
<m:set name="megatron.console.enable" value="true"/>
<!-- REST plugin -->
<m:set name="megatron.rest.enable" value="true"/>
<m:set name="megatron.rest.bindAddress" value="0.0.0.0"/>
<m:set name="megatron.rest.port" value="9470"/>
<!-- Prometheus PushGateway Plugin -->
<m:set name="megatron.prometheus.gateway.enable" value="true"/>
<m:set name="megatron.prometheus.gateway.url" value="http://localhost:9091/metrics/job/megatron"/>
<m:set name="megatron.prometheus.gateway.prefix" value="megatron"/>
<m:set name="megatron.prometheus.gateway.tags" value="stripe="stripe1",cluster="MyCluster""/>
<m:set name="megatron.prometheus.gateway.async" value="true"/>
<m:set name="megatron.prometheus.gateway.queueSize" value="-1"/>
</m:properties>
</m:megatron>
</service>
<cache alias="cache-1">
<key-type>java.lang.String</key-type>
<value-type>[B</value-type>
<resources>
<heap unit="entries">50</heap>
<offheap unit="MB">1</offheap>
</resources>
</cache>
</config>
Any megatron property can be also passed as a Java System Property or an Environment Variable.
For environment variables, property names must be set in upper-case and underscore replaces point.
Example:
If ou need to override megatron.console.enable=false
in the config file, then you can set the env, variable: MEGATRON_CONSOLE_ENABLE=false
Just outputs in the server console the received statistics and notifications.
Edit your tc-config.xml
file to add the plugin configurations:
<?xml version="1.0" encoding="UTF-8"?>
<tc-config xmlns="http://www.terracotta.org/config">
<plugins>
<config xmlns:mc='http://www.mycila.com/config/megatron-config'>
<mc:megatron-config>
<mc:statisticCollectorInterval unit="seconds">5</mc:statisticCollectorInterval>
<mc:set name="megatron.console.enable" value="true"/>
</mc:megatron-config>
</config>
</plugins>
</tc-config>
Edit your tc-config.xml
file to add the plugin configurations:
<?xml version="1.0" encoding="UTF-8"?>
<tc-config xmlns="http://www.terracotta.org/config">
<plugins>
<config xmlns:mc='http://www.mycila.com/config/megatron-config'>
<mc:megatron-config>
<mc:statisticCollectorInterval unit="seconds">5</mc:statisticCollectorInterval>
<mc:set name="megatron.rest.enable" value="true"/>
<mc:set name="megatron.rest.bindAddress" value="0.0.0.0"/>
<mc:set name="megatron.rest.port" value="9470"/>
</mc:megatron-config>
</config>
</plugins>
</tc-config>
# get active server name
curl http://active:9470/api/v1/platform/server
# trigger a server state dump on the server logs
curl http://active:9470/api/v1/platform/dump
# get the server XML config
curl http://active:9470/api/v1/platform/config
# get the stripe live topology
curl http://active:9470/api/v1/topology
# get the live servers
curl http://active:9470/api/v1/topology/servers
# get the live clients
curl http://active:9470/api/v1/topology/clients
# get the live ehcache clients
curl http://active:9470/api/v1/topology/clients/ehcache
# get statistics
curl http://active:9470/api/v1/statistics
curl http://active:9470/api/v1/statistics?statNames=Cache:UpdateCount,Cache:MissCount
curl http://active:9470/api/v1/statistics/clients/{clientId}
curl http://active:9470/api/v1/statistics/clients/{clientId}?statNames=Cache:UpdateCount,Cache:MissCount
curl http://active:9470/api/v1/statistics/clients/{clientId}/cacheManagers/{cmName}
curl http://active:9470/api/v1/statistics/clients/{clientId}/cacheManagers/{cmName}?statNames=Cache:UpdateCount,Cache:MissCount
curl http://active:9470/api/v1/statistics/clients/{clientId}/cacheManagers/{cmName}/caches/{cName}
curl http://active:9470/api/v1/statistics/clients/{clientId}/cacheManagers/{cmName}/caches/{cName}?statNames=Cache:UpdateCount,Cache:MissCount
The Datadog plugin supports metrics tagging to facilitate aggregation filtering.
The format of the data sent is: metric.name:value|type|@sample_rate|#tag1:value,tag2
.
See https://docs.datadoghq.com/guides/dogstatsd/.
tc-config.xml
file to add the plugin configurations:<?xml version="1.0" encoding="UTF-8"?>
<tc-config xmlns="http://www.terracotta.org/config">
<plugins>
<config xmlns:mc='http://www.mycila.com/config/megatron-config'>
<mc:megatron-config>
<mc:statisticCollectorInterval unit="seconds">5</mc:statisticCollectorInterval>
<mc:set name="megatron.datadog.enable" value="true"/>
<mc:set name="megatron.datadog.server" value="localhost"/>
<mc:set name="megatron.datadog.port" value="8125"/>
<mc:set name="megatron.datadog.prefix" value="megatron"/>
<mc:set name="megatron.datadog.tags" value="stripe:stripe1,cluster:MyCluster"/>
<mc:set name="megatron.datadog.async" value="true"/>
<mc:set name="megatron.datadog.queueSize" value="-1"/>
</mc:megatron-config>
</config>
</plugins>
</tc-config>
megatron.datadog.server
is your Datadog Agent address that is running a StatsD server (https://docs.datadoghq.com/guides/dogstatsd/).
You can run one by executing:
docker run -d --name dd-agent -v /var/run/docker.sock:/var/run/docker.sock:ro -v /proc/:/host/proc/:ro -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro -e API_KEY=<YOUR_DATADOG_API_KEY> -e SD_BACKEND=docker -p 8125:8125/udp datadog/docker-dd-agent:latest
Be careful to set your YOUR_DATADOG_API_KEY
.
See https://app.datadoghq.com/account/settings#agent/docker
The Librato plugin supports metrics tagging to facilitate aggregation filtering.
Metrics are sent in the Graphite form: my.metric#service=web,app_version=1.12:42
.
See https://www.librato.com/docs/kb/collect/collection_agents/stastd/.
tc-config.xml
file to add the plugin configurations:<?xml version="1.0" encoding="UTF-8"?>
<tc-config xmlns="http://www.terracotta.org/config">
<plugins>
<config xmlns:mc='http://www.mycila.com/config/megatron-config'>
<mc:megatron-config>
<mc:statisticCollectorInterval unit="seconds">5</mc:statisticCollectorInterval>
<mc:set name="megatron.librato.enable" value="true"/>
<mc:set name="megatron.librato.server" value="localhost"/>
<mc:set name="megatron.librato.port" value="8125"/>
<mc:set name="megatron.librato.prefix" value="megatron"/>
<mc:set name="megatron.librato.tags" value="stripe=stripe1,cluster=MyCluster"/>
<mc:set name="megatron.librato.async" value="true"/>
<mc:set name="megatron.librato.queueSize" value="-1"/>
</mc:megatron-config>
</config>
</plugins>
</tc-config>
megatron.librato.server
is your Etsy/StatsD server configured to work with Librato backend (see provided configuration sample):
{
port: 8125,
keyNameSanitize: false,
backends: ["statsd-librato-backend"],
// See https://github.com/librato/statsd-librato-backend
librato: {
email: "your_librato_email",
token: "your_librato_api_key",
skipInternalMetrics: false
}
}
The Graphite plugin supports metrics tagging to facilitate aggregation filtering.
Metrics are sent in the Graphite form: [prefix.name][;tag1=value1;tag2=value2] [value] [timestamp]
.
See http://graphite.readthedocs.io/en/latest/feeding-carbon.html.
Requires Graphite/Carbon 1.1.x.
Edit your tc-config.xml
file to add the plugin configurations:
<?xml version="1.0" encoding="UTF-8"?>
<tc-config xmlns="http://www.terracotta.org/config">
<plugins>
<config xmlns:mc='http://www.mycila.com/config/megatron-config'>
<mc:megatron-config>
<mc:statisticCollectorInterval unit="seconds">5</mc:statisticCollectorInterval>
<mc:set name="megatron.graphite.enable" value="true"/>
<mc:set name="megatron.graphite.server" value="localhost"/>
<mc:set name="megatron.graphite.port" value="2003"/>
<mc:set name="megatron.graphite.prefix" value="megatron"/>
<mc:set name="megatron.graphite.tags" value="stripe=stripe1;cluster=MyCluster"/>
<mc:set name="megatron.graphite.async" value="true"/>
<mc:set name="megatron.graphite.queueSize" value="-1"/>
</mc:megatron-config>
</config>
</plugins>
</tc-config>
megatron.graphite.server
is your Graphite server
The StatsD plugin does not supports metrics tagging. Metrics are sent in the form: [prefix.name]:[value]|[type]
Edit your tc-config.xml
file to add the plugin configurations:
<?xml version="1.0" encoding="UTF-8"?>
<tc-config xmlns="http://www.terracotta.org/config">
<plugins>
<config xmlns:mc='http://www.mycila.com/config/megatron-config'>
<mc:megatron-config>
<mc:statisticCollectorInterval unit="seconds">5</mc:statisticCollectorInterval>
<mc:set name="megatron.statsd.enable" value="true"/>
<mc:set name="megatron.statsd.server" value="localhost"/>
<mc:set name="megatron.statsd.port" value="8125"/>
<mc:set name="megatron.statsd.prefix" value="megatron"/>
<mc:set name="megatron.statsd.async" value="true"/>
<mc:set name="megatron.statsd.queueSize" value="-1"/>
</mc:megatron-config>
</config>
</plugins>
</tc-config>
megatron.statsd.server
is your Etsy/StatsD server configured to work with any StatsD backend.
List StatsD backends (non exhaustive): https://github.com/etsy/statsd/blob/master/docs/backend.md
There are several examples of StatsD backend configurations in the distribution module
{
port: 8125,
backends: ["./backends/graphite"],
// graphite support
graphiteHost: 'localhost',
graphitePort: 2003,
globalPrefix: '',
}
{
port: 8125,
backends: ['statsd-ganglia-backend'],
// Ganglia: https://github.com/jbuchbinder/statsd-ganglia-backend
ganglia: {
host: 'localhost',
port: 8649,
}
}
{
port: 8125,
backends: ['statsd-newrelic-backend'],
// NewRelic: https://github.com/mpayetta/statsd-newrelic-backend
newRelicLicense: "your_newrelic_license_key",
newRelicApp: "your_newrelic_app_name",
dispatchers: ['customEvent', 'customMetric'],
}
The Prometheus StatsD plugin supports metrics tagging to facilitate aggregation filtering.
The format of the data sent is: metric.name:value|type|@sample_rate|#tag1:value,tag2
.
See https://github.com/prometheus/statsd_exporter.
tc-config.xml
file to add the plugin configurations:<?xml version="1.0" encoding="UTF-8"?>
<tc-config xmlns="http://www.terracotta.org/config">
<plugins>
<config xmlns:mc='http://www.mycila.com/config/megatron-config'>
<mc:megatron-config>
<mc:statisticCollectorInterval unit="seconds">5</mc:statisticCollectorInterval>
<mc:set name="megatron.prometheus.statsd.enable" value="true"/>
<mc:set name="megatron.prometheus.statsd.server" value="localhost"/>
<mc:set name="megatron.prometheus.statsd.port" value="9125"/>
<mc:set name="megatron.prometheus.statsd.prefix" value="megatron"/>
<mc:set name="megatron.prometheus.statsd.tags" value="stripe:stripe1,cluster:MyCluster"/>
<mc:set name="megatron.prometheus.statsd.async" value="true"/>
<mc:set name="megatron.prometheus.statsd.queueSize" value="-1"/>
</mc:megatron-config>
</config>
</plugins>
</tc-config>
megatron.prometheus.statsd.server
is your Prometheus StatsD Exporter server address (https://github.com/prometheus/statsd_exporter).
You can run one by executing:
docker pull prom/statsd-exporter
docker run -d -p 9102:9102 -p 9125:9125/udp \
-v $PWD/statsd_mapping.conf:/tmp/statsd_mapping.conf \
prom/statsd-exporter -statsd.mapping-config=/tmp/statsd_mapping.conf
See https://hub.docker.com/r/prom/statsd-exporter/
The Prometheus PushGateway plugin supports metrics tagging to facilitate aggregation filtering. See https://github.com/prometheus/pushgateway.
tc-config.xml
file to add the plugin configurations:<?xml version="1.0" encoding="UTF-8"?>
<tc-config xmlns="http://www.terracotta.org/config">
<plugins>
<config xmlns:mc='http://www.mycila.com/config/megatron-config'>
<mc:megatron-config>
<mc:statisticCollectorInterval unit="seconds">5</mc:statisticCollectorInterval>
<mc:set name="megatron.prometheus.gateway.enable" value="true"/>
<mc:set name="megatron.prometheus.gateway.url" value="http://localhost:9091/metrics/job/megatron"/>
<mc:set name="megatron.prometheus.gateway.prefix" value="megatron"/>
<mc:set name="megatron.prometheus.gateway.tags" value="stripe="stripe1",cluster="MyCluster""/>
<mc:set name="megatron.prometheus.gateway.async" value="true"/>
<mc:set name="megatron.prometheus.gateway.queueSize" value="-1"/>
</mc:megatron-config>
</config>
</plugins>
</tc-config>
megatron.prometheus.gateway.url
is your Prometheus PushGateway server address (https://github.com/prometheus/pushgateway).
You can run one by executing:
docker pull prom/pushgateway
docker run -d -p 9091:9091 prom/pushgateway
See https://github.com/prometheus/pushgateway
You can easily write a plugin: the API os really simple. Look at the current implementations in the project. It is as easy as writing a class like this one:
@Namespace("megatron.ganglia")
public class MegatronGangliaPlugin extends AbstractMegatronPlugin {
@Config private String server = "localhost";
@Config private int port = 8649;
@Config private String prefix = "megatron";
private GangliaClient client;
@Override
protected void enable(MegatronConfiguration configuration, MegatronApi api) {
client = new GangliaClient(prefix, server, port);
}
@Override
public void close() {
if (enable) {
client.stop();
}
}
@Override
public void onNotification(ContextualNotification notification) {
if (enable) {
logger.trace("onNotification({})", notification.getType());
String prefix = buildFullPrefix("events", notification);
client.count(prefix + notification.getType(), 1);
}
}
@Override
public void onStatistics(ContextualStatistics statistics) {
if (enable) {
logger.trace("onStatistics({})", statistics.size());
String prefix = buildFullPrefix("statistics", statistics);
for (Map.Entry<String, Number> entry : statistics.getStatistics().entrySet()) {
String statName = escape(entry.getKey());
Number value = entry.getValue();
if (value instanceof Double || value instanceof Float) {
client.gauge(prefix + statName, value.doubleValue());
} else {
client.gauge(prefix + statName, value.longValue());
}
}
}
}
}