首页 > 解决方案 > 意外字符('-'(代码 45)):需要空格分隔根级值

问题描述

我正在使用grok的logstash过滤器并将日志文件导入elasticsearch。我想将我的日志文件分成 4 个部分,分别是时间、日志级别、类(已编辑:对不起,我的错,它是线程,而不是类)和消息。

下面是我使用 lob-back.xml 由 spring-boot 生成的日志文件的几行

2019-09-17 16:25:01,116 INFO  [main]: org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler:initialize:Initializing ExecutorService 'taskScheduler'
2019-09-17 16:25:01,225 INFO  [main]: org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor:initialize:Initializing ExecutorService 'applicationTaskExecutor'

我得到的错误如下:

[2019-09-17T16:25:01,425][ERROR][logstash.codecs.json] JSON parse error, original data now in message field {:error=>#<LogStash::Json::ParserError:
Unexpected character ('-' (code 45)): Expected space separating root-level values
"; line: 1, column: 6]>, :data=>"2019-09-17 16:25:01,043 INFO  [main]: org.springframework.security.web.DefaultSecurityFilterChain:<init>:Creating filter chain: Ant [pattern='/v2/api-docs'], []\r"}

我的logstash配置:

input { 
    file { 
        path => "C:/data/log/*.log" 
        codec => "json" 
        type => "logback" 
    } 
} 

filter {
    grok { 
        match => { 
            "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:log-level} [%{DATA:class}]: %{GREEDYDATA:syslog_message}" 
        } 
    } 
} 

output {
    if [type]=="logback" {
        elasticsearch { 
            hosts => [ "localhost:9200" ] 
            index => "logback-%{+YYYY.MM.dd}" 
        } 
    } 
}

标签: springspring-bootelasticsearchlogstash

解决方案


您必须转义 [] 字符才能将它们视为字符串的一部分,而不是特殊字符

match => {
  "message" => '^%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:log_level}%{SPACE}\[%{DATA:thread}\]: %{GREEDYDATA:syslog_message}$'
}

我已经通过一些改进更新了您的模式:

  • 设置行锚的 start(^) 和 end($)以提高正则表达式的性能,因为失败会更快。更多关于它的信息在这里

  • 您的日志在“日志级别”和“类”之间有 2 个空格(实际上,它是线程,而不是类)。如果它不是永久数量的空格(有时 Spring 将日志变量填充到一定长度),最好使用%{SPACE} 掩码

  • 遵循“日志级别”变量的es 命名约定:

    • 使用蛇形大小写(下划线)组合单词。

推荐阅读