Logstash + Elasticsearch連携時のLogstash confメモ(jsonからconvert, filter, dateなど)
LogstashからElasticsearchへデータを送信する仕組みを試しました。Logstashのconfの参考になれば幸い。
json側のフィールドをElasticsearchのdate型にconvertしたり、文字列を数値にconvertしたりしました。
ログはjsonフォーマット
{"reportDate":"2016-11-08 00:00:00","reportType":"report","gender":"female","ageBracket":"18-24","value":"269"}
Logstashのconfファイル
input { file { path => "/path_to_log_file" codec => "json" } } filter { date { match => ["reportDate", "YYYY-MM-dd HH:mm:ss" ] } date { match => ["reportDate", "yyyy-MM-dd HH:mm:ss"] target => "reportDate" } mutate { convert => { "value" => "integer" } } } output { elasticsearch { hosts => ["localhost:9200"] index => "test" } }
Logstashはinput/codec/filter/outputのそれぞれの処理を理解する必要がある。
今回の例でいうと以下のように整理できる。
1: input
- inputはログファイル(file)から行う
2:codec
- inputから受け取ったログファイルをjson形式に整形する
3:filter
- reportDateをElasticsearchの@timestampへ適応させている。(以下のコードが参考箇所)
date { match => ["reportDate", "YYYY-MM-dd HH:mm:ss" ] }
- また、reportDateの値はElasticsearchの1つのvalueとしてインデックスされるが型がdate型に変換している。(以下のコードが参考箇所)
date { match => ["reportDate", "yyyy-MM-dd HH:mm:ss"] target => "reportDate" }
- 最後にvalueの値をinteger型に変換している(以下のコードが参考箇所)
mutate { convert => { "value" => "integer" } }
4:output
- ログの出力先にElasticsearchを指定している。インデックスはtest。
関連エントリ
go langからGoogle Analytics APIを使う
こちらの記事↓ではSpring Boot + kotlinからの利用方法でしたがgoからの利用も調査しました。
Spring Boot + kotlinでGoogle Analytics APIを使ってみた - 平日インプット週末アウトプットぶろぐ
簡易的なデータの取り方を確認できたので記載。
main.go
package main import ( "fmt" "log" "os" "golang.org/x/oauth2" "golang.org/x/oauth2/google" analytics "google.golang.org/api/analytics/v3" ) func main() { client, err := google.DefaultClient( oauth2.NoContext, "https://www.googleapis.com/auth/analytics.readonly") if err != nil { log.Fatalf("Unable to read client : %v", err) } service, err := analytics.New(client) if err != nil { log.Fatalf("Unable to Access Google Analytics: %v", err) } result, err := service.Data.Ga.Get("ga:"+os.Getenv("PROFILE_ID"), "yesterday", "today", "ga:sessions").Dimensions("ga:visitorGender,ga:visitorAgeBracket").Do() if err != nil { log.Fatalf("Unable to get data: %v", err) } for _, row := range result.Rows { fmt.Printf("%s,%s,%s\n", row[0], row[1], row[2]) } }
実行する
GOOGLE_APPLICATION_CREDENTIALS=secret.json PROFILE_ID=xxxxx go run main.go
実行結果
$ GOOGLE_APPLICATION_CREDENTIALS=secret.json PROFILE_ID=xxxxx go run main.go female,18-24,260 female,25-34,1495 female,35-44,1503 female,45-54,424 female,55-64,55 male,18-24,28 male,25-34,106 male,35-44,132 male,45-54,32
※ 2016/11現在、Google Analytics APIのgoのサポートはalphaバージョンですのでご利用はご注意ください
Spring Boot + KotlinでGoogle Analytics APIを使ってみた
Googleアナリテクスの設定は本家情報を参照
https://developers.google.com/analytics/devguides/reporting/core/v3/quickstart/service-java?hl=ja
ビルドツールはgraldeを使う
compile "com.google.apis:google-api-services-analytics:$google_api_version"
versionは4.7を使う。
Configurationのインスタンス
@Configuration open class GoogleAnalyticsConfig { val applicationName = "googleAnalytics" val jsonFactory = JacksonFactory.getDefaultInstance()!! val serviceAccountEmail = "xxxxx@xxxxx.iam.gserviceaccount.com" val keyFileLocation = "/credential.p12" @Bean open fun analytics(): Analytics { val httpTransport = GoogleNetHttpTransport.newTrustedTransport() val credential = GoogleCredential.Builder() .setTransport(httpTransport) .setJsonFactory(jsonFactory) .setServiceAccountId(serviceAccountEmail) .setServiceAccountPrivateKeyFromP12File( File(javaClass.getResource(keyFileLocation).path)) .setServiceAccountScopes(AnalyticsScopes.all()) .build(); return Analytics.Builder(httpTransport, jsonFactory, credential) .setApplicationName(applicationName).build(); } }
データの取得
- 昨日から今日までのセッション数を性別と年齢別に取得する
- "ga:" + "xxxxx"のxxxxxはアナリティクスのprofileIDを指定する
- 簡易的なコントローラーを用意してlog出力
@RestController open class AnalyticsController @Autowired constructor(val googleAnalytics: Analytics) { val log: Logger = LoggerFactory.getLogger("ANALYTICS"); @RequestMapping(value = "/analytics", method = arrayOf(RequestMethod.GET)) fun index(): String { val gaData = googleAnalytics.data().ga() .get("ga:" + "xxxxx", "yesterday", "today", "ga:sessions") .setDimensions("ga:visitorGender,ga:visitorAgeBracket") .execute() for (row in gaData.rows) { log.info(Moshi.Builder().build() .adapter(List::class.java) .toJson(row)) } return "ok"; } }
出力例
{"@timestamp":"2016-11-07T12:10:56.021+09:00","@version":1,"message":"[\"female\",\"18-24\",\"xxx\"]","logger_name":"ANALYTICS","thread_name":"http-nio-8080-exec-7","level":"INFO","level_value":20000,"HOSTNAME":"xxxxx"} {"@timestamp":"2016-11-07T12:10:56.022+09:00","@version":1,"message":"[\"female\",\"25-34\",\"xxx\"]","logger_name":"ANALYTICS","thread_name":"http-nio-8080-exec-7","level":"INFO","level_value":20000,"HOSTNAME":"xxxxx"} {"@timestamp":"2016-11-07T12:10:56.023+09:00","@version":1,"message":"[\"female\",\"35-44\",\"xxx\"]","logger_name":"ANALYTICS","thread_name":"http-nio-8080-exec-7","level":"INFO","level_value":20000,"HOSTNAME":"xxxxx"} {"@timestamp":"2016-11-07T12:10:56.024+09:00","@version":1,"message":"[\"female\",\"45-54\",\"xxx\"]","logger_name":"ANALYTICS","thread_name":"http-nio-8080-exec-7","level":"INFO","level_value":20000,"HOSTNAME":"xxxxx"} {"@timestamp":"2016-11-07T12:10:56.025+09:00","@version":1,"message":"[\"female\",\"55-64\",\"xxx\"]","logger_name":"ANALYTICS","thread_name":"http-nio-8080-exec-7","level":"INFO","level_value":20000,"HOSTNAME":"xxxxx"} {"@timestamp":"2016-11-07T12:10:56.025+09:00","@version":1,"message":"[\"male\",\"18-24\",\"xxx\"]","logger_name":"ANALYTICS","thread_name":"http-nio-8080-exec-7","level":"INFO","level_value":20000,"HOSTNAME":"xxxxx"} {"@timestamp":"2016-11-07T12:10:56.026+09:00","@version":1,"message":"[\"male\",\"25-34\",\"xxx\"]","logger_name":"ANALYTICS","thread_name":"http-nio-8080-exec-7","level":"INFO","level_value":20000,"HOSTNAME":"xxxxx"} {"@timestamp":"2016-11-07T12:10:56.027+09:00","@version":1,"message":"[\"male\",\"35-44\",\"xxx\"]","logger_name":"ANALYTICS","thread_name":"http-nio-8080-exec-7","level":"INFO","level_value":20000,"HOSTNAME":"xxxxx"} {"@timestamp":"2016-11-07T12:10:56.028+09:00","@version":1,"message":"[\"male\",\"45-54\",\"xxx\"]","logger_name":"ANALYTICS","thread_name":"http-nio-8080-exec-7","level":"INFO","level_value":20000,"HOSTNAME":"xxxxx"}