[GH-ISSUE #854] LogstashFormatter and numeric contextPrefix keys #336

Closed
opened 2026-03-04 02:14:13 +03:00 by kerem · 1 comment
Owner

Originally created by @KIVagant on GitHub (Sep 20, 2016).
Original GitHub issue: https://github.com/Seldaek/monolog/issues/854

The LogstashFormatter have a problem in this file:

            foreach ($record['context'] as $key => $val) {
                $message[$this->contextPrefix . $key] = $val;
            }
  1. If Logstash configuration contains manage_template => true in the elasticsearch output section.
  2. And if the $record['context'] has a numeric keys and different types of values.

Than fields with the names 'ctxt_0', 'ctxt_1' etc will be created automatically in the ElasticSearch index.

And if formatter will called twice with a different $context array, for example [0, 1] and ['aaa','bbb'] then Logstash will throw an error:

"error"=>{"type"=>"mapper_parsing_exception", "reason"=>"failed to parse [ctxt_0]", "caused_by"=>{"type"=>"number_format_exception", "reason"=>"For input string: \"aaa\""

Because field was created with a type 'number' at the first time.

I have no idea how to fix that with a correct way. Maybe instead of using numeric keys suffixes the sub-array must be created with the key 'ctxt_something'? For example:

        if (!empty($record['context'])) {
            // this will always be an 'array' or 'object' type in Logstash.
            // Not best ("Objects in arrays not well supported" in Kibana),
            // but better than parsing error.
            $numeric_key = $this->contextPrefix . '_sub';
            $message['@fields'][$numeric_key] = [];
            foreach ($record['context'] as $key => $val) {
                if (is_numeric($key)) {
                    $message['@fields'][$numeric_key][] = $val;
                } else {
                    $message['@fields'][$this->contextPrefix . $key] = $val;
                }
            }
            if (empty($message['@fields'][$numeric_key])) {
                unset($message['@fields'][$numeric_key]);
            }
        }

Up: I have checked, this wasn't help.

So now I have only this working variant:

        if (!empty($record['context'])) {
            foreach ($record['context'] as $key => $val) {
                if (!is_numeric($key)) {
                    $message['@fields'][$this->contextPrefix . $key] = $val;
                }
            }
        }
Originally created by @KIVagant on GitHub (Sep 20, 2016). Original GitHub issue: https://github.com/Seldaek/monolog/issues/854 The LogstashFormatter have a problem [in this file](https://github.com/Seldaek/monolog/blob/master/src/Monolog/Formatter/LogstashFormatter.php#L97): ``` foreach ($record['context'] as $key => $val) { $message[$this->contextPrefix . $key] = $val; } ``` 1. If Logstash configuration contains `manage_template => true` in the elasticsearch output section. 2. And if the `$record['context']` has a numeric keys and different types of values. Than fields with the names 'ctxt_0', 'ctxt_1' etc will be created automatically in the ElasticSearch index. And if formatter will called twice with a different $context array, for example `[0, 1]` and `['aaa','bbb']` then Logstash will throw an error: ``` "error"=>{"type"=>"mapper_parsing_exception", "reason"=>"failed to parse [ctxt_0]", "caused_by"=>{"type"=>"number_format_exception", "reason"=>"For input string: \"aaa\"" ``` Because field was created with a type 'number' at the first time. I have no idea how to fix that with a correct way. Maybe instead of using numeric keys suffixes the sub-array must be created with the key 'ctxt_something'? For example: ``` if (!empty($record['context'])) { // this will always be an 'array' or 'object' type in Logstash. // Not best ("Objects in arrays not well supported" in Kibana), // but better than parsing error. $numeric_key = $this->contextPrefix . '_sub'; $message['@fields'][$numeric_key] = []; foreach ($record['context'] as $key => $val) { if (is_numeric($key)) { $message['@fields'][$numeric_key][] = $val; } else { $message['@fields'][$this->contextPrefix . $key] = $val; } } if (empty($message['@fields'][$numeric_key])) { unset($message['@fields'][$numeric_key]); } } ``` Up: I have checked, this wasn't help. So now I have only this working variant: ``` if (!empty($record['context'])) { foreach ($record['context'] as $key => $val) { if (!is_numeric($key)) { $message['@fields'][$this->contextPrefix . $key] = $val; } } } ```
kerem closed this issue 2026-03-04 02:14:13 +03:00
Author
Owner

@Seldaek commented on GitHub (Sep 25, 2016):

It seems like the issue really is that you sometimes pass numbers and sometimes strings into a given context key..

The best option IMO is to make sure you always name your context, so always pass something like ['count' => 0] or ['foo' => 'bar'], that way you won't twice end up with ctxt_0, but rather ctxt_count (int type) and ctxt_foo (string type)..

In any case, I don't think it's something we can do on monolog's end I'm afraid.

<!-- gh-comment-id:249426881 --> @Seldaek commented on GitHub (Sep 25, 2016): It seems like the issue really is that you sometimes pass numbers and sometimes strings into a given context key.. The best option IMO is to make sure you always name your context, so always pass something like `['count' => 0]` or `['foo' => 'bar']`, that way you won't twice end up with ctxt_0, but rather ctxt_count (int type) and ctxt_foo (string type).. In any case, I don't think it's something we can do on monolog's end I'm afraid.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/monolog#336
No description provided.