加载中

故障排查 Logstash

本页面旨在帮助您对 Logstash 进行故障排查。

某些版本的 JRuby 运行时和某些插件中的库(例如 TCP 输入中的 Netty 网络库)会将可执行文件复制到临时目录。当 /tmp 被挂载为 noexec 时,这种情况会导致后续失败。

示例错误

[2018-03-25T12:23:01,149][ERROR][org.logstash.Logstash ]
java.lang.IllegalStateException: org.jruby.exceptions.RaiseException:
(LoadError) Could not load FFI Provider: (NotImplementedError) FFI not
available: java.lang.UnsatisfiedLinkError: /tmp/jffi5534463206038012403.so:
/tmp/jffi5534463206038012403.so: failed to map segment from shared object:
Operation not permitted
		

可能的解决方案

  • 更改设置,将 /tmp 挂载为 exec
  • jvm.options 文件中使用 -Djava.io.tmpdir 设置指定一个替代目录。

升级后,Logstash 可能会显示类似于以下的警告

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.jruby.ext.openssl.SecurityHelper (file:/{...}/jruby{...}jopenssl.jar) to field java.security.MessageDigest.provider
WARNING: Please consider reporting this to the maintainers of org.jruby.ext.openssl.SecurityHelper
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
		

这些错误似乎与 JRuby 的一个已知问题有关。

变通方法

尝试将这些值添加到 jvm.options 文件中。

--add-opens=java.base/java.security=ALL-UNNAMED
--add-opens=java.base/java.io=ALL-UNNAMED
--add-opens=java.base/java.nio.channels=ALL-UNNAMED
--add-opens=java.base/sun.nio.ch=org.ALL-UNNAMED
--add-opens=java.management/sun.management=ALL-UNNAMED
		

注意

  • 这些设置允许 Logstash 在启动时不显示警告。
  • 此变通方法已在简单的管道中进行了测试。如果您有经验想要分享,请在 issue 中发表评论。

在 Windows 上,使用某些用户提供的 JDK 版本时,Logstash 可能无法启动。

示例错误

[FATAL] 2022-04-27 15:13:16.650 [main] Logstash - Logstash stopped processing because of an error: (EACCES) Permission denied - NUL
org.jruby.exceptions.SystemCallError: (EACCES) Permission denied - NUL
		

此错误似乎与一个 JDK 问题有关,该问题涉及添加了一个具有不当默认值的新属性。

此问题影响 Windows 上的某些 OpenJDK 衍生 JVM 版本(Adoptium、OpenJDK 和 Azul Zulu)

  • 11.0.15+10
  • 17.0.3+7

变通方法

  • 使用 Logstash 自带的 捆绑 JDK

  • 或者,尝试将此值添加到 jvm.options 文件中,并重启 Logstash

    -Djdk.io.File.enableADS=true
    		

在容器中运行的 Logstash 可能会因为 JDK 中的一个 Bug 而无法启动。

示例错误

