javajmxdropwizardnewrelic

How to get HikariCP metrics to show properly in NewRelic?


We have a custom webapp hat is using HikariCP. The application is compiled into a jar and then started in a docker container. Depending on the environment we are loading the newrelic-agent.jar via the -javaagent flag when we're starting the webapp.jar.

Our HikariCP setup looks like this:

  private DataSource createDataSource() {

    final HikariConfig config = new HikariConfig();

    config.setJdbcUrl(...);
    config.setUsername(...);
    config.setPassword(...);
    config.setSchema(...);

    config.setConnectionTimeout(...);
    config.setMinimumIdle(...);
    config.setMaximumPoolSize(...);
    config.setIdleTimeout(...);

    config.setLeakDetectionThreshold(...);
    config.setMaxLifetime(...);

    config.addDataSourceProperty("cachePrepStmts", "true");
    config.addDataSourceProperty("prepStmtCacheSize", "250");
    config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

    config.setMetricRegistry(metricsRegistry.getRegistry());

    return new HikariDataSource(config);
  }

We have created a service that starts the reporter upon application boot based whether or not the NewRelic class exists. Since we're loading the java agent it does also provide us with the parsed newrelic.yaml configuration which we're re-using down below:


public class NewRelicMetricsService {

    private static final Logger logger = LoggerFactory.getLogger(NewRelicMetricsService.class);

    private final NewRelicReporter reporter;

    @Inject
    public NewRelicMetricsService(ApplicationMetricsRegistry metricRegistry) {
        NewRelicReporter tmpReporter = null;
        // Check if the NewRelic java agent has been loaded.
        try {
            Class.forName("com.newrelic.api.agent.NewRelic");
            Config config = NewRelic.getAgent().getConfig();

            SenderConfiguration sender = MetricBatchSender.configurationBuilder()
                    .apiKey(config.getValue("license_key"))
                    .useLicenseKey(true)
                    .httpPoster(new OkHttpPoster(Duration.ofSeconds(2)))
                    .build();

            MetricBatchSender metricBatchSender = MetricBatchSender.create(sender);

            // Use this to define custom attributes visible in the APM & Service.
            Attributes commonAttributes = new Attributes();

            tmpReporter = NewRelicReporter.build(metricRegistry.getRegistry(), metricBatchSender)
                                          .commonAttributes(commonAttributes)
                                          .build();

        } catch (ClassNotFoundException e) {
            logger.info("New Relic java agent has not been loaded. Metrics will not be showing in New Relic.");
        }

        this.reporter = tmpReporter;

        // Start reporting.
        start();
    }

    public void start() {
        if (reporter == null) {
            return;
        }
        reporter.start(1, TimeUnit.SECONDS);
    }

    public void stop() {
        if (reporter == null) {
            return;
        }
        reporter.stop();
    }

}

The code above works just fine and metrics start appearing in NewRelic under Metrics.

hikaricp metrics in newrelic

However, once you attempt to filter the metrics via entity -- those metrics are nowhere to be seen. It is as if the metrics are scoped to be in the "root" entity where you see "all metrics".

enter image description here

Not entirely sure what's wrong here. Does anybody have any ideas? Maybe we need to add a specific/additional attributes?


Solution

  • The problem is that the Telemetry SDK does not know about the application (entity) you are instrumenting.

    If you set entity.guid to the common attributes in your Telemetry SDK config, it will link the metrics to the application.

    String entityGuid = NewRelic.getAgent().getLinkingMetadata().get("entity.guid");
    Attributes commonAttributes = new Attributes()
        .put("entity.guid", entityGuid);
    
    

    Alternatively you could use the agent API (see "Create and accumulate custom metrics").