#ingress nginx kubernetes + custom logs

1 messages · Page 1 of 1 (latest)

warm bobcat
#

The logs are being parsed, but no further events occur.
Nginx has custom logs, but I created a parser.

Could you please advise me on how to resolve this issue?

torpid shadowBOT
#
Important Information

This post has been marked as resolved. If this is a mistake please press the red button below or type /unresolve

warm bobcat
#

I have followed the troubleshooting steps, but unfortunately the issue still persists.

worn ore
warm bobcat
worn ore
warm bobcat
#

but if I check the raw log from Docker, the transition to other parsers does not happen. Could that be the issue?

#

scenarios

worn ore
#

Also your parser needs to use evt.Parsed.message instead of evt.Line.Raw as the raw line include the containerd prefixes

warm bobcat
#

cri log - cscli explain ... --type containerd --labels "program:nginx"
nginx log - cscli explain ... --type nginx

#

kubectl -n crowdsec logs pods/crowdsec-agent-q4txc --tail 10
Defaulted container "crowdsec-agent" out of: crowdsec-agent, wait-for-lapi-and-register (init)
time="2025-09-02T09:36:07Z" level=error msg="JsonExtractObject: key proxy does not exist"
time="2025-09-02T09:36:07Z" level=error msg="JsonExtractObject: key upstream does not exist"
time="2025-09-02T09:36:07Z" level=error msg="JsonExtractObject: key http does not exist"
time="2025-09-02T09:36:07Z" level=error msg="JsonExtractObject: key http does not exist"
time="2025-09-02T09:36:07Z" level=error msg="JsonExtractObject: key proxy does not exist"
time="2025-09-02T09:36:07Z" level=error msg="JsonExtractObject: key upstream does not exist"

#

