これは、なにをしたくて書いたもの?
この前、ElasticsearchのIngest Nodeと、FilebeatのMultiline Messageを試してみました。
ElasticsearchのIngest Nodeを試す - CLOVER🍀
Filebeatで、複数行のログをElasticsearchに取り込んでみる - CLOVER🍀
今度は、この2つを組み合わせて、アプリケーションログを読み込み、Elasticsearchに取り込む際にIngest Nodeのパイプラインで
パースしてみたいと思います。
環境
今回の環境は、こちら。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.3 LTS Release: 18.04 Codename: bionic $ java --version openjdk 11.0.4 2019-07-16 OpenJDK Runtime Environment (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3) OpenJDK 64-Bit Server VM (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3, mixed mode, sharing)
ElasticsearchとFilebeatは、7.5.0を使用します。
$ filebeat version filebeat version 7.5.0 (amd64), libbeat 7.5.0 [6d0d0ae079e5cb1d4f224801ac6df926dfb1594c built 2019-11-26 00:06:12 +0000 UTC] $ curl localhost:9200 { "name" : "ubuntu1804.localdomain", "cluster_name" : "elasticsearch", "cluster_uuid" : "hI0ApgY2Qze4w2_fAz4NTg", "version" : { "number" : "7.5.0", "build_flavor" : "default", "build_type" : "deb", "build_hash" : "e9ccaed468e2fac2275a3761849cbee64b39519f", "build_date" : "2019-11-26T01:06:52.518245Z", "build_snapshot" : false, "lucene_version" : "8.3.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
お題
こちらのエントリで作成したアプリケーションが出力するログを、Filebeatで読み込みIngest Nodeでパースして取り込みたいと思います。
Filebeatで、複数行のログをElasticsearchに取り込んでみる - CLOVER🍀
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.2.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.2.2.RELEASE</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
src/main/java/org/littlewings/spring/example/App.java
package org.littlewings.spring.example; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController @RequestMapping("app") public class App { Logger logger = LoggerFactory.getLogger(App.class); public static void main(String... args) { SpringApplication.run(App.class, args); } @GetMapping("info") public String info() { logger.info("{}, info logging", "hello"); return "info logging"; } @GetMapping("warn") public String warn() { logger.warn("{}, warn logging", "world"); return "warn logging"; } @GetMapping("error") public String error() { logger.error("{}, error logging", "oops!!"); return "error logging"; } @GetMapping("exception") public String exception() { Exception e = new RuntimeException("Oops!!"); logger.error("exception occurred, {}", "why?", e); return "exception logging"; } }
こちらを、以下のコマンドで実行します。
$ java -Dlogging.file.path=/tmp -jar target/simple-logging-web-app.jar
では、FilebeatとElasticsearchの設定をしましょう。
Ingest Nodeのパイプラインを作成する
アプリケーションのログをパースするための、パイプラインを作成します。
Spring Bootのデフォルトのログフォーマットは、このあたりを見ればOKです。
ログをパースするための、Grokパターンを考えます。こんな感じになりました。
(?m)^(?<logtime>\\d\\d\\d\\d-\\d\\d-\\d\\d \\d\\d:\\d\\d:\\d\\d.\\d\\d\\d) *%{LOGLEVEL:loglevel} %{POSINT:pid} --- \\[%{NOTSPACE:thread}\\] %{NOTSPACE:logger} *: *%{GREEDYDATA:logmessage}
「.」が行を跨いでマッチするように、(?m)オプションを使用します。
https://github.com/kkos/oniguruma/blob/v6.9.4/doc/RE#L500-L507
これは、Onigurumaの正規表現をベースにしているので使えます。
では、パイプラインを登録してみましょう。
こんな感じで作成。
$ curl -XPUT -H 'Content-Type: application/json' localhost:9200/_ingest/pipeline/application-log-pipeline -d ' { "description": "My application log pipeline", "processors": [ { "grok": { "field": "message", "patterns": [ "(?m)^(?<logtime>\\d\\d\\d\\d-\\d\\d-\\d\\d \\d\\d:\\d\\d:\\d\\d.\\d\\d\\d) *%{LOGLEVEL:loglevel} %{POSINT:pid} --- \\[%{NOTSPACE:thread}\\] %{NOTSPACE:logger} *: *%{GREEDYDATA:logmessage}" ] } }, { "date": { "field": "logtime", "target_field": "@timestamp", "formats": [ "yyyy-MM-dd HH:mm:ss.SSS" ] } }, { "remove": { "field": ["message", "logtime"] } } ] } '
Grok Processorでパースして
{ "grok": { "field": "message", "patterns": [ "(?m)^(?<logtime>\\d\\d\\d\\d-\\d\\d-\\d\\d \\d\\d:\\d\\d:\\d\\d.\\d\\d\\d) *%{LOGLEVEL:loglevel} %{POSINT:pid} --- \\[%{NOTSPACE:thread}\\] %{NOTSPACE:logger} *: *%{GREEDYDATA:logmessage}" ] } },
キャプチャしたlogtimeをtimestampに変換して
{ "date": { "field": "logtime", "target_field": "@timestamp", "formats": [ "yyyy-MM-dd HH:mm:ss.SSS" ] } },
オリジナルのmessageフィールドと、logtimeフィールドは削除。
{ "remove": { "field": ["message", "logtime"] } }
シミュレーションしてみます。
$ curl -XPOST -H 'Content-Type: application/json' localhost:9200/_ingest/pipeline/application-log-pipeline/_simulate?pretty -d ' > { > "docs": [ > { > "_source": { > "message": "2019-12-07 19:56:26.948 INFO 24075 --- [main] org.littlewings.spring.example.App : No active profile set, falling back to default profiles: default" > } > } > ] > } > ' { "docs" : [ { "doc" : { "_index" : "_index", "_type" : "_doc", "_id" : "_id", "_source" : { "@timestamp" : "2019-12-07T19:56:26.948Z", "loglevel" : "INFO", "logger" : "org.littlewings.spring.example.App", "logmessage" : "No active profile set, falling back to default profiles: default", "pid" : "24075", "thread" : "main" }, "_ingest" : { "timestamp" : "2019-12-10T15:04:04.346329Z" } } } ] }
OKそうです。
Filebeatの設定をする
では、続いてFilebeatの設定を行います。
こちらを参考に。
Parse data by using ingest node | Filebeat Reference [7.5] | Elastic
こんな感じにしてみました。
$ sudo grep -vE ' *#|^$' /etc/filebeat/filebeat.yml filebeat.inputs: - type: log enabled: true paths: - /tmp/spring.log multiline.pattern: '^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}' multiline.negate: true multiline.match: after filebeat.config.modules: path: ${path.config}/modules.d/*.yml reload.enabled: false setup.template.settings: index.number_of_shards: 1 setup.kibana: host: "localhost:5601" output.elasticsearch: hosts: ["localhost:9200"] pipeline: "application-log-pipeline" processors: - add_host_metadata: ~ - add_cloud_metadata: ~ - add_docker_metadata: ~ - add_kubernetes_metadata: ~
取り込むログの設定。
filebeat.inputs: - type: log enabled: true paths: - /tmp/spring.log multiline.pattern: '^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}' multiline.negate: true multiline.match: after
出力先のElasticsearchの設定に、pipelineを加えます。
output.elasticsearch: hosts: ["localhost:9200"] pipeline: "application-log-pipeline"
これで、Filebeatを再起動。
$ sudo systemctl restart filebeat
確認
それでは、アプリケーションにログを出力させます。
$ curl localhost:8080/app/info info logging $ curl localhost:8080/app/exception exception logging $ curl localhost:8080/app/warn warn logging
出力されたログ。
2019-12-10 07:13:56.284 INFO 5683 --- [http-nio-8080-exec-1] org.littlewings.spring.example.App : hello, info logging 2019-12-10 07:14:01.138 ERROR 5683 --- [http-nio-8080-exec-2] org.littlewings.spring.example.App : exception occurred, why? java.lang.RuntimeException: Oops!! at org.littlewings.spring.example.App.exception(App.java:44) ~[classes!/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] 2019-12-10 07:14:44.143 WARN 5683 --- [http-nio-8080-exec-3] org.littlewings.spring.example.App : world, warn logging
インデックスの方を確認してみます。log.offsetの降順ソートで、最後の3件を見ています。
$ curl -XPOST -H 'Content-Type: application/json' 'localhost:9200/filebeat-7.5.0-2019.12.10-000001/_search?pretty&size=3' -d '{"sort": [{"log.offset": "desc"}]}' { "took" : 2, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 16, "relation" : "eq" }, "max_score" : null, "hits" : [ { "_index" : "filebeat-7.5.0-2019.12.10-000001", "_type" : "_doc", "_id" : "PC5g8G4B2wTXVLkwmME1", "_score" : null, "_source" : { "agent" : { "hostname" : "ubuntu1804.localdomain", "id" : "e8bc2292-947e-40dc-96d6-0f91eff31db5", "type" : "filebeat", "ephemeral_id" : "e5f9cd85-1f2b-4738-9daa-2fee6f619531", "version" : "7.5.0" }, "log" : { "file" : { "path" : "/tmp/spring.log" }, "offset" : 9004 }, "logger" : "org.littlewings.spring.example.App", "logmessage" : "world, warn logging", "pid" : "5683", "thread" : "http-nio-8080-exec-3", "input" : { "type" : "log" }, "@timestamp" : "2019-12-10T07:14:44.143Z", "ecs" : { "version" : "1.1.0" }, "loglevel" : "WARN", "host" : { "hostname" : "ubuntu1804.localdomain", "os" : { "kernel" : "4.15.0-70-generic", "codename" : "bionic", "name" : "Ubuntu", "family" : "debian", "version" : "18.04.3 LTS (Bionic Beaver)", "platform" : "ubuntu" }, "containerized" : false, "name" : "ubuntu1804.localdomain", "id" : "2a99d47c230b452d94e8b87696475971", "architecture" : "x86_64" } }, "sort" : [ 9004 ] }, { "_index" : "filebeat-7.5.0-2019.12.10-000001", "_type" : "_doc", "_id" : "Oy5f8G4B2wTXVLkw6MFr", "_score" : null, "_source" : { "agent" : { "hostname" : "ubuntu1804.localdomain", "id" : "e8bc2292-947e-40dc-96d6-0f91eff31db5", "type" : "filebeat", "ephemeral_id" : "e5f9cd85-1f2b-4738-9daa-2fee6f619531", "version" : "7.5.0" }, "log" : { "file" : { "path" : "/tmp/spring.log" }, "offset" : 2061, "flags" : [ "multiline" ] }, "logger" : "org.littlewings.spring.example.App", "logmessage" : "exception occurred, why?\n\njava.lang.RuntimeException: Oops!!\n\tat org.littlewings.spring.example.App.exception(App.java:44) ~[classes!/:na]\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]\n\tat org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar!/:5.2.2.RELEASE]\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.29.jar!/:9.0.29]\n\tat java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]\n", "pid" : "5683", "thread" : "http-nio-8080-exec-2", "input" : { "type" : "log" }, "@timestamp" : "2019-12-10T07:14:01.138Z", "ecs" : { "version" : "1.1.0" }, "loglevel" : "ERROR", "host" : { "hostname" : "ubuntu1804.localdomain", "os" : { "kernel" : "4.15.0-70-generic", "codename" : "bionic", "name" : "Ubuntu", "family" : "debian", "version" : "18.04.3 LTS (Bionic Beaver)", "platform" : "ubuntu" }, "containerized" : false, "name" : "ubuntu1804.localdomain", "id" : "2a99d47c230b452d94e8b87696475971", "architecture" : "x86_64" } }, "sort" : [ 2061 ] }, { "_index" : "filebeat-7.5.0-2019.12.10-000001", "_type" : "_doc", "_id" : "Oi5f8G4B2wTXVLkw1MHi", "_score" : null, "_source" : { "agent" : { "hostname" : "ubuntu1804.localdomain", "id" : "e8bc2292-947e-40dc-96d6-0f91eff31db5", "ephemeral_id" : "e5f9cd85-1f2b-4738-9daa-2fee6f619531", "type" : "filebeat", "version" : "7.5.0" }, "log" : { "file" : { "path" : "/tmp/spring.log" }, "offset" : 1936 }, "logger" : "org.littlewings.spring.example.App", "logmessage" : "hello, info logging", "pid" : "5683", "thread" : "http-nio-8080-exec-1", "input" : { "type" : "log" }, "@timestamp" : "2019-12-10T07:13:56.284Z", "ecs" : { "version" : "1.1.0" }, "loglevel" : "INFO", "host" : { "hostname" : "ubuntu1804.localdomain", "os" : { "kernel" : "4.15.0-70-generic", "codename" : "bionic", "name" : "Ubuntu", "family" : "debian", "version" : "18.04.3 LTS (Bionic Beaver)", "platform" : "ubuntu" }, "containerized" : false, "name" : "ubuntu1804.localdomain", "id" : "2a99d47c230b452d94e8b87696475971", "architecture" : "x86_64" } }, "sort" : [ 1936 ] } ] } }
OKそうです。
これで、Filbeatでのログ取り込み時に、Ingest Nodeのパイプラインを合わせて使うことができました。