はじめに
New RelicのJavaエージェントをDockerで導入し、
ECS(Fargate)上でSpring Bootアプリケーションと連携させてみました。
作業手順
「Create a new key」を押下し、APIキーが表示されたら、「Continue」を押下する。
APIキーの用途(Notes)が空白で作成されるので、後で必ず記載しましょう。
後で何のAPIキーかわからなくなることがあるので。
APIキーはここでしか確認できないので、忘れずに保管しておきましょう。
コピーしたcurlをターミナルなどで実行する。
$ curl -O https://download.newrelic.com/newrelic/java-agent/newrelic-agent/current/newrelic-java.zip
取得したzipファイルを解凍する。(newrelicフォルダが作成されます。)
$ unzip newrelic-java.zip
中身はこんな感じです。これらをnewrelicフォルダごとJavaプロジェクトフォルダに配置します。
$ ls newrelic
extension-example.xml newrelic-api-javadoc.jar newrelic.jar
extension.xsd newrelic-api-sources.jar newrelic.yml
LICENSE newrelic-api.jar THIRD_PARTY_NOTICES.md
アプリケーション名を設定し、newrelic.ymlをダウンロードする。
ダウンロードした「newrelic.yml」を先ほど解凍したnewrelicフォルダ配下の同名ファイルに差し替えます。
DockerfileにNewRelicエージェントを起動する処理を追加します。
FROM amazoncorretto:17-alpine
COPY target/app-0.0.1-SNAPSHOT.jar /usr/local/app.jar
RUN mkdir -p /usr/local/newrelic
ADD ./newrelic/newrelic.jar /usr/local/newrelic/newrelic.jar
ADD ./newrelic/newrelic.yml /usr/local/newrelic/newrelic.yml
EXPOSE 8080
ENTRYPOINT ["java", "-javaagent:/usr/local/newrelic/newrelic.jar", "-jar", "/usr/local/app.jar"]
Dockefileを修正したら、「Continue」を押下する。
infrastructure agentの導入については、今回は導入しないので「Skip」を押下する。
(コンテナのCPUやメモリの使用率などが連携されるようになります。)
Statusが「Successful」となっていることを確認したら、「See your data」を押下する。
NewRelicへの連携が開始されると、色々と情報が連携されるようになります。
例えば、トランザクション情報だと、APM & Services > Transactionsを見ると、
全体的なスループットやTATなど確認することができます。
追加設定
デフォルトでも色々と情報を取得できるのですが、追加で様々な情報を取得できます。
レスポンス情報を取得する
基本的に、NewRelicはレスポンス情報については連携していないようで、
連携したい場合は、明示的に設定する必要があるみたいです。
その場合には、addCustomParameter() というメソッドを使います。
以下のように、Javaソースにて、NewRelicエージェントをインポートします。
import com.newrelic.api.agent.NewRelic;
あとはこんな感じでメソッドを追加するだけです。
第一引数が表示名称、第二引数が値です。
NewRelic.addCustomParameter("resultCode", response.getResultCode());
すると、以下のようにCustom attribute項目として連携されるようになります。
リクエストボディ項目を取得する
リクエストボディ項目については、
newrelic.ymlに以下の設定を追加することで、連携対象項目を追加できます。
common.attributes.includeに連携したい項目名を記載します。
common:
attributes:
include: request.parameters.email
設定すると、APM & Services > Transactions > Attributesに出力されます。
request.parameters.*とした場合、リクエストボディの全項目を取得します。
複数項目を指定したい場合は、カンマ区切りで設定すると良いです。
request.parametersによる情報取得はGETメソッドの場合もしくは、Content-Typeが「application/x-www-form-urlencoded」の場合は取得できるみたいです。
JSON形式などの場合は、addCustomParameter() で取得する必要がありそう。
リクエストヘッダ項目を取得する
リクエストボディと同様にヘッダも連携する対象を追加できます。
common.transaction_eventsにcustom_request_headersを追加し、
リスト形式で連携したいヘッダ名を記載します。
common:
transaction_events:
custom_request_headers:
- header_name: "x-forwarded-for"
同じく、APM & Services > Transactions > Attributesに出力されます。
NewRelic上の表示名を変更することも可能です。詳細は以下のページを参照。
気にした方が良いポイント
触ってみて思いましたが、以下の点は検討しておいた方が良さそうです。
ログ出力対象を制御する
NewRelicエージェントを導入すると、デフォルトでログ連携がされるようになります。
Logs > All logsなどを見ると、INFO、WARN、ERROR全て出力されることがわかります。
ログはコスト増や機密情報流出のタネになりやすいので、しっかり制御した方が良さそうです。
どのレベルのログをNewRelicへ連携するかについては、アプリ側で制御する必要があります。(試しに、logback-spring.xmlでWARN指定すると、NewRelicへ連携されるログレベルもWARN以上となりました。)
ちなみに、newrelic.ymlの以下あたりをfalseにするとログ連携されなくなります。
common:
application_logging:
enabled: false
forwarding:
enabled: false
newrelic.ymlにlog_levelという項目がありますが、これはNewRelicエージェントログの出力対象を制御する項目で、エージェントの連携対象を制御するものではありません。
上記以外にも、例えばAPM & Services > Errors (errors inbox)あたりにも、
想定外の内容が出力されていないかは確認した方が良いです。
取得対象のトランザクションを制御する
例えば、LBからのヘルスチェックをSpring Bootで受け付けたりする場合(/actuator/healthなどに対して)そのトランザクション情報がNewRelicへ連携されます。
そうすると、NewRelicにデータ取込された分だけコストがかかってしまうので、不要であれば除外する必要があります。
様々なやり方があるみたいですが、NerdGraphを使うとトランザクション情報を除外できるみたいです。
「NerdGraph API Explorer」を押下する。
左上にUSER KEYを設定し、「Submit」を押下する。
例)トランザクション情報からNLBからのヘルスチェックを除外するクエリ
mutation {
nrqlDropRulesCreate(
accountId: <アカウントID(7桁の数字)>
rules: [
{
action: DROP_DATA
nrql: "SELECT * FROM Transaction WHERE request.headers.userAgent = 'ELB-HealthChecker/2.0'"
description: "Exclude HealthCheck URI Transactions from data ingestion"
}
]
) {
successes {
id
}
failures {
submitted {
nrql
}
error {
reason
description
}
}
}
}
あとは、試していないですが、以下でもできそう。
サンプリング数を適切に設定する
newrelic.ymlの以下項目は、New Relicエージェントが1回の収集間隔でTransactionまたはSpanを取得する件数を制御するものです。(初期値は2,000)
トランザクション量に応じて取得すると良いですが、増やすとその分だけ負荷が掛かってしまうので注意です。
- common.transaction_events.max_samples_stored:Transaction用
- common.span_events.max_samples_stored;Span用
おわりに
NewRelicは様々な情報を細かく取得できそうで、かつ、情報を落とす仕組みもあるので、
基本的には連携させてNewRelic側で除外設定をして必要な情報を監視するのが良さそうです。
個人的にはトランザクション情報がSQLに似たクエリで検索できる点が良かったです。