package com.zendesk.maxwell.metrics; import com.codahale.metrics.JmxReporter; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Slf4jReporter; import com.codahale.metrics.health.HealthCheckRegistry; import com.zendesk.maxwell.MaxwellConfig; import com.zendesk.maxwell.MaxwellContext; import org.apache.commons.lang.StringUtils; import org.coursera.metrics.datadog.DatadogReporter; import org.coursera.metrics.datadog.transport.HttpTransport; import org.coursera.metrics.datadog.transport.Transport; import org.coursera.metrics.datadog.transport.UdpTransport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.EnumSet; import java.util.concurrent.TimeUnit; import static org.coursera.metrics.datadog.DatadogReporter.Expansion.*; public class MaxwellMetrics { public static final MetricRegistry metricRegistry = new MetricRegistry(); public static final HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry(); public static final String reportingTypeSlf4j = "slf4j"; public static final String reportingTypeJmx = "jmx"; public static final String reportingTypeHttp = "http"; public static final String reportingTypeDataDog = "datadog"; static final Logger LOGGER = LoggerFactory.getLogger(MaxwellMetrics.class); private static String metricsPrefix; public static void setup(MaxwellConfig config, MaxwellContext context) { if (config.metricsReportingType == null) { LOGGER.warn("Metrics will not be exposed: metricsReportingType not configured."); return; } metricsPrefix = config.metricsPrefix; if (config.metricsReportingType.contains(reportingTypeSlf4j)) { final Slf4jReporter reporter = Slf4jReporter.forRegistry(metricRegistry) .outputTo(LOGGER) .convertRatesTo(TimeUnit.SECONDS) .convertDurationsTo(TimeUnit.MILLISECONDS) .build(); reporter.start(config.metricsSlf4jInterval, TimeUnit.SECONDS); LOGGER.info("Slf4j metrics reporter enabled"); } if (config.metricsReportingType.contains(reportingTypeJmx)) { final JmxReporter jmxReporter = JmxReporter.forRegistry(metricRegistry) .convertRatesTo(TimeUnit.SECONDS) .convertDurationsTo(TimeUnit.MILLISECONDS) .build(); jmxReporter.start(); LOGGER.info("JMX metrics reporter enabled"); if (System.getProperty("com.sun.management.jmxremote") == null) { LOGGER.warn("JMX remote is disabled"); } else { String portString = System.getProperty("com.sun.management.jmxremote.port"); if (portString != null) { LOGGER.info("JMX running on port " + Integer.parseInt(portString)); } } } if (config.metricsReportingType.contains(reportingTypeHttp)) { healthCheckRegistry.register("MaxwellHealth", new MaxwellHealthCheck(metricRegistry)); LOGGER.info("Metrics http server starting"); new MaxwellHTTPServer(config.metricsHTTPPort, MaxwellMetrics.metricRegistry, healthCheckRegistry, context); LOGGER.info("Metrics http server started on port " + config.metricsHTTPPort); } if (config.metricsReportingType.contains(reportingTypeDataDog)) { Transport transport; if (config.metricsDatadogType.contains("http")) { LOGGER.info("Enabling HTTP Datadog reporting"); transport = new HttpTransport.Builder() .withApiKey(config.metricsDatadogAPIKey) .build(); } else { LOGGER.info("Enabling UDP Datadog reporting with host " + config.metricsDatadogHost + ", port " + config.metricsDatadogPort); transport = new UdpTransport.Builder() .withStatsdHost(config.metricsDatadogHost) .withPort(config.metricsDatadogPort) .build(); } final DatadogReporter reporter = DatadogReporter.forRegistry(metricRegistry) .withTransport(transport) .withExpansions(EnumSet.of(COUNT, RATE_1_MINUTE, RATE_15_MINUTE, MEDIAN, P95, P99)) .withTags(getDatadogTags(config.metricsDatadogTags)) .build(); reporter.start(config.metricsDatadogInterval, TimeUnit.SECONDS); LOGGER.info("Datadog reporting enabled"); } } private static ArrayList<String> getDatadogTags(String datadogTags) { ArrayList<String> tags = new ArrayList<>(); for (String tag : datadogTags.split(",")) { if (!StringUtils.isEmpty(tag)) { tags.add(tag); } } return tags; } public static String getMetricsPrefix() { return metricsPrefix; } }