У нас есть собственное веб-приложение, использующее HikariCP. Приложение компилируется в jar
, а затем запускается в Docker-контейнере. В зависимости от среды мы загружаем newrelic-agent.jar
через флаг -javaagent
, когда запускаем webapp.jar
.
Наша установка HikariCP выглядит так:
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);
}
Мы создали службу, которая запускает генератор отчетов при загрузке приложения в зависимости от того, существует ли класс NewRelic. Поскольку мы загружаем java agent
, он также предоставляет нам проанализированную конфигурацию newrelic.yaml
, которую мы повторно используем ниже:
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();
}
}
Приведенный выше код работает отлично, и метрики начинают появляться в NewRelic под Metrics
.
Однако, как только вы попытаетесь отфильтровать показатели с помощью entity
, этих показателей нигде не будет видно. Это как если бы метрики были включены в «корневую» сущность, где вы видите «все метрики».
Не совсем уверен, что здесь не так. У кого-нибудь есть идеи?
Может быть, нам нужно добавить конкретный/дополнительный attributes
?
Проблема в том, что SDK телеметрии не знает о приложении (объекте), который вы инструментируете.
Если вы установите entity.guid
для общих атрибутов в конфигурации SDK телеметрии, метрики будут связаны с приложением.
String entityGuid = NewRelic.getAgent().getLinkingMetadata().get("entity.guid");
Attributes commonAttributes = new Attributes()
.put("entity.guid", entityGuid);
Альтернативно вы можете использовать агент API (см. «Создание и накопление пользовательских метрик»).
Я действительно это понял! Мне пришлось добавить com.newrelic.agent.java:agent-bridge
, а затем привести NewRelic.getAgent()
к com.newrelic.agent.bridge.Agent
. После этого вы можете вызвать agent.getEntityGuid(true)
и получить правильный GUID. Спасибо!
Он должен работать с API. Вероятно, это вопрос времени, вы пытались получить это до того, как оно было установлено.
Спасибо за ответ! К сожалению, это значение кажется
null
. Единственное возможное значение — этоentity.name
, но, похоже, это не имеет эффекта. Есть еще идеи?