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

DropWizard metrics #76

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ lookups.hostname.file,etc/hostname.json,Path to username-to-hostname lookup tabl
lookups.appname.file,etc/appname.json,Path to username-to-appname lookup table
payload.splitRegex, \n (newline), A regex based on which incoming requests will be split into multiple outgoing messages
payload.splitEnabled, false, Sets whether splitting incoming messages by splitRegex is enabled
prometheus.port, 1234, Port used by the server that provides DropWizard metrics
|===

=== Lookup tables
Expand Down
2 changes: 2 additions & 0 deletions etc/config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ lookups.appname.file=etc/appname.json

payload.splitRegex=\n
payload.splitEnabled=false

prometheus.port=1234
39 changes: 39 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
<log4j.version>2.23.1</log4j.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<metrics.version>4.2.8</metrics.version>
<netty.version>4.1.108.Final</netty.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<prometheus-simpleclient.version>0.16.0</prometheus-simpleclient.version>
<revision>0.0.1</revision>
<rlo_14.version>1.0.1</rlo_14.version>
<rlp_01.version>4.0.1</rlp_01.version>
Expand Down Expand Up @@ -90,6 +92,43 @@
<artifactId>netty-handler</artifactId>
<version>${netty.version}</version>
</dependency>
<!-- metrics -->
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>${metrics.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-jmx</artifactId>
<version>${metrics.version}</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>${prometheus-simpleclient.version}</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_dropwizard</artifactId>
<version>${prometheus-simpleclient.version}</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_servlet</artifactId>
<version>${prometheus-simpleclient.version}</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>${prometheus-simpleclient.version}</version>
</dependency>
<!-- for exporting prometheus -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>10.0.15</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
Expand Down
23 changes: 15 additions & 8 deletions src/main/java/com/teragrep/lsh_01/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package com.teragrep.lsh_01;

import com.codahale.metrics.MetricRegistry;
import com.teragrep.lsh_01.authentication.BasicAuthentication;
import com.teragrep.lsh_01.authentication.BasicAuthenticationFactory;
import com.teragrep.lsh_01.config.*;
Expand All @@ -38,13 +39,15 @@ public static void main(String[] args) {
InternalEndpointUrlConfig internalEndpointUrlConfig = new InternalEndpointUrlConfig();
LookupConfig lookupConfig = new LookupConfig();
PayloadConfig payloadConfig = new PayloadConfig();
MetricsConfig metricsConfig = new MetricsConfig();
try {
nettyConfig.validate();
relpConfig.validate();
securityConfig.validate();
internalEndpointUrlConfig.validate();
lookupConfig.validate();
payloadConfig.validate();
metricsConfig.validate();
}
catch (IllegalArgumentException e) {
LOGGER.error("Can't parse config properly: {}", e.getMessage());
Expand All @@ -57,15 +60,15 @@ public static void main(String[] args) {
LOGGER.info("Got payload config: <[{}]>", payloadConfig);
LOGGER.info("Authentication required: <[{}]>", securityConfig.authRequired);

RelpConnectionFactory relpConnectionFactory = new RelpConnectionFactory(relpConfig);
// metrics
MetricRegistry metricRegistry = new MetricRegistry();

RelpConnectionFactory relpConnectionFactory = new RelpConnectionFactory(relpConfig, metricRegistry);
Pool<IManagedRelpConnection> pool = new Pool<>(relpConnectionFactory, new ManagedRelpConnectionStub());

RelpConversion relpConversion = new RelpConversion(
pool,
securityConfig,
basicAuthentication,
lookupConfig,
payloadConfig
IMessageHandler relpConversion = new MetricRelpConversion(
new RelpConversion(pool, securityConfig, basicAuthentication, lookupConfig, payloadConfig),
metricRegistry
);

try (
Expand All @@ -75,10 +78,14 @@ public static void main(String[] args) {
null,
200,
internalEndpointUrlConfig
)
); Metrics metrics = new Metrics(metricsConfig.prometheusPort, metricRegistry)
51-code marked this conversation as resolved.
Show resolved Hide resolved
) {
metrics.start();
server.run();
}
catch (Exception e) {
throw new RuntimeException("Couldn't close DropWizard metrics: " + e.getMessage());
51-code marked this conversation as resolved.
Show resolved Hide resolved
}
finally {
pool.close();
}
Expand Down
75 changes: 75 additions & 0 deletions src/main/java/com/teragrep/lsh_01/MetricRelpConversion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
logstash-http-input to syslog bridge
Copyright 2024 Suomen Kanuuna Oy

Derivative Work of Elasticsearch
Copyright 2012-2015 Elasticsearch

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.teragrep.lsh_01;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.SlidingWindowReservoir;
import com.codahale.metrics.Timer;
import com.teragrep.lsh_01.authentication.Subject;

import java.util.Map;

import static com.codahale.metrics.MetricRegistry.name;

/**
* Decorator for IMessageHandler. Responsible for reporting metrics.
*/
public class MetricRelpConversion implements IMessageHandler {

private final IMessageHandler relpConversion;
private final MetricRegistry metricRegistry;
private final Timer sendLatency;

public MetricRelpConversion(IMessageHandler relpConversion, MetricRegistry metricRegistry) {
this.relpConversion = relpConversion;
this.metricRegistry = metricRegistry;
this.sendLatency = metricRegistry
.timer(name(MetricRelpConversion.class, "sendLatency"), () -> new Timer(new SlidingWindowReservoir(10000)));
}

@Override
public boolean onNewMessage(Subject subject, Map<String, String> headers, String body) {
boolean sent;
try (Timer.Context ctx = sendLatency.time()) {
sent = relpConversion.onNewMessage(subject, headers, body);
}
return sent;
}

@Override
public IMessageHandler copy() {
return new MetricRelpConversion(relpConversion.copy(), metricRegistry);
}

@Override
public Subject asSubject(String token) {
return relpConversion.asSubject(token);
}

@Override
public boolean requiresToken() {
return relpConversion.requiresToken();
}

@Override
public Map<String, String> responseHeaders() {
return relpConversion.responseHeaders();
}
}
85 changes: 85 additions & 0 deletions src/main/java/com/teragrep/lsh_01/Metrics.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
logstash-http-input to syslog bridge
Copyright 2024 Suomen Kanuuna Oy

Derivative Work of Elasticsearch
Copyright 2012-2015 Elasticsearch

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.teragrep.lsh_01;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Slf4jReporter;
import com.codahale.metrics.jmx.JmxReporter;
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 org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

public final class Metrics implements AutoCloseable {

private final JmxReporter jmxReporter;
private final Slf4jReporter slf4jReporter;
private final Server jettyServer;
private final MetricRegistry metricRegistry;

public Metrics(int prometheusPort, MetricRegistry metricRegistry) {
this.metricRegistry = metricRegistry;

this.jmxReporter = JmxReporter.forRegistry(metricRegistry).build();
this.slf4jReporter = Slf4jReporter
.forRegistry(metricRegistry)
.outputTo(LoggerFactory.getLogger(Metrics.class))
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.build();
jettyServer = new Server(prometheusPort);
}

public void start() {
this.jmxReporter.start();
this.slf4jReporter.start(1, TimeUnit.MINUTES);

// prometheus-exporter
CollectorRegistry.defaultRegistry.register(new DropwizardExports(metricRegistry));

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

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

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

@Override
public void close() throws Exception {
slf4jReporter.close();
jmxReporter.close();
jettyServer.stop();
}
}
44 changes: 44 additions & 0 deletions src/main/java/com/teragrep/lsh_01/config/MetricsConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
logstash-http-input to syslog bridge
Copyright 2024 Suomen Kanuuna Oy

Derivative Work of Elasticsearch
Copyright 2012-2015 Elasticsearch

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.teragrep.lsh_01.config;

public class MetricsConfig implements Validateable {

public final int prometheusPort;

public MetricsConfig() {
PropertiesReaderUtilityClass propertiesReader = new PropertiesReaderUtilityClass(
System.getProperty("properties.file", "etc/config.properties")
);
prometheusPort = propertiesReader.getIntProperty("prometheus.port");
}

@Override
public void validate() {
if (prometheusPort < 1 || prometheusPort > 65535) {
throw new IllegalArgumentException("prometheus.port wasn't a valid port");
}
}

@Override
public String toString() {
return "RelpConfig{" + "prometheusPort=" + prometheusPort + "}";
}
}
Loading