Skip to content

Commit

Permalink
Refactors metrics (#9)
Browse files Browse the repository at this point in the history
* Refactors metrics

* Changes ci workflow to java 11

* Changes metrics endpoint from /metrics to /

* Revert "Changes metrics endpoint from /metrics to /"

This reverts commit c23defc.
  • Loading branch information
StrongestNumber9 authored Nov 11, 2024
1 parent 56f6214 commit 64ff2b0
Show file tree
Hide file tree
Showing 14 changed files with 436 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup Maven Central
uses: actions/setup-java@v2
with:
java-version: 17
java-version: 11
distribution: 'adopt'

- name: Cache Local Maven Repository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
metrics.name=target
# Metrics window size
metrics.window=10000
# Metrics report interval, in seconds
metrics.interval=60

# Delay between sending events, in milliseconds
probe.interval=1000
Expand All @@ -18,5 +20,5 @@ record.hostname=rlp_11
target.hostname=127.0.0.1
# Relp Server target port
target.port=12345
# RELP Server reconnect interval
# RELP Server reconnect interval, in milliseconds
target.reconnectinterval=1000
13 changes: 7 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
<changelist>-SNAPSHOT</changelist>
<cnf_01.version>1.0.0</cnf_01.version>
<dropwizard.metrics.version>4.2.28</dropwizard.metrics.version>
<eclipse.jetty.version>11.0.24</eclipse.jetty.version>
<eclipse.jetty.version>10.0.24</eclipse.jetty.version>
<eclipse.parsson.version>1.1.7</eclipse.parsson.version>
<jakarta.json.version>2.1.3</jakarta.json.version>
<java.version>17</java.version>
<java.version>11</java.version>
<junit.platform.version>1.11.3</junit.platform.version>
<junit.version>5.11.3</junit.version>
<log4j2.version>2.24.1</log4j2.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<prometheus.version>0.16.0</prometheus.version>
Expand Down Expand Up @@ -390,7 +390,7 @@
<version>3.6.53</version>
</requireMavenVersion>
<requireJavaVersion>
<version>[17,18)</version>
<version>[11,12)</version>
</requireJavaVersion>
<banDynamicVersions>
<ignores>
Expand Down Expand Up @@ -510,9 +510,10 @@
<exclude>eclipse-java-formatter.xml</exclude>
<exclude>src/main/assembly/jar-with-dependencies.xml</exclude>
<!-- test properties -->
<exclude>src/test/resources/*.properties</exclude>
<exclude>etc/*.properties</exclude>
<!-- logging configuration -->
<exclude>src/main/resources/log4j2.xml</exclude>
<exclude>src/test/resources/log4j2-test.xml</exclude>
<!-- readme -->
<exclude>README.adoc</exclude>
</excludes>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,25 @@ public int window() {
}
return window;
}

public int interval() {
final String intervalString = config.get("metrics.interval");
if (intervalString == null) {
LOGGER.error("Configuration failure: <metrics.interval> is null");
throw new ConfigurationException("Invalid value for <metrics.interval> received");
}
final int interval;
try {
interval = Integer.parseInt(intervalString);
}
catch (NumberFormatException e) {
LOGGER.error("Configuration failure: Invalid value for <metrics.interval>: <{}>", e.getMessage());
throw e;
}
if (interval <= 0) {
LOGGER.error("Configuration failure: <metrics.interval> <[{}]> too small, expected to be >0", interval);
throw new ConfigurationException("Invalid value for <metrics.interval> received");
}
return interval;
}
}
35 changes: 31 additions & 4 deletions src/main/java/com/teragrep/rlp_11/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,22 @@
*/
package com.teragrep.rlp_11;

import com.codahale.metrics.MetricRegistry;
import com.teragrep.cnf_01.ConfigurationException;
import com.teragrep.cnf_01.PathConfiguration;
import com.teragrep.rlp_11.Configuration.ProbeConfiguration;
import com.teragrep.rlp_11.Configuration.RecordConfiguration;
import com.teragrep.rlp_11.Configuration.MetricsConfiguration;
import com.teragrep.rlp_11.Configuration.PrometheusConfiguration;
import com.teragrep.rlp_11.Configuration.TargetConfiguration;
import com.teragrep.rlp_11.metrics.HttpReport;
import com.teragrep.rlp_11.metrics.JmxReport;
import com.teragrep.rlp_11.metrics.Report;
import com.teragrep.rlp_11.metrics.Slf4jReport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
Expand All @@ -62,15 +69,15 @@ public class Main {

private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);

public static void main(final String[] args) throws com.teragrep.cnf_01.ConfigurationException {
public static void main(final String[] args) throws ConfigurationException, IOException {
final PathConfiguration pathConfiguration = new PathConfiguration(
System.getProperty("configurationPath", "etc/rlp_11.properties")
);
final Map<String, String> map;
try {
map = pathConfiguration.asMap();
}
catch (com.teragrep.cnf_01.ConfigurationException e) {
catch (ConfigurationException e) {
LOGGER.error("Failed to create PathConfiguration: <{}>", e.getMessage());
throw e;
}
Expand All @@ -84,13 +91,21 @@ public static void main(final String[] args) throws com.teragrep.cnf_01.Configur
recordConfiguration.appname()
);
final ProbeConfiguration probeConfiguration = new ProbeConfiguration(map);
final MetricRegistry metricRegistry = new MetricRegistry();
final RelpProbe relpProbe = new RelpProbe(
targetConfiguration,
probeConfiguration,
prometheusConfiguration,
metricsConfiguration,
recordFactory
recordFactory,
metricRegistry
);
final Report report = new Slf4jReport(
new JmxReport(new HttpReport(metricRegistry, prometheusConfiguration.port()), metricRegistry),
metricRegistry,
metricsConfiguration.interval()
);
report.start();

final Thread shutdownHook = new Thread(() -> {
LOGGER.debug("Stopping RelpProbe..");
relpProbe.stop();
Expand All @@ -107,7 +122,19 @@ public static void main(final String[] args) throws com.teragrep.cnf_01.Configur
"Using hostname <[{}]> and appname <[{}]> for the records.", recordConfiguration.hostname(),
recordConfiguration.appname()
);
LOGGER
.info(
"Printing reports every <[{}]> seconds. Prometheus stats are available on port <[{}]>.",
metricsConfiguration.interval(), prometheusConfiguration.port()
);
relpProbe.start();
try {
report.close();
}
catch (IOException e) {
LOGGER.error("Failed to close stats reporting: <{}>", e.getMessage());
throw e;
}
}

private static String getHostname() {
Expand Down
44 changes: 7 additions & 37 deletions src/main/java/com/teragrep/rlp_11/RelpProbe.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,13 @@

import com.codahale.metrics.Counter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Slf4jReporter;
import com.codahale.metrics.SlidingWindowReservoir;
import com.codahale.metrics.Timer;
import com.codahale.metrics.jmx.JmxReporter;
import com.teragrep.rlp_01.RelpBatch;
import com.teragrep.rlp_01.RelpConnection;
import com.teragrep.rlp_11.Configuration.ProbeConfiguration;
import com.teragrep.rlp_11.Configuration.MetricsConfiguration;
import com.teragrep.rlp_11.Configuration.PrometheusConfiguration;
import com.teragrep.rlp_11.Configuration.TargetConfiguration;
import org.eclipse.jetty.server.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -75,7 +71,6 @@ public class RelpProbe {
private static final Logger LOGGER = LoggerFactory.getLogger(RelpProbe.class);
private final TargetConfiguration targetConfiguration;
private final RecordFactory recordFactory;
private final PrometheusConfiguration prometheusConfiguration;
private final MetricsConfiguration metricsConfiguration;
private final ProbeConfiguration probeConfiguration;
private final AtomicBoolean stayRunning = new AtomicBoolean(true);
Expand All @@ -89,28 +84,24 @@ public class RelpProbe {
private Counter retriedConnects;
private Timer sendLatency;
private Timer connectLatency;
private JmxReporter jmxReporter;
private Slf4jReporter slf4jReporter;
private Server jettyServer;
private final MetricRegistry metricRegistry;

public RelpProbe(
final TargetConfiguration targetConfiguration,
final ProbeConfiguration probeConfiguration,
final PrometheusConfiguration prometheusConfiguration,
final MetricsConfiguration metricsConfiguration,
final RecordFactory recordFactory
final RecordFactory recordFactory,
final MetricRegistry metricRegistry
) {
this.targetConfiguration = targetConfiguration;
this.probeConfiguration = probeConfiguration;
this.recordFactory = recordFactory;
this.prometheusConfiguration = prometheusConfiguration;
this.metricsConfiguration = metricsConfiguration;
this.recordFactory = recordFactory;
this.metricRegistry = metricRegistry;
}

public void start() {
createMetrics(metricsConfiguration.name());
this.jmxReporter.start();
this.slf4jReporter.start(1, TimeUnit.MINUTES);
relpConnection = new RelpConnection();
connect();
while (stayRunning.get()) {
Expand Down Expand Up @@ -140,15 +131,14 @@ public void start() {
}
try {
LOGGER.debug("Sleeping before sending next event");
Thread.sleep(probeConfiguration.interval());
TimeUnit.MILLISECONDS.sleep(probeConfiguration.interval());
}
catch (InterruptedException e) {
LOGGER.warn("Sleep interrupted: <{}>", e.getMessage());
}
}
disconnect();
latch.countDown();
teardownMetrics();
}

private void connect() {
Expand All @@ -169,7 +159,7 @@ private void connect() {
if (!connected) {
try {
LOGGER.debug("Sleeping for <[{}]>ms before reconnecting", targetConfiguration.reconnectInterval());
Thread.sleep(targetConfiguration.reconnectInterval());
TimeUnit.MILLISECONDS.sleep(targetConfiguration.reconnectInterval());
retriedConnects.inc();
}
catch (InterruptedException e) {
Expand Down Expand Up @@ -219,7 +209,6 @@ public void stop() {
}

private void createMetrics(final String name) {
final MetricRegistry metricRegistry = new MetricRegistry();
this.records = metricRegistry.counter(name(RelpProbe.class, "<[" + name + "]>", "records"));
this.resends = metricRegistry.counter(name(RelpProbe.class, "<[" + name + "]>", "resends"));
this.connects = metricRegistry.counter(name(RelpProbe.class, "<[" + name + "]>", "connects"));
Expand All @@ -229,24 +218,5 @@ private void createMetrics(final String name) {
.timer(name(RelpProbe.class, "<[" + name + "]>", "sendLatency"), () -> new Timer(new SlidingWindowReservoir(metricsConfiguration.window())));
this.connectLatency = metricRegistry
.timer(name(RelpProbe.class, "<[" + name + "]>", "connectLatency"), () -> new Timer(new SlidingWindowReservoir(metricsConfiguration.window())));
jmxReporter = JmxReporter.forRegistry(metricRegistry).build();
slf4jReporter = Slf4jReporter
.forRegistry(metricRegistry)
.outputTo(LoggerFactory.getLogger(RelpProbe.class))
.build();
jettyServer = new Server(prometheusConfiguration.port());
}

private void teardownMetrics() {
jmxReporter.close();
slf4jReporter.close();
try {
jettyServer.stop();
}
//CHECKSTYLE:OFF
catch (Exception e) {
throw new RuntimeException(e);
}
//CHECKSTYLE:ON
}
}
103 changes: 103 additions & 0 deletions src/main/java/com/teragrep/rlp_11/metrics/HttpReport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* RELP Commit Latency Probe RLP-11
* Copyright (C) 2024 Suomen Kanuuna Oy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*
* Additional permission under GNU Affero General Public License version 3
* section 7
*
* If you modify this Program, or any covered work, by linking or combining it
* with other code, such other code is not for that reason alone subject to any
* of the requirements of the GNU Affero GPL version 3 as long as this Program
* is the same Program as licensed from Suomen Kanuuna Oy without any additional
* modifications.
*
* Supplemented terms under GNU Affero General Public License version 3
* section 7
*
* Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
* versions must be marked as "Modified version of" The Program.
*
* Names of the licensors and authors may not be used for publicity purposes.
*
* No rights are granted for use of trade names, trademarks, or service marks
* which are in The Program if any.
*
* Licensee must indemnify licensors and authors for any liability that these
* contractual assumptions impose on licensors and authors.
*
* To the extent this program is licensed as part of the Commercial versions of
* Teragrep, the applicable Commercial License may apply to this file if you as
* a licensee so wish it.
*/
package com.teragrep.rlp_11.metrics;

import com.codahale.metrics.MetricRegistry;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.dropwizard.DropwizardExports;
import io.prometheus.client.exporter.MetricsServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

import java.io.IOException;

public class HttpReport implements Report {

private final Server jettyServer;
private final MetricRegistry metricRegistry;

public HttpReport(final MetricRegistry metricRegistry, final int prometheusPort) {
this.metricRegistry = metricRegistry;
jettyServer = new Server(prometheusPort);
}

@Override
public void start() {
// prometheus-exporter
CollectorRegistry.defaultRegistry.register(new DropwizardExports(metricRegistry));

final ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
jettyServer.setHandler(context);

final MetricsServlet metricsServlet = new MetricsServlet();
final ServletHolder servletHolder = new ServletHolder(metricsServlet);
context.addServlet(servletHolder, "/metrics");

// Start the webserver.
try {
jettyServer.start();
}
//CHECKSTYLE:OFF
catch (Exception e) {
throw new RuntimeException(e);
}
//CHECKSTYLE:ON
}

@Override
public void close() throws IOException {
try {
jettyServer.stop();
}
//CHECKSTYLE:OFF
catch (Exception e) {
throw new IOException(e);
}
//CHECKSTYLE:ON
}
}
Loading

0 comments on commit 64ff2b0

Please sign in to comment.