超概要
stackdriver loggingのJavaクライアントライブラリからLogbackを使って利用する場合にはErrorをLogに送っても、Stackdriver ErrorReportingの方にはそのまま入らない。(題名通り
通常はStackdriver loggingにError以上のLogを入れるとErrorReportingの方にも入るのだが(それから通知などに使える)
Javaクライントライブラリ(Logback使用)の場合はどうやっても入らなかった。
これにハマって色々と調べるとなかなかつらいことが判明。
経緯
時代にさかのぼってる感ありだが、最近Java(正確にはKotlin)で動くデスクトップアプリを制作している。
各ユーザーさんの環境で動くアプリケーションがどのようなエラーを吐いているかを見たいので、クラウドのロギングサービスを導入しようと思った。
ちょうどGCPを色々と試していた&Stackdriver ErrorReportingはJavaで使ったことあったので、Stackdriver loggingを使うことにした。
Stackdriver ErrorReportingを使ったとき
→Official
https://cloud.google.com/error-reporting/docs/reference/libraries?hl=ja
このままのコードでやると直接ErrorReportingには飛ばせるのだが、ロガーに追加して投げる処理を追加しないといけない。
これはなんか同じコードが各所で出てきて美しくない。(気がする。
なんとかしてlogger.error("hoge error", exception)
みたいな感じでファイルログと同時にErrorReportingできないものだろうか。
Stackdriver logging with logback
→official
https://cloud.google.com/logging/docs/setup/java?hl=ja
LogbackのAppenderを作れば、logger.なんたらでそのままStackdriver loggingにも入れてくれる。
ここまではOK、ただし
https://cloud.google.com/error-reporting/docs/setup/java?hl=ja
にある通り、
Stackdriver Logging を使用してエラーデータを Error Reporting に送信することもできます。データのフォーマット要件については、Stackdriver Logging でのエラー メッセージのフォーマットをご覧ください。
とあるんだが、何度やってもLoggingにエラー送ってもErrorReportingには何も入らない。
もうちょっと詳しく見てみると
データのフォーマット要件については、Stackdriver Logging でのエラー メッセージのフォーマットをご覧ください。
エラーメッセージのフォーマット?
リンク先を見ると
{
"eventTime": string,
"serviceContext": {
"service": string, // Required.
"version": string
},
"message": string, // Required. Should contain the full exception
// message, including the stack trace.
"context": {
"httpRequest": {
"method": string,
"url": string,
"userAgent": string,
"referrer": string,
"responseStatusCode": number,
"remoteIp": string
},
"user": string,
"reportLocation": { // Required if no stack trace in 'message'.
"filePath": string,
"lineNumber": number,
"functionName": string
}
}
}
いくつかrequiredのフィールドになっているが、Logbackからのloggingには該当するフィールドは入っていない。
(serviceContext > serviceが無いようだった)
たぶんこれかな、ということはわかったのでじゃあ設定でなんとかなるか、と思いきや。
Logbackのxml設定ではserviceContextとかもろもろを設定する項目はない!
ナンテコッタイ
やろうとしたこと
https://cloud.google.com/logging/docs/setup/java?hl=ja#additional_fields_and_labels
この通り、LoggingEnhancerを作成してやればラベルとかは追加できるようだ。
ただこれもGCPのコンソールでの絞り込みで使えるだけでErrorReportingにはいかない。
かといってEnhacerにそれ以上カスタマイズできるようなコードは見当たらない…
結局は
さらに色々と調べるとこんなことも
https://github.com/googleapis/google-cloud-java/issues/4179
デフォではできないんかい!
で、このやりとりの中の別のIssueをたどっていくと
https://github.com/logstash/logstash-logback-encoder
こんなのも。
つまり、logbackのencoderのlayoutを直接いじるクラスを作ればErrorReportingに入るLoggingができるそう。
こちらもありました。
https://github.com/kurochan/logback-stackdriver-logging
結論
クライアントアプリケーションは難しい
javaクライアントライブラリがうまく対応してくれると嬉しい。