Posted at

CloudWatch Logsにslf4j/logbackでログを送付する単体Javaアプリ

忘れないうちにメモ。CloudWatch Logsにログを送付する仕組みを理解しようとサンプルを作っていたけど、参考にするサイトがなかなか見つからなかったので。


前提


  1. なるべく作りたくない → GithubとかにあるOSSを利用

  2. 最小限のコードで送付したい

  3. Gradle対応


結果

こうなりました。

https://github.com/kojiisd/cloudwatch-logs-java-standalone


利用したOSS

cloudwatch-logback-appender

https://github.com/j256/cloudwatch-logback-appender


使い方

logback.xmlの内容を編集すればある程度自由にログを流しこめます。

    <appender name="CLOUDWATCH" class="com.j256.cloudwatchlogbackappender.CloudWatchAppender">

<region>us-east-1</region>
<accessKeyId>XXXXXXX</accessKeyId>
<secretKey>XXXXXXX</secretKey>
<logGroup>test-loggroup</logGroup>
<logStream>test-logstream</logStream>
<layout>
<pattern>[%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - %msg%n</pattern>
</layout>
<maxBatchSize>32</maxBatchSize>
</appender>

accessKeyIdsecretKey は項目自体を削除すれば、実行マシンのAWSConfigを見に行くらしい(試してないけど)


実行結果

無事ログがCloudWatch Logsに出力されました。(ロググループやログストリームは存在しなければ作成してくれる)

スクリーンショット 2019-02-17 19.18.35.png


注意点

当たり前ですが、ライブラリの中でCloudWatch Logsにデータを送付するために、色々と初期化だったりデータ送付を行います。その処理はスレッド実行されるので、呼び出し元のロギング処理が終了してアプリが終了すると、自動的に子スレッド側も終了すわけで、ログがCloudWatch Logsに送付されません。(実際にはこんな単体アプリでのログ送付なんてないと思うのでそこまで気にすることではない気がしますが)OSS側のソースを見ていて気づきました。

それを回避するために、わざと実装の中にSleep処理を20秒ほど入れています。


まとめ

注意点の部分さえハマらなければ、とても簡単に実現できました。