Можно ли разместить плагин apm-agent-java внутри JAR-файла приложения?

Мотивация

Java-агент Elastic APM не поддерживает R2DBC . Они предоставляют API-интерфейс плагина, который

позволяет добавить к агенту собственный инструментарий, который агент будет автоматически применять так же, как он применяет внутренне определенный инструментарий.

После создания плагина вы упаковываете его как обычный JAR-файл, и вам нужно указать агенту APM, в какой папке искать дополнительные плагины, установив параметр конфигурации config-plugins-dir.

Мы хотим развернуть плагин как часть исполняемого JAR-файла Spring Boot.

Что работает

Кажется, что config-plugins-dir оценивается только как путь внутри хост-системы. Когда мы вручную помещаем JAR-файл плагина в любую системную папку, видимую приложению, он распознается правильно.

Что не работает

Нам не удалось установить параметр config-plugins-dir, чтобы заставить java-apm-agent искать плагины внутри JAR-файла приложения.

Дополнительная информация

Существует несколько способов настройки агента APM, среди прочего:

  • Ручная настройка с флагом -javaagent
  • Программная настройка API для самостоятельного подключения с помощью вызова ElasticApmAttacher.attach(); перед SpringApplication.run().

Сомнения

Я понимаю, что первый метод с использованием -javaagent может не видеть внутреннюю часть JAR-файла, но почему он не работает, когда он подключен из самого Java-приложения? Я ожидаю, что внутри работающего приложения я увижу содержимое JAR, по крайней мере, путь к классам???

Я предполагаю, что это может быть каким-то образом связано со схожими по звучанию вопросами Stackoverflow, такими как

однако я не могу собрать все это воедино, ни понять, почему это не работает, ни как заставить это работать.

Вопрос

Есть ли способ достичь нашей основной цели, чтобы мы могли развернуть подключаемый модуль агента APM внутри JAR-файла приложения? Например. какой-нибудь умный трюк Maven для достижения этой цели? Или что-то другое?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
2
0
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Наконец мы пришли к решению, но изменений Maven оказалось недостаточно, нам также нужно было изменить файл Dockerfile. Вот наше решение:

Краткое содержание

  1. Maven maven-dependency-plugin копирует плагин из репозитория артефактов в папку target/apm-plugins/.
  2. Докер копирует его из target/apm-plugins/ в /app/apm-plugins/.
  3. Для локальной разработки переменная plugins_dir указывает на локальное расположение файла target/apm-plugins.
  4. В Kubernetes переменная plugins_dir перезаписывается системной переменной ELASTIC_APM_PLUGINS_DIR.

Подробности

Код был упрощен и анонимизирован, поэтому возможно я опустил какие-то мелочи :)

1. Мавен pom.xml

<dependency>
    <groupId>com.mycompany.myproject</groupId>
    <artifactId>apm-plugins</artifactId>
</dependency>
...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy</id>
            <phase>compile</phase>
            <goals>
                <goal>copy</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <artifactItems>
            <artifactItem>
                <groupId>com.mycompany.myproject</groupId>
                <artifactId>apm-plugins</artifactId>
                <type>jar</type>
                <overWrite>true</overWrite>
                <outputDirectory>${project.build.directory}/apm-plugins</outputDirectory>
            </artifactItem>
        </artifactItems>
        <overWriteReleases>true</overWriteReleases>
        <overWriteSnapshots>true</overWriteSnapshots>
    </configuration>
</plugin>

2. Докер Dockerfile

COPY target/apm-plugins/*.jar /app/apm-plugins/

3. Локальная конфигурация elasticapm.properties:

Это гарантирует, что плагин будет найден даже тогда, когда приложение будет создано в локальной среде.

# https://www.elastic.co/guide/en/apm/agent/java/current/plugin-api.html
# A folder that contains external agent plugins.
# We have implemented our own plugin to support reactive R2DBC. More frameworks support can be added there later.
# Overridden by environment variable ELASTIC_APM_PLUGINS_DIR.
plugins_dir=target/apm-plugins

# This is to suppress the "Unexpected error during automatic discovery process for cloud provider" warning after start of application
cloud_provider=NONE

4. Кубернетес

values.yaml

env:
  ELASTIC_APM_PLUGINS_DIR: apm-plugins

deployment.yaml — это гарантирует, что все из values.yaml под env установлено как системная переменная:

spec:
  template:
    spec:
      containers:
        - name: xxxx
          env:
            {{- range $key, $value := .Values.env }}
            - name: {{ $key }}
              value: {{ $value | quote }}
            {{- end }}

Другие вопросы по теме