Tomcat 環境における RuoYi モノリシックアプリケーションのデプロイと可観測性のベストプラクティス¶
本ドキュメントは、RuoYi のモノリシックアプリケーション をベースに、外部 Tomcat 環境で可観測性を実現するためのベストプラクティスを説明します。
実現目標¶
- メトリクス情報の収集
- トレース情報の収集
- ログ情報の収集
- リアルユーザーモニタリング(RUM)情報の収集
- セッションリプレイ ユーザーがフロントエンドにアクセスする一連のセッション録画情報(ボタンクリック、画面操作、滞在時間など)を取得します。これにより、ユーザーの真の意図や操作の再現に役立ちます。
バージョン情報¶
- Tomcat (9.0.81)
- Springboot(2.6.2)
- JDK (>=8)
- DDTrace (>=1.0)
特記事項
Springboot プロジェクトの場合、Tomcat のメジャーバージョンは Springboot に内蔵されている Tomcat のメジャーバージョンと一致している必要があります。そうしないと、起動時に異常が発生する可能性があります。
RuoYi のモノリシックアプリケーション¶
- ソースコードのダウンロード
- 内蔵 Tomcat の削除
プロジェクトルートディレクトリの pom.xml を修正します。
......
<dependencyManagement>
<dependencies>
<!-- SpringBootの依存関係設定-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.15</version>
<type>pom</type>
<scope>import</scope>
<!-- 内蔵 Tomcat を除外 -->
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
......
war出力
ruoyi-admin モジュール配下の pom.xml ファイルを修正します。
- ログ設定の調整
ruoyi-admin/src/main/resources に新規ファイル logback-spring.xml を作成します。内容は以下の通りです。
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- ログ保存先パス -->
<property name="log.path" value="/home/root/ruoyi/logs" />
<!-- ログ出力フォーマット -->
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - [%method,%line] %X{dd.service} %X{dd.trace_id} %X{dd.span_id} - %msg%n" />
<!-- コンソール出力 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- システムログ出力 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<!-- ローテーションポリシー:時間ベースでログファイルを作成 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- ログファイル名フォーマット -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- ログの最大保持期間 60日 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- フィルタリングするレベル -->
<level>INFO</level>
<!-- マッチ時の動作:受け入れ(記録) -->
<onMatch>ACCEPT</onMatch>
<!-- マッチしない場合の動作:拒否(記録しない) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<!-- ローテーションポリシー:時間ベースでログファイルを作成 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- ログファイル名フォーマット -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- ログの最大保持期間 60日 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- フィルタリングするレベル -->
<level>ERROR</level>
<!-- マッチ時の動作:受け入れ(記録) -->
<onMatch>ACCEPT</onMatch>
<!-- マッチしない場合の動作:拒否(記録しない) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- ユーザーアクセスログ出力 -->
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-user.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日次ローテーション -->
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- ログの最大保持期間 60日 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- システムモジュールのログレベル制御 -->
<logger name="com.ruoyi" level="info" />
<!-- Spring のログレベル制御 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!-- システム操作ログ -->
<root level="debug">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
<!-- システムユーザー操作ログ -->
<logger name="sys-user" level="info">
<appender-ref ref="sys-user"/>
</logger>
</configuration>
- コンパイル
プロジェクトルートディレクトリで以下のコマンドを実行してコンパイルします。
Maven がインストールされていない場合は、事前に Maven をインストールしてからコンパイルを実行してください。
[INFO] --- spring-boot:2.5.15:repackage (default) @ ruoyi-admin ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for ruoyi 4.7.7:
[INFO]
[INFO] ruoyi .............................................. SUCCESS [ 0.179 s]
[INFO] ruoyi-common ....................................... SUCCESS [ 4.622 s]
[INFO] ruoyi-system ....................................... SUCCESS [ 0.770 s]
[INFO] ruoyi-framework .................................... SUCCESS [ 0.950 s]
[INFO] ruoyi-quartz ....................................... SUCCESS [ 0.388 s]
[INFO] ruoyi-generator .................................... SUCCESS [ 0.378 s]
[INFO] ruoyi-admin ........................................ SUCCESS [ 4.554 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12.287 s
[INFO] Finished at: 2023-10-13T16:30:12+08:00
[INFO] ------------------------------------------------------------------------
DataKit¶
- DataKit のインストール
- コレクターの有効化
DataKit のインストール¶
DataKit インストールドキュメント を参照してください。
DataKit で DDTrace コレクターを有効化¶
DDTrace コレクターはアプリケーションのトレース情報を収集するために使用します。DDTrace コレクター の導入ドキュメントを参照してください。
DataKit で Log コレクターを有効化¶
Log コレクターはログ情報を収集するために使用します。Log コレクター の導入ドキュメントを参照してください。
以下の設定を調整する必要があります。
logfiles = [
"/home/liurui/ruoyi/logs/*.log",
]
## サービス名を追加。空の場合は $source を使用。
service = "ruoyi"
## Grok パイプラインスクリプト名。
pipeline = "ruoyi.p"
logfiles:収集するログファイルのパスservice:サービス名pipeline:ログ解析
Pipeline 設定
Pipeline はデータガバナンスに使用され、ここでは主にログ情報を抽出してトレース情報と関連付けます。
datakit/pipeline/ ディレクトリに ruoyi.p ファイルを作成し、内容は以下の通りです。
grok(_, "%{TIMESTAMP_ISO8601:time} %{NOTSPACE:thread_name} %{LOGLEVEL:status}%{SPACE}%{NOTSPACE:class_name} - \\[%{NOTSPACE:method_name},%{NUMBER:line}\\] %{DATA:service_name2} %{DATA:trace_id} %{DATA:span_id} - %{GREEDYDATA:msg}")
default_time(time,"Asia/Shanghai")
DataKit で StatsD コレクターを有効化¶
StatsD コレクターはメトリクス情報を収集するために使用します。StatsD コレクター の導入ドキュメントを参照してください。
DataKit で RUM コレクターを有効化¶
RUM コレクター: RUM コレクターは、Web ページまたはモバイル端末から報告されるユーザーアクセス監視データを収集するために使用します。RUM コレクター の導入ドキュメントを参照してください。
DataKit の再起動¶
DataKit の再起動 を参照してください。
DDTrace¶
dd-trace-java をダウンロードします。可能な限り最新バージョンをダウンロードしてください。
RUM の作成¶
- Guance にログインします。
ユーザーアクセスモニタリングを選択し、アプリケーション一覧を選択して、アプリケーションを作成をクリックします。アプリケーション名にruoyi-adminを入力し、アプリケーション IDは自由に設定するか、ランダム生成ボタンをクリックします。アプリケーションタイプはwebを選択します。右側のSDK 設定にはいくつかのタイプがありますが、ここではCDN 同期読み込みを選択します。スクリプトの内容をコピーしておいてください。後で使用します。作成ボタンをクリックして作成を完了します。
Tomcat¶
Tomcat のダウンロード¶
対応するバージョンの Tomcat をダウンロードします。
DDTrace の設定¶
Tomcat の bin ディレクトリにスクリプトファイル setenv.sh を新規作成します。
export CATALINA_OPTS="-javaagent:/home/root/agent/dd-java-agent-1.14.0-guance.jar \
-Ddd.tags=env:test \
-Ddd.jmxfetch.enabled=true \
-Ddd.jmxfetch.statsd.host=localhost \
-Ddd.jmxfetch.statsd.port=8125 \
-Ddd.jmxfetch.tomcat.enabled=true\
-Dlogging.config=classpath:logback-spring.xml"
javaagent:ddtraceのパスを指定します。Dlogging.config: アプリケーションのログをlogback形式で出力するように指定します。アプリケーション内部で log4j を使用している場合は、対応するファイルを指定してください。
アプリケーションのデプロイ¶
パッケージ化済みのアプリケーション RuoYi/ruoyi-admin/target/ruoyi-admin.war を Tomcat の webapps ディレクトリにコピーします。
Tomcat の起動¶
bin/startup.sh を実行します。
apache-tomcat-9.0.81/bin$ ./startup.sh
Using CATALINA_BASE: /home/root/middleware/apache-tomcat-9.0.81
Using CATALINA_HOME: /home/root/middleware/apache-tomcat-9.0.81
Using CATALINA_TMPDIR: /home/root/middleware/apache-tomcat-9.0.81/temp
Using JRE_HOME: /home/root/middleware/jdk/jdk-11.0.18
Using CLASSPATH: /home/root/middleware/apache-tomcat-9.0.81/bin/bootstrap.jar:/home/root/middleware/apache-tomcat-9.0.81/bin/tomcat-juli.jar
Using CATALINA_OPTS: -javaagent:/home/root/agent/dd-java-agent-1.14.0-guance.jar -Ddd.tags=env:test -Ddd.jmxfetch.enabled=true -Ddd.jmxfetch.statsd.host=localhost -Ddd.jmxfetch.statsd.port=8125 -Ddd.jmxfetch.tomcat.enabled=true -Dlogging.config=classpath:logback-spring.xml
Tomcat started.
RUM の組み込み¶
Tomcat 起動後、war アプリケーションが自動的に展開されます。/webapps/ruoyi-admin/WEB-INF/classes/templates ディレクトリに移動し、include.html を修正して、前の手順でコピーしたスクリプトコードを head タグ内に貼り付けます。
<head th:fragment="header(title)">
...
<script src="https://static.guance.com/browser-sdk/v3/dataflux-rum.js" type="text/javascript"></script>
<script>
window.DATAFLUX_RUM &&
window.DATAFLUX_RUM.init({
applicationId: 'APP_ID',
datakitOrigin: 'http://localhost:9529', // プロトコル(//を含む)、ドメイン名(またはIPアドレス)[およびポート番号]
env: 'production',
version: '1.0.0',
service: 'browser',
sessionSampleRate: 100,
sessionReplaySampleRate: 70,
trackInteractions: true,
traceType: 'ddtrace', // 任意。デフォルトは ddtrace。現在サポートされているのは ddtrace、zipkin、skywalking_v3、jaeger、zipkin_single_header、w3c_traceparent の6種類
allowedTracingOrigins: ['http://localhost:8080','http://localhost:8080/ruoyi-admin'], // 任意。トレースコレクターに必要なヘッダーを注入するリクエストのリスト。リクエストのオリジンまたは正規表現で指定可能
});
window.DATAFLUX_RUM && window.DATAFLUX_RUM.startSessionReplayRecording()
</script>
...
</head>
applicationId:コピーした内容をそのまま使用します。調整は不要です。datakitOrigin:RUM データを受け取る DataKit のアドレスです。allowedTracingOrigins:バックエンドの APM と連携するために使用します。フロントエンドが API を呼び出す際に、指定されたオリジンに対してトレースに必要なヘッダー情報を追加します。
動作確認¶
http://localhost:8080/ruoyi-admin にアクセスします。デフォルトのユーザー名は admin、パスワードは admin123 です。
ログ¶
ログの詳細画面では、現在のログに対応するトレース情報を確認できます。
トレース情報¶
トレースからログやメトリクス情報を確認することもできます。







