2

Is it possible to add some metrics to a Java system that will return the version number as a string for the application that is monitored?

I am aiming for a dashboard where each pod, running a Java application inside a Docker container, in a Kubernetes cluster is monitored and the current version of each Java application is viewed.

If it isn't possible, do you have an idea on how to get that information from the Java application and make it available in a Grafana dashboard?

Thomas Sundberg
  • 4,098
  • 3
  • 18
  • 25
  • 1
    Do you mean something like `System.getProperty("java.version")` for the Java version in the Docker container? Or do you mean the version of the application itself? If the second, it depends on how it is build. We personally use Maven (and Jenkins to build) for that. How to do it with other build-able applications I don't really have experience with. – Kevin Cruijssen Aug 08 '18 at 12:44
  • Will the implementation version from [MANIFEST.MF](https://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Manifest_Specification) work for you? Check out this question, to see how to obtain it at runtime: https://stackoverflow.com/questions/2712970/get-maven-artifact-version-at-runtime – default locale Aug 08 '18 at 12:46
  • What metrics collector are you using? If you are using prometheus java_client(https://github.com/prometheus/client_java), I think it will expose java version as metric.(Dependents on your instrumentation to pull metrics)(https://stackoverflow.com/questions/47559338/how-to-expose-metrics-to-prometheus-from-a-java-spring-boot-application) – Veerendra K Aug 08 '18 at 13:02
  • I mean a version number as in the version of my application. Say that version 1.7.4711 is deployed. Then I want to be able to see 1.7.4711 in my dashboard. I will give @Olivier s answer a spin. It sounds like one way to come around the fact that Prometheus likes to return numbers and number series. – Thomas Sundberg Aug 08 '18 at 14:06

2 Answers2

2

In your application, you can make available a Gauge metric that uses labels to export e.g. a version number or commit/build hash and then set the value of the gauge to 1.

For example, this is how the redis_exporter exports information about a redis instance:

# HELP redis_instance_info Information about the Redis instance
# TYPE redis_instance_info gauge
redis_instance_info{addr="redis://localhost:6379",os="Linux 4.4.0-62-generic x86_64",redis_build_id="687a2a319020fa42",redis_mode="standalone",redis_version="3.0.6",role="master"} 1

You can see the version and a couple of other attributes exported as labels of the metric redis_instance_info.

Oliver
  • 11,857
  • 2
  • 36
  • 42
1

Expanding on the idea of @Oliver I'm adding a sample java class which exposes the currently used application version, git branch and git commit id to the Prometheus metrics endpoint after the application is started/ready.

This assumes that you have a spring boot app with prometheus metrics enabled as an actuator endpoint.

@Component
@RequiredArgsConstructor
public class PrometheusCustomMetricsService implements ApplicationListener<ApplicationReadyEvent> {

    private static final int FIXED_VALUE = 1;
    @Value("${info.project.version}")
    private String applicationVersion;

    private final MeterRegistry meterRegistry;
    private final GitProperties gitProperties;

    @Override
    public void onApplicationEvent(@NonNull ApplicationReadyEvent event) {
        registerApplicationInfoGauge();
    }

    private void registerApplicationInfoGauge() {
        Tag versionTag = new ImmutableTag("application_version", applicationVersion);
        Tag branchTag = new ImmutableTag("branch", gitProperties.getBranch());
        Tag commitIdTag = new ImmutableTag("commit_id", gitProperties.getShortCommitId());

        meterRegistry.gauge("application_info",
                            List.of(versionTag, branchTag, commitIdTag),
                            new AtomicInteger(FIXED_VALUE));
    }
}

Your custom metric should show up something like this in the prometheus endpoint:

application_info{application_version="1.2.3",branch="SOME-BRANCH-123",commit_id="123456"} NaN

I wouldn't worry about the value of the application_info gauge being NaN as we don't need the value and only use it as a way to send over the tags.

Nexonus
  • 706
  • 6
  • 26