create evt.Parsed.http_referer : [32mhttps://new.site.online/ship <-- from "http": {"referer": "https://new.site.online/ships/celestyal-discovery","user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36","accept_encoding": "gzip, deflate, br, zstd"}

((((((

worn ore
#

let me cook up a parser using UnmarshalJSON

#

its faster, and more runtime efficient

worn ore
#

Hey @warm bobcat

what is the intention from these groks?

nodes:
    - grok:
         pattern: '%{GREEDYDATA}(?<endpoint>Error obtaining Endpoints for Service)%{GREEDYDATA}'
        expression: evt.Line.Raw
    - filter: evt.Parsed.endpoint != nil
       onsuccess: next_stage
       statics:
         - meta: log_type
            value: dev-null-endpoint
warm bobcat
#

this is an attempt to not process logs containing the string Error obtaining Endpoints for Service

worn ore
warm bobcat
#

this line appeared out of desperation and attempts to fix log parsing (

worn ore
#
filter: "evt.Parsed.program startsWith 'nginx' && UnmarshalJSON(evt.Parsed.message, evt.Unmarshaled, 'nginx') in [nil, '']"
name: crowdsecurity/custom-nginx-logs
description: "Parse nginx access logs in JSON format"
onsuccess: next_stage
statics:
  - target: evt.StrTime
    expression: evt.Unmarshaled.nginx["@timestamp"]
  - parsed: status
    expression: int(evt.Unmarshaled.nginx.status)
  - parsed: body_bytes_sent
    expression: evt.Unmarshaled.nginx["body_bytes_sent"]
  - parsed: request_length
    expression: evt.Unmarshaled.nginx["request_length"]
  - parsed: request_time
    expression: evt.Unmarshaled.nginx["request_time"]
  - parsed: request
    expression: evt.Unmarshaled.nginx.request
  - parsed: remote_addr
    expression: evt.Unmarshaled.nginx["remote_addr"]
  - parsed: verb
    expression: evt.Unmarshaled.nginx["request_method"]
  - parsed: time_local
    expression: evt.Unmarshaled.nginx["time_local"]
  - parsed: http_version
    expression: evt.Unmarshaled.nginx["server_protocol"]
  - parsed: target_fqdn
    expression: evt.Unmarshaled.nginx.vhost
  - parsed: http_referer
    expression: evt.Unmarshaled.nginx.http.referer
  - parsed: http_user_agent
    expression: evt.Unmarshaled.nginx.http["user_agent"]
  - parsed: proxy_upstream_name
    expression: evt.Unmarshaled.nginx.proxy["upstream_name"]
  - parsed: proxy_alternative_upstream_name
    expression: evt.Unmarshaled.nginx.upstream.addr
  - parsed: port
    value: "-"
  - parsed: remote_user
    value: "-"
  - meta: source_ip
    expression: "evt.Parsed.remote_addr"
  - meta: http_status
    expression: "evt.Parsed.status"
  - meta: http_path
    expression: "evt.Parsed.request"
  - meta: http_verb
    expression: "evt.Parsed.verb"
  - meta: http_user_agent
    expression: "evt.Parsed.http_user_agent"
  - meta: target_fqdn
    expression: "evt.Parsed.target_fqdn"
  - meta: service
    value: http
  - meta: log_type
    value: http_access-log
#

This works for me and output is

$ cscli explain -f test.log --type containerd --labels "program:nginx"
line: 2025-09-02T08:27:15.486046104Z stdout F {"@timestamp": "2025-09-02T08:27:15+00:00", "_ym_uid": "1755531811525907277" , "request_id": "386ac2fb4058ca99df87c92fca92dfaa", "remote_addr": "45.82.64.192","time_local": "02/Sep/2025:08:27:15 +0000","request": "/discounts?_rsc=1omfx","request_length": 1002,"request_time": 0.020,"request_method": "GET","status": 200,"vhost": "new.site.online","body_bytes_sent": 2034,"namespace": "site-online","ingress_name": "new-site-online","server_protocol": "HTTP/2.0","service": {"name": "ithaca-production","port": "3000"},"proxy": {"protocol_addr": "-","upstream_name": "site-online-ithaca-production-3000","add_x_forwarded_for": "45.82.64.192"},"http": {"referer": "https://new.site.online/ships/celestyal-discovery","user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36","accept_encoding": "gzip, deflate, br, zstd"},"upstream": {"addr": "10.112.189.44:3000","response_length": 2051,"response_time": 0.006,"status": 200,"location": "-","connect_time": 0.001,"response_length_string": "2051","response_time_string": "0.006","status_string": "200","connect_time_string": "0.001"}}
        ├ s00-raw
        |       └ 🟢 crowdsecurity/cri-logs (+10 ~9)
        ├ s01-parse
        |       └ 🟢 crowdsecurity/custom-nginx-logs (+25 ~2)
        ├ s02-enrich
        |       ├ 🟢 crowdsecurity/dateparse-enrich (+2 ~2)
        |       ├ 🟢 crowdsecurity/geoip-enrich (+13)
        |       ├ 🟢 crowdsecurity/http-logs (+8 ~1)
        |       ├ 🟢 crowdsecurity/public-dns-allowlist (unchanged)
        |       └ 🟢 crowdsecurity/whitelists (unchanged)
        ├-------- parser success 🟢
        ├ Scenarios
                └ 🟢 crowdsecurity/http-crawl-non_statics
#

ohh wait I just need to update it

#

updated it, by default all numbers are floats so we have to wrap status in int() call

warm bobcat
#

The parser worked perfectly! Thank you!
What was my mistake? Why didn’t it move on to the next parser?

#

and...
crowdsec-agent-6vn8b:/# cscli decisions list
No active decisions

#

time="2025-09-02T10:56:43Z" level=warning msg="failed to run filter : unexpected end of JSON input (1:42)\n | evt.Parsed.program startsWith 'nginx' && UnmarshalJSON(evt.Parsed.message, evt.Unmarshaled, 'nginx') in [nil, '']\n | .........................................^" id=wandering-snow name=crowdsecurity/custom-nginx-logs stage=s01-parse

warm bobcat
#

Hooray! You’re amazing! We managed to fix it! HUGE THANKS!

We needed to override the variable in the Helm chart container_runtime: containerd.
Unfortunately, I couldn’t find any documentation on this issue.

worn ore
warm bobcat
#

in the agent logs there are errors
is this normal or should it be fixed?

time="2025-09-02T12:54:04Z" level=error msg="UnmarshalJSON : invalid character 'W' looking for beginning of value" line="W0902 12:54:04.346346 7 controller.go:1107] Error obtaining Endpoints for Service "logs/devnull": no object matching key "logs/devnull" in local store"

time="2025-09-02T12:54:04Z" level=warning msg="failed to run filter : invalid character 'W' looking for beginning of value (1:42)\n | evt.Parsed.program startsWith 'nginx' && UnmarshalJSON(evt.Parsed.message, evt.Unmarshaled, 'nginx') == nil\n | .........................................^" id=throbbing-sound name=crowdsecurity/custom-nginx-logs stage=s01-parse

worn ore
# warm bobcat in the agent logs there are errors is this normal or should it be fixed? time="...

Probably you have non json logs being printed?

if so you can add to the filter like

filter: "evt.Parsed.program startsWith 'nginx' && trim(evt.Parsed.message) startsWith '{' && UnmarshalJSON(evt.Parsed.message, evt.Unmarshaled, 'nginx') in [nil, '']"

so in short we check the message starts with { indicating a json log, depending on it also we can check for stdout or stderr from containerd

warm bobcat
#

yes, the agents are monitoring nginx through which many services pass. It turned out that there are non-normalized logs there.

warm bobcat
#

cool! the fix works
once again, huge thanks

torpid shadowBOT