[Dynatrace] SAP BTP Cloud Foundry にDeployしたJavaアプリで分散トレーシングを実現する（その2）

## 今回のお題も前回と同様「SAP BTP Cloud Foundry」です
前回のその1の投稿（2024年6月30日投稿）から、また少し時間が空いてしまいましたが、前回の続編について書こうと思います。前回は、DynatraceのOneAgentをJavaのアプリに自動的に cf push 時に埋め込んで、トレース情報やメトリクス情報を可視化する方法についてお話しました。今回は、可観測性と呼ばれる Observability の三本柱の3つ目のピース（Signal）である「ログ」の取り込み方法について、まとめたいと思います。分析の方法は、また次の機会にしたいと思います。

## SAP BTP Cloud Foundry でのログの取り扱い
SAP BTP Cloud Foundy 環境におけるログの取り扱いについては、下記2つの記事が2023年に投稿され、比較的に新しい情報としてまとめられていましたので、まずはここで紹介します。
- [SAP Cloud Loggingについて調べてみた](https://qiita.com/isogami/items/70d6d96a45e10145f85e)
- [SAP Cloud Logging Service入門](https://community.sap.com/t5/technology-blogs-by-sap/sap-cloud-logging-service-%E5%85%A5%E9%96%80/ba-p/13571855)

SAP BTP Cloud Foundry環境でアプリをDeployする際、SAP社が提供するCloud Logging Service インスタンスを有効にしておくと、自動的にCFのログやアプリのログは、そちらにストアされ、検索、閲覧できるようになっています。SAP BTP Cloud logging Serivce では、OpenSearch が提供され、下記のような画面でログを確認することができます。下記ログは、Java の Sample アプリをDeployしたときに出力されたメッセージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778724/601e1f75-066a-03af-3da2-f29ba61f0de8.png)
OpenSearchに慣れている人であれば、これはこれで使えそうですが、やっぱりメトリクスとトレースをDynatrace側で収集できているのあれば、ログもDynatraceへ集約したくなると思います。でも、どうやって？という疑問が残ると思いますし、それらの方法についてまとめてある日本語ブログも見当たらないので、今回自分が書くこのブログがSAP BTP Cloud Foundry ログをDynatraceに集約し、Observabilityを始めるよいきっかけになるといいなと思います。
## SAP BTP Cloud Foundry のログの転送の仕方
### 全体概要
SAP BTP Cloud Foundry のログを他のプラットフォーム（今回の場合であれば、Dynatrace）へ転送する場合、Cloud Foundryが提供する `syslog-drain` と呼ばれる機能をまず使用します。また、CF側で作成した syslog-drain が転送するSyslogメッセージを受信するサーバとして、`Environment ActiveGate`（以下、EAG）を途中に用意します。Syslog メッセージをこのEAGで受信させ、そのメッセージをHTTPSでDynatraceのSaaS環境に転送するという流れになります。全体概要としては下図のような接続形態になり、3つのコンポーネントが必要です。
```text:Syslog forwarding
[syslog-drain] ---(syslog)---> [syslog endpoint on Environment ActiveGate]---(https)--->[Dynatrace SaaS]
```
### 作成手順
ここから先では、CFのログをDynatraceに取り込むために必要となる3つのコンポーネントについて、解説していきます。
* **syslog-drain を作成する**
Syslog-drainの作成方法は、[本家のCloud Foundryのページ](https://docs.cloudfoundry.org/devguide/services/log-management.html)を参照しましょう。ここではCFコマンドを使って、新規に syslog-drain を作成します。Marketplace に Dynatrace用のSyslogサービスは定義されていないため、先ほどのリンクに記載がある「Using Services not available in your Marketplace」に従い、syslog-drain を user-provided service instance として作成します。
```text:サービスの事前確認
yasusuzu@DT-7PW8FY3:src/blogs/cloudfoundry/spring-music$ cf services
Getting service instances in org <Org>_sap-btp-yorcv20i / space Dev as yasuyuki.suzuki@pm.me...

name               offering        plan       bound apps     last operation     broker                                                  upgrade available
cloud-logging      cloud-logging   standard   spring-music   create succeeded   sm-cloud-logging-6fe5fa99-a677-4b86-a220-19b6d29e6540   no
dynatraceservice   user-provided              spring-music   update succeeded
```
```text:syslog-drainサービスの新規作成
yasusuzu@DT-7PW8FY3:src/blogs/cloudfoundry/spring-music$ cf create-user-provided-service syslog-activegate
Creating user provided service syslog-activegate in org <Org>_sap-btp-yorcv20i / space Dev as yasuyuki.suzuki@pm.me...
OK

yasusuzu@DT-7PW8FY3:src/blogs/cloudfoundry/spring-music$ cf services
Getting service instances in org <Org>_sap-btp-yorcv20i / space Dev as yasuyuki.suzuki@pm.me...

name                offering        plan       bound apps     last operation     broker                                                  upgrade available
cloud-logging       cloud-logging   standard   spring-music   create succeeded   sm-cloud-logging-6fe5fa99-a677-4b86-a220-19b6d29e6540   no
dynatraceservice    user-provided              spring-music   update succeeded
syslog-activegate   user-provided                             create succeeded <<< 新規作成
yasusuzu@DT-7PW8FY3:src/blogs/cloudfoundry/spring-music$
```
これで、まずはSyslog-drainの器ができあがったので、これにSyslogの転送先を追加します。`cf uups`コマンド（uups とは update-user-provided-service のこと）で syslog の転送先IPアドレスとポート番号を指定します。
```text:syslog-drainの転送先を指定
yasusuzu@DT-7PW8FY3:src/blogs/cloudfoundry/spring-music$ cf uups syslog-activegate -l syslog://<Global-ip-address>:<tcp port number>
Updating user provided service syslog-activegate in org <Org>_sap-btp-yorcv20i / space Dev as yasuyuki.suzuki@pm.me...
OK

TIP: Use 'cf restage' for any bound apps to ensure your env variable changes take effect
```
その後、`cf service syslog-activegate`コマンドで、先ほどの設定が正しく反映されている確認します。
```text:syslog-drainの設定内容を確認
yasusuzu@DT-7PW8FY3:src/blogs/cloudfoundry/spring-music$ cf service syslog-activegate
Showing info of service syslog-activegate in org <Org>_sap-btp-yorcv20i / space Dev as yasuyuki.suzuki@pm.me...

name:                syslog-activegate
guid:                5cbff5bf-7824-4f66-831d-f90ac65af0b3
type:                user-provided
tags:
route service url:
syslog drain url:    syslog:/<global-ip-address>:<tcp port number> <<< ここを確認

Showing status of last operation:
   status:    update succeeded
   message:   Operation succeeded
   started:   2024-07-22T08:05:38Z
   updated:   2024-07-22T08:05:38Z

Showing bound apps:
   There are no bound apps for this service instance.

yasusuzu@DT-7PW8FY3:/src/blogs/cloudfoundry/spring-music$
```
ここまでで、SAP BTP Cloud Foundry側の設定は、一旦終了です。その1でDeployしたJavaアプリの `manifest.yaml` で、この syslog-drain service とアプリを紐付ければOKです。
```text:manifest.yaml
---
applications:
- name: spring-music
  memory: 768m
  random-route: true
  hostname: spring-music
  path: build/libs/spring-music-1.0.jar
  buildpacks:
  - java_buildpack
  services:
  - dynatraceservice
  - syslog-activegate  <<< Javaのアプリのmanifest.yamlでサービスインスタンスとの紐付けをここで宣言
  env:
    JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{enabled: false}'
    SPRING_PROFILES_ACTIVE: http2
    JBP_CONFIG_OPEN_JDK_JRE: '{ jre: { version: 17.+ } }'
```
:::note warn
今回のブログで紹介している方法は、syslog を TCP を使って転送するやり方です。この方法の場合、Syslogメッセージは暗号化されず、平文で送付されます。そのため、SyslogメッセージをSecureに暗号化して転送させたい場合は、syslog-tls を使用する必要がありますので、ご注意下さい。
:::
* **syslog endpoint on EAGを作成する**
JavaアプリをモニタリングしているDynatraceのSaaSテナントから、ActiveGateをダウンロードして、VM上にインストールします。インストールする手順はここでは、割愛します。[こちらのヘルプ](https://docs.dynatrace.com/docs/setup-and-configuration/dynatrace-activegate/installation/linux/linux-install-an-environment-activegate)をご覧下さい。なお、今回使用する ActiveGate は、syslog endpoint の機能を有している必要があるため、インストールするバージョンは、`v1.293以降` である必要がありますので、ご注意下さい。この機能に関するRelease Notesもありますので、[こちら](https://docs.dynatrace.com/docs/whats-new/release-notes/activegate/sprint-293#syslog-ingestion)にてご確認下さい。EAGをVMにインストールできたら、Syslogメッセージを受信できるように設定していきますが、そちらのやりかたも[ヘルプ](https://docs.dynatrace.com/docs/shortlink/lma-ingestion-syslog)に記載があります。まとめると、以下の手順で syslog endpoint を有効にしていきます。
  * EAGでSyslog機能の有効化
EAGをインストールしたVMのファイル(`/var/lib/dynatrace/remotepluginmodule/agent/conf/extensionsuser.conf`)にSYSLOG機能を有効にする宣言を加えます。
    ```text:extensionsuser.conf
    ubuntu@ip-172-31-41-147:/var/lib/dynatrace/remotepluginmodule/agent/conf$ cat 
    extensionsuser.conf 
    #STATSD configuration
    statsdenabled=false
    StatsdPort=18126
    
    #Syslog configuration
    syslogenabled=true  <<< ここでSYSLOG機能の有効を宣言
    ubuntu@ip-172-31-41-147:/var/lib/dynatrace/remotepluginmodule/agent/conf$
    ```
  * CF syslog-drain からのSYSLOGメッセージに属性を付与したり、Parseしたりする宣言
  同じくEAGをインストールしたVMのファイル（`/var/lib/dynatrace/remotepluginmodule/agent/conf/syslog.yaml`）を下記のように変更していきます。
    ```text:/var/lib/dynatrace/remotepluginmodule/agent/conf/syslog.yaml
    receivers:
    syslog/udp:
      udp:
        listen_address: "0.0.0.0:514"
        add_attributes: true
      protocol: rfc5424
      operators:
        - type: syslog_parser
          protocol: rfc5424
  
    syslog/tcp:
      tcp:
        listen_address: "0.0.0.0:601"   <<< syslog-tcp をどのポート番号で受けるか宣言
        add_attributes: true　　
      protocol: rfc5424
      enable_octet_counting: true
      operators:　　　　　　　　　　　　　<<< 属性（Attributes）やParseをどのようにやるか宣言
        - type: syslog_parser
          protocol: rfc5424
        - type: add
          field: attributes.cloud.provider
          value: "SAP BTP CF"
        - type: add
          field: attributes.cloud.region
          value: "Tokyo"
        - type: add
          field: attributes.cloud.logsource
          value: "syslog on EAG"
    ```

* **sysoog メッセージをDynatraceのUIで確認する**
cf push コマンドで、先ほど更新した Java サンプルアプリの manifest.yaml を使って、Javaアプリを再度Deployします。JavaアプリをDeployした後、syslog-drain サービスインスタンスとこのJavaアプリがBindingされていることを cf services コマンドで念のため、確認しておきましょう。
    ```text:cf services
    yasusuzu@DT-7PW8FY3:src/blogs/cloudfoundry/spring-music$ cf services
    Getting service instances in org <Org>_sap-btp-yorcv20i / space Dev as 
    yasuyuki.suzuki@pm.me...
      
    name                offering        plan       bound apps     last operation     broker         
                                               upgrade available
    cloud-logging       cloud-logging   standard   spring-music   create succeeded   sm-cloud- 
    logging-6fe5fa99-a677-4b86-a220-19b6d29e6540   no
    dynatraceservice    user-provided              spring-music   update succeeded
    syslog-activegate   user-provided              spring-music   update succeeded   <<< spring- 
    music と binding されていることを確認
    yasusuzu@DT-7PW8FY3:src/blogs/cloudfoundry/spring-music
    ```
ここまで確認できたら Dynatrace のUIにアクセスして、`Logs and evnets`でCFのログが転送されてきているか確認しましょう。画面上部のフィルタ部分で、`cloud.provider:SAP BTP CF`でフィルタされた結果が表示されていれば、正しくSAP BTP Cloud Foundry のログが転送されてきている証拠です。パチパチパチ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778724/be1d031e-18a2-000a-5194-3c6d767ff0b8.png)
試しに、Javaのアプリにアクセスし、Webブラウザから新しいアルバムを追加してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778724/21915693-562e-4342-6b0d-dd98e2861a95.png)
このアルバムのUpdate操作がDistributed Trace画面に出力されていますが、ログの出力もTrace/Span情報と紐付いているので、何かトラブルがあったときもトラブルシューティングがしやすいのではないでしょうか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778724/faed1d4d-2dd3-6e87-e4fe-51ca5e35bd9b.png)
## まとめ
今回は、SAP BTP Cloud FoundryにデプロイしたJavaのアプリの可観測性（Observability）を実現する方法を2回に分けてまとめました。1回目は、分散トレース情報の可視化、2回目はログの取り込みについてです。やはり、メトリクス、トレース、ログの3つの三本柱がひとつのプラットフォーム上で集約され分析できると大変便利になると思います。ログとトレースの紐付けや、ログの出力から何かを追いかける際も、使い慣れたひとつのUI上で分析できると時間短縮にも貢献できるかなと。

まだ、Dynatraceを触ったことがない方、このブログを見てやってみたいと思われた方は、下記フリートライアルにてお試し下さい。↓↓↓

Dynatraceフリートライアル → https://www.dynatrace.com/ja/trial/

## 参考情報
* [Syslog endpoint on Environment ActiveGate のブログ](https://www.dynatrace.com/news/blog/observe-syslog-with-dynatrace-activegate/)
* [Syslog を Fluentd を使ってDynatraceに取り込む](https://docs.dynatrace.com/docs/observe-and-explore/logs/lma-log-ingestion/lma-log-ingestion-via-api/lma-send-syslogs-via-fluentd)