将 PHP monolog 消息的上下文搜索到 ELK

Grokking context of PHP monolog message into ELK

我希望能够在 Kibana 中搜索我在 Monolog 中作为上下文记录的字段。

我的意思是,如果我 $log->info("Request", $visitDetails); 其中 $visitDetails 是一个数组,那么我希望 Logstash 为 Elastic 理解它,以便对数组 key/values 进行索引和搜索。

我的 PHP 看起来像这样:

// "logstash" is a host defined by docker-compose
$handler = new SocketHandler('logstash:9001', Logger::DEBUG);
$log->pushHandler($handler);
$log->pushHandler(new StreamHandler(__DIR__ . '/test.log', Logger::DEBUG));


// log the details of the user visit
$visitDetails = [
    'ip' => $_SERVER['REMOTE_ADDR'],
    'method' => $_SERVER['REQUEST_METHOD'],
    'uri' => $_SERVER['REQUEST_URI'],
    'agent' => $_SERVER['HTTP_USER_AGENT'],
    'referer' => $_SERVER['HTTP_REFERER'] ?? 'not set'
];
$log->info("Request", $visitDetails);

我的 Logstash 配置如下所示:

input {
    tcp {
        port => 9001
    }
}

filter {
    grok {
        match => { "\[%{TIMESTAMP_ISO8601:timestamp}\] %{DATA:env}\.%{DATA:severity}: %{GREEDYDATA:message} \{%{GREEDYDATA:context}\} \[\]" }
    }
}

output {
    stdout {}
}

我正在使用 https://grokdebug.herokuapp.com/ 来帮助计算 grok 模式,现在可以将 "context" 隔离为 JSON 字符串。

如何创建一个过滤器,将其扩展为 Elastic 的 key/value 对?

我认为部分问题是 json 字符串周围的大括号 {} 被拿走了。我正在努力在 grok 中为他们创建一个非捕获组。

我宁愿使用 Grok 的正则表达式功能(由 https://github.com/kkos/oniguruma/blob/master/doc/RE 提供支持)。

这让我可以使用正则表达式,使用这种语法 (?<field_name>the pattern here) 然后我在左括号中使用了一个非捕获组。

这似乎符合我的要求:

filter {
    grok {
        match => { "message" => "\[%{TIMESTAMP_ISO8601:timestamp}\] %{DATA:env}\.%{DATA:severity}: %{GREEDYDATA:message} (?<context>(\{.*?\})) \[\]" }
    }
}

filter {
      json {
        source => "context"
      }
    }