[FATAL] 2024-11-11 11:11:11.465 [LogStash::Runner] runner - An unexpected error occurred! {:error=>#<Java::JavaLang::NullPointerException: >, :backtrace=>[
        "java.util.Objects.requireNonNull(java/util/Objects.java:233)",
        "sun.nio.fs.UnixFileSystem.getPath(sun/nio/fs/UnixFileSystem.java:296)",
        "java.nio.file.Path.of(java/nio/file/Path.java:148)",
        "java.nio.file.Paths.get(java/nio/file/Paths.java:69)",
        "jdk.internal.platform.CgroupUtil.lambda$readStringValue$1(jdk/internal/platform/CgroupUtil.java:67)",
        "java.security.AccessController.doPrivileged(java/security/AccessController.java:571)",
        "jdk.internal.platform.CgroupUtil.readStringValue(jdk/internal/platform/CgroupUtil.java:69)",
        "jdk.internal.platform.CgroupSubsystemController.getStringValue(jdk/internal/platform/CgroupSubsystemController.java:65)",
        "jdk.internal.platform.cgroupv1.CgroupV1Subsystem.getCpuSetCpus(jdk/internal/platform/cgroupv1/CgroupV1Subsystem.java:275)",
        "jdk.internal.platform.CgroupMetrics.getCpuSetCpus(jdk/internal/platform/CgroupMetrics.java:100)",
        "com.sun.management.internal.OperatingSystemImpl.isCpuSetSameAsHostCpuSet(com/sun/management/internal/OperatingSystemImpl.java:277)",
        "com.sun.management.internal.OperatingSystemImpl$ContainerCpuTicks.getContainerCpuLoad(com/sun/management/internal/OperatingSystemImpl.java:96)",
        "com.sun.management.internal.OperatingSystemImpl.getProcessCpuLoad(com/sun/management/internal/OperatingSystemImpl.java:271)",
        "org.logstash.instrument.monitors.ProcessMonitor$Report.<init>(org/logstash/instrument/monitors/ProcessMonitor.java:63)",
        "org.logstash.instrument.monitors.ProcessMonitor.detect(org/logstash/instrument/monitors/ProcessMonitor.java:136)",
        "org.logstash.instrument.reports.ProcessReport.generate(org/logstash/instrument/reports/ProcessReport.java:35)",
        "jdk.internal.reflect.DirectMethodHandleAccessor.invoke(jdk/internal/reflect/DirectMethodHandleAccessor.java:103)",
        "java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:580)",
        "org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(org/jruby/javasupport/JavaMethod.java:300)",
        "org.jruby.javasupport.JavaMethod.invokeStaticDirect(org/jruby/javasupport/JavaMethod.java:222)",
        "RUBY.collect_process_metrics(/usr/share/logstash/logstash-core/lib/logstash/instrument/periodic_poller/jvm.rb:102)",
        "RUBY.collect(/usr/share/logstash/logstash-core/lib/logstash/instrument/periodic_poller/jvm.rb:73)",
        "RUBY.start(/usr/share/logstash/logstash-core/lib/logstash/instrument/periodic_poller/base.rb:72)",
        "org.jruby.RubySymbol$SymbolProcBody.yieldSpecific(org/jruby/RubySymbol.java:1541)",
        "org.jruby.RubySymbol$SymbolProcBody.doYield(org/jruby/RubySymbol.java:1534)",
        "org.jruby.RubyArray.collectArray(org/jruby/RubyArray.java:2770)",
        "org.jruby.RubyArray.map(org/jruby/RubyArray.java:2803)",
        "org.jruby.RubyArray$INVOKER$i$0$0$map.call(org/jruby/RubyArray$INVOKER$i$0$0$map.gen)",
        "RUBY.start(/usr/share/logstash/logstash-core/lib/logstash/instrument/periodic_pollers.rb:41)",
        "RUBY.configure_metrics_collectors(/usr/share/logstash/logstash-core/lib/logstash/agent.rb:477)",
        "RUBY.initialize(/usr/share/logstash/logstash-core/lib/logstash/agent.rb:88)",
        "org.jruby.RubyClass.new(org/jruby/RubyClass.java:949)",
        "org.jruby.RubyClass$INVOKER$i$newInstance.call(org/jruby/RubyClass$INVOKER$i$newInstance.gen)",
        "RUBY.create_agent(/usr/share/logstash/logstash-core/lib/logstash/runner.rb:552)",
        "RUBY.execute(/usr/share/logstash/logstash-core/lib/logstash/runner.rb:434)",
        "RUBY.run(/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/clamp-1.0.1/lib/clamp/command.rb:68)",
        "RUBY.run(/usr/share/logstash/logstash-core/lib/logstash/runner.rb:293)",
        "RUBY.run(/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/clamp-1.0.1/lib/clamp/command.rb:133)",
        "usr.share.logstash.lib.bootstrap.environment.<main>(/usr/share/logstash/lib/bootstrap/environment.rb:89)",
        "usr.share.logstash.lib.bootstrap.environment.run(usr/share/logstash/lib/bootstrap//usr/share/logstash/lib/bootstrap/environment.rb)",
        "java.lang.invoke.MethodHandle.invokeWithArguments(java/lang/invoke/MethodHandle.java:733)",
        "org.jruby.Ruby.runScript(org/jruby/Ruby.java:1245)",
        "org.jruby.Ruby.runNormally(org/jruby/Ruby.java:1157)",
        "org.jruby.Ruby.runFromMain(org/jruby/Ruby.java:983)",
        "org.logstash.Logstash.run(org/logstash/Logstash.java:163)",
        "org.logstash.Logstash.main(org/logstash/Logstash.java:73)"
    ]
}
[FATAL] 2024-11-11 11:11:11.516 [LogStash::Runner] Logstash - Logstash stopped processing because of an error: (SystemExit) exit
    org.jruby.exceptions.SystemExit: (SystemExit) exit
    at org.jruby.RubyKernel.exit(org/jruby/RubyKernel.java: 921) ~[jruby.jar:?]
    at org.jruby.RubyKernel.exit(org/jruby/RubyKernel.java: 880) ~[jruby.jar:?]
    at usr.share.logstash.lib.bootstrap.environment.<main>(/usr/share/logstash/lib/bootstrap/environment.rb: 90) ~[?:?]
		

