Skip to content

Commit

Permalink
Add prometheus metrics for logs and basic jvm stats
Browse files Browse the repository at this point in the history
  • Loading branch information
schnapster committed May 20, 2018
1 parent 315804f commit 2a81830
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 1 deletion.
5 changes: 5 additions & 0 deletions LavalinkServer/application.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ lavalink:
bufferDurationMs: 400
youtubePlaylistLoadLimit: 600

metrics:
prometheus:
enabled: false
endpoint: /metrics

logging:
file:
max-history: 30
Expand Down
5 changes: 5 additions & 0 deletions LavalinkServer/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ dependencies {
compile group: 'org.json', name: 'json', version: jsonOrgVersion
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion
compileOnly group: 'com.github.spotbugs', name: 'spotbugs-annotations', version: spotbugsAnnotationsVersion

compile group: 'io.prometheus', name: 'simpleclient', version: prometheusVersion
compile group: 'io.prometheus', name: 'simpleclient_hotspot', version: prometheusVersion
compile group: 'io.prometheus', name: 'simpleclient_logback', version: prometheusVersion
compile group: 'io.prometheus', name: 'simpleclient_servlet', version: prometheusVersion
}

//create a simple version file that we will be reading to create appropriate docker tags
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package lavalink.server.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
* Created by napster on 20.05.18.
*/
@Component
@ConfigurationProperties("metrics.prometheus")
public class MetricsPrometheusConfigProperties {

private boolean enabled = false;
private String endpoint = "";

public boolean isEnabled() {
return enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public String getEndpoint() {
return endpoint;
}

public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package lavalink.server.metrics;

import ch.qos.logback.classic.LoggerContext;
import io.prometheus.client.hotspot.DefaultExports;
import io.prometheus.client.logback.InstrumentedAppender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

/**
* Created by napster on 08.05.18.
*/
@Component
@ConditionalOnProperty("metrics.prometheus.enabled")
public class PrometheusMetrics {

private static final Logger log = LoggerFactory.getLogger(PrometheusMetrics.class);

public PrometheusMetrics() {

InstrumentedAppender prometheusAppender = new InstrumentedAppender();
//log metrics
final LoggerContext factory = (LoggerContext) LoggerFactory.getILoggerFactory();
final ch.qos.logback.classic.Logger root = factory.getLogger(Logger.ROOT_LOGGER_NAME);
prometheusAppender.setContext(root.getLoggerContext());
prometheusAppender.start();
root.addAppender(prometheusAppender);

//jvm (hotspot) metrics
DefaultExports.initialize();

log.info("Prometheus metrics set up");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package lavalink.server.metrics;

import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.common.TextFormat;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Nullable;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
* Created by napster on 18.10.17. - Copied from Quarterdeck on 20.05.2018
* <p>
* Used to expose the prometheus metrics. Some code copied from prometheus' own MetricsServlet
*/
@RestController
@RequestMapping("${metrics.prometheus.endpoint:/metrics}")
@ConditionalOnBean(PrometheusMetrics.class)
public class PrometheusMetricsController {

private final CollectorRegistry registry;

public PrometheusMetricsController() {
this.registry = CollectorRegistry.defaultRegistry;
}

@GetMapping(produces = TextFormat.CONTENT_TYPE_004)
public ResponseEntity<String> getMetrics(@Nullable @RequestParam(name = "name[]", required = false) String[] includedParam)
throws IOException {
return buildAnswer(includedParam);
}

private ResponseEntity<String> buildAnswer(@Nullable String[] includedParam) throws IOException {
Set<String> params;
if (includedParam == null) {
params = Collections.emptySet();
} else {
params = new HashSet<>(Arrays.asList(includedParam));
}

Writer writer = new StringWriter();
try (writer) {
TextFormat.write004(writer, this.registry.filteredMetricFamilySamples(params));
writer.flush();
}

return new ResponseEntity<>(writer.toString(), HttpStatus.OK);
}
}
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ subprojects {
oshiVersion = '3.4.4'
jsonOrgVersion = '20180130'
spotbugsAnnotationsVersion = '3.1.3'
prometheusVersion = '0.3.0'
prometheusVersion = '0.4.0'

junitJupiterVersion = '5.1.0'
junitPlatformVersion = '1.1.0'
Expand Down

0 comments on commit 2a81830

Please sign in to comment.