You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Log4j2配置将Elasticsearch多行堆栈日志转为单行?

问题

需要将Elasticsearch日志推送至rsyslog,再转发到Fluentd,要求错误堆栈日志为单行格式。此前日志为多行形式(示例如下):

443 [2022-08-05T07:45:38,068][ERROR][o.e.i.g.GeoIpDownloader  ] [techsrv01] exception during geoip databases update
   444  org.elasticsearch.ElasticsearchException: not all primary shards of [.geoip_databases] index are active
   445      at org.elasticsearch.ingest.geoip.GeoIpDownloader.updateDatabases(GeoIpDownloader.java:137) ~[ingest-geoip-7.17.5.jar:7.17.5]
   446      at org.elasticsearch.ingest.geoip.GeoIpDownloader.runDownloader(GeoIpDownloader.java:284) [ingest-geoip-7.17.5.jar:7.17.5]
   447      at org.elasticsearch.ingest.geoip.GeoIpDownloaderTaskExecutor.nodeOperation(GeoIpDownloaderTaskExecutor.java:100) [ingest-geoip-7.17.5.jar:7.17.5]
   448      at org.elasticsearch.ingest.geoip.GeoIpDownloaderTaskExecutor.nodeOperation(GeoIpDownloaderTaskExecutor.java:46) [ingest-geoip-7.17.5.jar:7.17.5]
   449      at org.elasticsearch.persistent.NodePersistentTasksExecutor$1.doRun(NodePersistentTasksExecutor.java:42) [elasticsearch-7.17.5.jar:7.17.5]
   450      at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:777) [elasticsearch-7.17.5.jar:7.17.5]
   451      at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:26) [elasticsearch-7.17.5.jar:7.17.5]
   452      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
   453      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
   454      at java.lang.Thread.run(Thread.java:833) [?:?]

修改log4j2.properties中的pattern layout为以下格式后,日志变为两行,无法合并为单行:

appender.rolling_old.layout.pattern =
[%d{ISO8601}][%-5p][%-25c{1.}][%node_name] %marker %m %n
%throwable{separator(|)}

修改后的日志示例:

2028     [2022-08-05T11:04:40,810][ERROR][o.e.i.g.GeoIpDownloader  ][techsrv01]  exception during geoip databases update
      2029   ElasticsearchException[not all primary shards of [.geoip_databases] index are active]| at org.elasticsearch.ingest.geoip.GeoIpDownloader.updateDatabases(GeoIpDownloader.java:137)|    at org.elasticsearch.ingest.geoip.GeoIpDownloader.runDownloader(GeoIpDownloader.java:284)|  at org.elasticsearch.ingest.geoip.GeoIpDownloaderTaskExecutor.nodeOperation(GeoIpDownloaderTaskExecutor.java:100)|  at org.elasticsearch.ingest.geoip.GeoIpDownloaderTaskExecutor.nodeOperation(GeoIpDownloaderTaskExecutor.java:46)|   at org.elasticsearch.persistent.NodePersistentTasksExecutor$1.doRun(NodePersistentTasksExecutor.java:42)|   at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:777)|  at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:26)| at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)|   at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)|   at java.base/java.lang.Thread.run(Thread.java:833)[2022-08-05T11:04:41,171][INFO ][o.e.c.r.a.AllocationService][techsrv01]  Cluster health status changed from [RED] to [GREEN] (reason: [shards started [[.ds-ilm-history-5-2022.07.18-000001][0], [.kibana-event-log-7.17.5-000001][0], [.geoip_databases][0], [.ds-.logs-deprecation.elasticsearch-default-2022.07.18-000001][0]]]).
解决方案

问题出在当前pattern里的%n会在日志消息末尾插入换行符,导致堆栈信息被分到下一行。要实现单行日志,需要调整pattern的结构:

修改后的log4j2 pattern配置如下:

appender.rolling_old.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}][%node_name] %marker %m%throwable{separator(|)}%n

配置说明:

  • 移除原配置中%m后的%n,避免日志消息和堆栈信息之间出现换行
  • 将%throwable{separator(|)}直接紧跟在%m之后,让堆栈信息直接拼接在日志消息末尾
  • 只保留最后一个%n,用于分隔不同的日志条目,确保每条完整日志结束后换行,不会和下一条日志粘连

这样配置后,包含堆栈的错误日志会完全变为单行,满足rsyslog和Fluentd的处理要求。

内容的提问来源于stack exchange,提问作者Gautam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 10:06:45