当未启用 cgroups v2 时,可能会发生此错误,例如在 Red Hat 8 版本操作系统上运行时。

变通方法

按照您的操作系统说明启用 cgroups v2。

持久化队列问题的症状包括 Logstash 或一个或多个管道无法成功启动,并伴有类似此错误消息的内容。

message=>"java.io.IOException: Page file size is too small to hold elements"
		

有关修复持久化队列问题的更多信息,请参阅持久化队列部分中的 故障排查信息

429 消息表示应用程序正忙于处理其他请求。例如,Elasticsearch 发送 429 代码以通知 Logstash(或其他索引器)批量写入失败,因为摄取队列已满。Logstash 将重试发送文档。

可能的操作

检查 Elasticsearch 是否需要关注。

示例错误

[2018-08-21T20:05:36,111][INFO ][logstash.outputs.elasticsearch] retrying
failed action with response code: 429
({"type"=>"es_rejected_execution_exception", "reason"=>"rejected execution of
org.elasticsearch.transport.TransportService$7@85be457 on
EsThreadPoolExecutor[bulk, queue capacity = 200,
org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@538c9d8a[Running,
pool size = 16, active threads = 16, queued tasks = 200, completed tasks =
685]]"})
		

有关一般性能调优的提示和指南,请参阅 性能调优

管道在定义上是唯一的。以下是一些可以帮助您入门的指南。

  • 识别有问题的管道。
  • 从小处着手。创建一个能复现该问题的最小化管道。

对于基本管道,此配置可能足以使问题显现出来。

input {stdin{}} output {stdout{}}
		

Logstash 可以按管道分离日志。此功能可以帮助您识别有问题的管道。在您的 logstash.yml 中设置 pipeline.separate_logs: true 以启用每个管道的日志功能。

对于更复杂的管道,问题可能是由按特定顺序排列的一系列插件引起的。故障排查这些管道通常需要反复试验。从系统地移除输入和输出插件开始,直到只剩下能复现问题的最小集合。

我们希望扩展本节内容以使其更有帮助。如果您有想要分享的故障排查技巧

症状

简单的过滤器(如 mutatejson 过滤器)执行每个事件可能需要几毫秒。输入和输出也可能受到影响。

背景

如果将日志级别设置为 debugtrace,在 Logstash 上运行的不同插件可能会输出非常多的日志。由于 Logstash 中使用的日志库是同步的,大量的日志记录会影响性能。

解决方案

将日志级别重置为 info

症状

当日志格式为 json 且某些日志事件(例如来自 JSON 编解码器插件的错误)包含两个 message 字段实例时。

如果不设置此标志,json 日志将包含类似以下的对象

{
   "level":"WARN",
   "loggerName":"logstash.codecs.jsonlines",
   "timeMillis":1712937761955,
   "thread":"[main]<stdin",
   "logEvent":{
      "message":"JSON parse error, original data now in message field",
      "message":"Unexpected close marker '}': expected ']' (for Array starting at [Source: (String)\"{\"name\": [}\"; line: 1, column: 10])\n at [Source: (String)\"{\"name\": [}\"; line: 1, column: 12]",
      "exception":"LogStash::Json::ParserError",
      "data":"{\"name\": [}"
   }
}
		

请注意 message 字段的重复,虽然在技术上是有效的 json,但它并不总是能被正确解析。

解决方案config/logstash.yml 中启用 strict json 标志

log.format.json.fix_duplicate_message_fields: true
		

或传递命令行开关

bin/logstash --log.format.json.fix_duplicate_message_fields true
		

启用 log.format.json.fix_duplicate_message_fields 后,message 字段的重复将被消除,并在字段名称后添加 _1 后缀

{
   "level":"WARN",
   "loggerName":"logstash.codecs.jsonlines",
   "timeMillis":1712937629789,
   "thread":"[main]<stdin",
   "logEvent":{
      "message":"JSON parse error, original data now in message field",
      "message_1":"Unexpected close marker '}': expected ']' (for Array starting at [Source: (String)\"{\"name\": [}\"; line: 1, column: 10])\n at [Source: (String)\"{\"name\": [}\"; line: 1, column: 12]",
      "exception":"LogStash::Json::ParserError",
      "data":"{\"name\": [}"
   }
}
		
© . This website operates independently and is not affiliated with or endorsed by Elasticsearch B.V. All brand names, logos, and trademarks are the property of their respective owners.