intra-mart AccelPlatformのリクエストログをStackdriverに出力してみた。
さらに、StackdriverからPub/Sub, BigQuery, Cloud Storageにエクスポートしてみた。
シンクを作成すればいいだけなので簡単。
BigQuery, Cloud Storageへは1時間間隔で自動エクスポート、Pub/Subへは即時配信される模様。
Pub/Subに流したログはGoogle_pubsub input plugin | Logstashとかで受け取れるので他にも色々融通が利きそう。
以下、やったこと。
1. Google Cloud Console からプロジェクトを作成
既存のプロジェクトがあれば、新規に作成する必要は特になし。
2. JSON形式でサービスアカウントキーを作成し、保存
3. 必要なjarファイルを取得
3.1 以下の依存に対して mvn dependency:copy-dependencies などして取得可能
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-logging-logback</artifactId>
<version>0.21.0-alpha</version>
</dependency>
4. 解決されるjarはこんな感じ
- com.google.auth:google-auth-library-oauth2-http:jar:0.7.0
- org.threeten:threetenbp:jar:1.3.3
- io.netty:netty-handler:jar:4.1.11.Final
- com.google.instrumentation:instrumentation-api:jar:0.4.2
- org.codehaus.mojo:animal-sniffer-annotations:jar:1.14
- com.google.auth:google-auth-library-credentials:jar:0.7.0
- com.google.auto.value:auto-value:jar:1.2
- io.netty:netty-codec:jar:4.1.11.Final
- com.google.http-client:google-http-client-jackson2:jar:1.19.0
- com.fasterxml.jackson.core:jackson-core:jar:2.1.3
- com.google.cloud:google-cloud-core:jar:1.2.3
- io.netty:netty-tcnative-boringssl-static:jar:2.0.3.Final
- joda-time:joda-time:jar:2.9.2
- io.grpc:grpc-protobuf:jar:1.4.0
- com.google.http-client:google-http-client:jar:1.19.0
- ch.qos.logback:logback-classic:jar:1.2.3
- io.netty:netty-common:jar:4.1.11.Final
- io.grpc:grpc-stub:jar:1.4.0
- commons-logging:commons-logging:jar:1.1.1
- org.json:json:jar:20160810
- com.google.protobuf:protobuf-java-util:jar:3.3.0
- io.netty:netty-codec-socks:jar:4.1.11.Final
- io.grpc:grpc-netty:jar:1.4.0
- com.google.protobuf:protobuf-java:jar:3.3.0
- com.google.cloud:google-cloud-logging-logback:jar:0.20.3-alpha
- io.netty:netty-handler-proxy:jar:4.1.11.Final
- org.apache.httpcomponents:httpclient:jar:4.0.1
- io.netty:netty-resolver:jar:4.1.11.Final
- com.google.cloud:google-cloud-logging:jar:1.2.3
- com.google.code.findbugs:jsr305:jar:1.3.9
- commons-codec:commons-codec:jar:1.3
- com.google.j2objc:j2objc-annotations:jar:1.1
- com.google.cloud:google-cloud-core-grpc:jar:1.2.3
- ch.qos.logback:logback-core:jar:1.2.3
- com.google.api.grpc:proto-google-cloud-logging-v2:jar:0.1.13
- io.netty:netty-transport:jar:4.1.11.Final
- com.google.errorprone:error_prone_annotations:jar:2.0.18
- com.google.api:gax:jar:1.4.2
- com.google.api.grpc:proto-google-iam-v1:jar:0.1.13
- com.google.guava:guava:jar:22.0
- com.google.code.gson:gson:jar:2.7
- io.grpc:grpc-auth:jar:1.4.0
- io.netty:netty-codec-http:jar:4.1.11.Final
- io.netty:netty-buffer:jar:4.1.11.Final
- org.slf4j:slf4j-api:jar:1.7.25
- com.google.api.grpc:proto-google-common-protos:jar:0.1.13
- com.google.api:gax-grpc:jar:0.21.2
- io.grpc:grpc-protobuf-lite:jar:1.4.0
- org.apache.httpcomponents:httpcore:jar:4.0.1
- io.netty:netty-codec-http2:jar:4.1.11.Final
- io.grpc:grpc-core:jar:1.4.0
- io.grpc:grpc-context:jar:1.4.0
- com.google.api:api-common:jar:1.1.0
5. いくつかのjarを除去
いくつかはAccelPlatformがもつjarと競合していた。
jarjarで機械的にリパッケージしてしまうのが一番楽で早いと思われるが、恐らくその必要はない。
- commons-codec-1.3.jar
- commons-logging-1.1.1.jar
- gson-2.7.jar
- httpclient-4.0.1.jar
- httpcore-4.0.1.jar
- jackson-core-2.1.3.jar
- joda-time-2.9.2.jar
- logback-classic-1.2.3.jar
- logback-core-1.2.3.jar
これらはAccelPlatformがもつjarで代用できるため、除去する。
- guava-22.0.jar
AccelPlatformがもつjarのバージョンが古いせいで、このバージョンを使う必要がある。不安ならリパッケージだが、guavaは互換性に関しては優秀なので、そのままguava-22.0を使っても問題無いと判断した。
- slf4j-api-1.7.25.jar
AccelPlatformがもつlog4j-over-slf4jで代用可能なためこれも除去でいいだろう。
必要なjarだが、デプロイする度に消えるのは嫌なのでresin/webapp-jarsの中に放り込んで置く。
6. GOOGLE_APPLICATION_CREDENTIALS
サービスアカウントキーのjsonファイルへのパスを、GOOGLE_APPLICATION_CREDENTIALS環境変数に設定しておく。
システムの環境変数に設定してもいいし、resinを起動するプロセスの親(コンソールやコマンドプロンプト)から
set GOOGLE_APPLICATION_CREDENTIALS=/hoge/foo/bar/service_account_key.json
や
export GOOGLE_APPLICATION_CREDENTIALS=/hoge/foo/bar/service_account_key.json
としておけばいいだろう。
7. logbackの設定ファイル
<included>
<appender name="CLOUD" class="com.google.cloud.logging.logback.LoggingAppender">
<log>request.log</log>
<enhancer>hoge.MDCEnhancer</enhancer>
<flushLevel>INFO</flushLevel>
</appender>
<logger name="REQUEST_LOG" additivity="false">
<level value="info" />
<appender-ref ref="CLOUD" />
</logger>
</included>
こんな感じで設定ファイルを放り込んでおく。
8. MDCEnhancer
LoggingAppenderではencoderが使えないためMDCのエンハンサーを実装しておく。
package hoge;
import java.util.Map;
import org.slf4j.MDC;
import com.google.cloud.logging.LogEntry.Builder;
import com.google.cloud.logging.LoggingEnhancer;
import com.google.cloud.logging.Payload.StringPayload;
import jp.co.intra_mart.common.aid.jdk.java.lang.StringUtil;
public class MDCEnhancer implements LoggingEnhancer {
@Override
public void enhanceLogEntry(final Builder builder) {
final Map<String, String> map = MDC.getCopyOfContextMap();
if (map != null) {
builder.setLabels(map);
final String userCd = map.get("user.cd");
final String method = map.get("request.method");
final String url = map.get("request.url");
if (!StringUtil.isBlank(userCd) && !StringUtil.isBlank(method) && !StringUtil.isBlank(url)) {
builder.setPayload(StringPayload.of(userCd + ' ' + method + ' ' + url));
}
}
}
}
こいつもjarにコンパイル後resin/webapp-jarsの中に放り込んで置く。
とりあえずこんな感じ。
BigQueryが使えるのとGoogle Cloud Pub/Subで連携も容易になるのは大きいかな。