Skip to content

Add FilterGrep in Banzai Logging FluentbitSpec #2012

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 24, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,26 @@ spec:
vpc_id:
type: boolean
type: object
filterGrep:
properties:
Exclude:
items:
type: string
type: array
LogicalOp:
default: legacy
enum:
- legacy
- AND
- OR
type: string
Match:
type: string
Regex:
items:
type: string
type: array
type: object
filterKubernetes:
properties:
Annotations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2132,6 +2132,26 @@ spec:
vpc_id:
type: boolean
type: object
filterGrep:
properties:
Exclude:
items:
type: string
type: array
LogicalOp:
default: legacy
enum:
- legacy
- AND
- OR
type: string
Match:
type: string
Regex:
items:
type: string
type: array
type: object
filterKubernetes:
properties:
Annotations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,26 @@ spec:
vpc_id:
type: boolean
type: object
filterGrep:
properties:
Exclude:
items:
type: string
type: array
LogicalOp:
default: legacy
enum:
- legacy
- AND
- OR
type: string
Match:
type: string
Regex:
items:
type: string
type: array
type: object
filterKubernetes:
properties:
Annotations:
Expand Down
20 changes: 20 additions & 0 deletions charts/logging-operator/crds/logging.banzaicloud.io_loggings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2129,6 +2129,26 @@ spec:
vpc_id:
type: boolean
type: object
filterGrep:
properties:
Exclude:
items:
type: string
type: array
LogicalOp:
default: legacy
enum:
- legacy
- AND
- OR
type: string
Match:
type: string
Regex:
items:
type: string
type: array
type: object
filterKubernetes:
properties:
Annotations:
Expand Down
20 changes: 20 additions & 0 deletions config/crd/bases/logging.banzaicloud.io_fluentbitagents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,26 @@ spec:
vpc_id:
type: boolean
type: object
filterGrep:
properties:
Exclude:
items:
type: string
type: array
LogicalOp:
default: legacy
enum:
- legacy
- AND
- OR
type: string
Match:
type: string
Regex:
items:
type: string
type: array
type: object
filterKubernetes:
properties:
Annotations:
Expand Down
20 changes: 20 additions & 0 deletions config/crd/bases/logging.banzaicloud.io_loggings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2129,6 +2129,26 @@ spec:
vpc_id:
type: boolean
type: object
filterGrep:
properties:
Exclude:
items:
type: string
type: array
LogicalOp:
default: legacy
enum:
- legacy
- AND
- OR
type: string
Match:
type: string
Regex:
items:
type: string
type: array
type: object
filterKubernetes:
properties:
Annotations:
Expand Down
29 changes: 29 additions & 0 deletions docs/configuration/crds/v1beta1/fluentbit_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ DisableVarLibDockerContainers controls whether the /var/lib/docker/containers vo
### filterAws (*FilterAws, optional) {#fluentbitspec-filteraws}


### filterGrep (*FilterGrep, optional) {#fluentbitspec-filtergrep}


### filterKubernetes (FilterKubernetes, optional) {#fluentbitspec-filterkubernetes}

Parameters for Kubernetes metadata filter
Expand Down Expand Up @@ -848,6 +851,32 @@ The VPC ID for current EC2 instance. (default:false)
Default: false


## FilterGrep

FilterGrep The Grep Filter plugin

### Exclude ([]string, optional) {#filtergrep-exclude}

Exclude records where the content of KEY matches the regular expression.


### LogicalOp (string, optional) {#filtergrep-logicalop}

Specify a logical operator: AND, OR or legacy (default). In legacy mode the behavior is either AND or OR depending on whether the grep is including (uses AND) or excluding (uses OR). Available from 2.1 or higher. Default: "legacy"


### Match (string, optional) {#filtergrep-match}

Match filtered records (default:*)

Default: *

### Regex ([]string, optional) {#filtergrep-regex}

Keep records where the content of KEY matches the regular expression.



## FilterModify

FilterModify The Modify Filter plugin allows you to change records using rules and conditions.
Expand Down
18 changes: 18 additions & 0 deletions pkg/resources/fluentbit/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,24 @@ var fluentBitConfigTemplate = `
{{- template "input" .Input }}
{{- end }}

{{- if .FluentdFilterGrep }}
[FILTER]
Name grep
Match {{ .FluentdFilterGrep.Match }}

{{- if .FluentdFilterGrep.LogicalOp }}
Logical_Op {{ .FluentdFilterGrep.LogicalOp }}
{{- end }}

{{- range $value := .FluentdFilterGrep.Regex }}
Regex {{ $value }}
{{- end }}

{{- range $value := .FluentdFilterGrep.Exclude }}
Exclude {{ $value }}
{{- end }}
{{- end}}

{{- if not .DisableKubernetesFilter }}
[FILTER]
Name kubernetes
Expand Down
30 changes: 30 additions & 0 deletions pkg/resources/fluentbit/configsecret.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type fluentBitConfig struct {
DisableKubernetesFilter bool
KubernetesFilter map[string]string
AwsFilter map[string]string
FluentdFilterGrep *FluentdFilterGrep
BufferStorage map[string]string
FilterModify []v1beta1.FilterModify
FluentForwardOutput *fluentForwardOutputConfig
Expand All @@ -85,6 +86,13 @@ type fluentBitConfig struct {
HealthCheck *v1beta1.HealthCheck
}

type FluentdFilterGrep struct {
Match string
Regex []string
Exclude []string
LogicalOp string
}

type fluentForwardOutputConfig struct {
Network FluentbitNetwork
Options map[string]string
Expand Down Expand Up @@ -317,6 +325,13 @@ func (r *Reconciler) configSecret() (runtime.Object, reconciler.DesiredState, er
}
input.Input.Values = fluentbitInputValues

if r.fluentbitSpec.FilterGrep != nil {
input.FluentdFilterGrep, err = toFluentdFilterGrep(r.fluentbitSpec.FilterGrep)
if err != nil {
return nil, reconciler.StatePresent, err
}
}

input.KubernetesFilter, err = mapper.StringsMap(r.fluentbitSpec.FilterKubernetes)
if err != nil {
return nil, reconciler.StatePresent, errors.WrapIf(err, "failed to map kubernetes filter for fluentbit")
Expand Down Expand Up @@ -458,6 +473,21 @@ func (r *Reconciler) configSecret() (runtime.Object, reconciler.DesiredState, er
}, reconciler.StatePresent, nil
}

func toFluentdFilterGrep(filterGrep *v1beta1.FilterGrep) (*FluentdFilterGrep, error) {
if filterGrep.LogicalOp != "legacy" && len(filterGrep.Regex) > 0 && len(filterGrep.Exclude) > 0 {
return nil, errors.New("failed to parse grep filter for fluentbit, LogicalOp is set, it's not possible to set both Regex and Exclude")
}

fluentdFilterGrep := &FluentdFilterGrep{
Match: filterGrep.Match,
Regex: filterGrep.Regex,
Exclude: filterGrep.Exclude,
LogicalOp: filterGrep.LogicalOp,
}

return fluentdFilterGrep, nil
}

func (r *Reconciler) applyNetworkSettings(input fluentBitConfig) {
if r.fluentbitSpec.Network != nil {
if input.FluentForwardOutput != nil {
Expand Down
54 changes: 54 additions & 0 deletions pkg/resources/fluentbit/configsecret_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright © 2025 Kube logging authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fluentbit

import (
"testing"

"github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1"
"github.com/stretchr/testify/assert"
)

func TestInvalidFilterGrepConfig(t *testing.T) {
invalidFilterGrep := &v1beta1.FilterGrep{
Match: "*",
Regex: []string{"regex", "reg2"},
Exclude: []string{"exclude"},
LogicalOp: "AND",
}

_, err := toFluentdFilterGrep(invalidFilterGrep)

assert.EqualError(t, err, "failed to parse grep filter for fluentbit, LogicalOp is set, it's not possible to set both Regex and Exclude")
}

func TestValidFilterGrepConfig(t *testing.T) {
filterGrep := &v1beta1.FilterGrep{
Match: "*",
Regex: []string{"regex1", "regex2"},
LogicalOp: "AND",
}

expectedFluentFilterGrep := &FluentdFilterGrep{
Match: "*",
Regex: []string{"regex1", "regex2"},
LogicalOp: "AND",
}

parserFluentdFilterGrep, err := toFluentdFilterGrep(filterGrep)

assert.NoError(t, err)
assert.EqualValues(t, parserFluentdFilterGrep, expectedFluentFilterGrep)
}
21 changes: 21 additions & 0 deletions pkg/sdk/logging/api/v1beta1/fluentbit_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ type FluentbitSpec struct {
InputTail InputTail `json:"inputTail,omitempty"`
FilterAws *FilterAws `json:"filterAws,omitempty"`
FilterModify []FilterModify `json:"filterModify,omitempty"`
FilterGrep *FilterGrep `json:"filterGrep,omitempty"`
// Deprecated, use inputTail.parser
Parser string `json:"parser,omitempty"`
// Parameters for Kubernetes metadata filter
Expand Down Expand Up @@ -393,6 +394,26 @@ type FilterAws struct {
Match string `json:"Match,omitempty" plugin:"default:*"`
}

// FilterGrep The Grep Filter plugin
type FilterGrep struct {
// Match filtered records (default:*)
Match string `json:"Match,omitempty" plugin:"default:*"`
// Keep records where the content of KEY matches the regular expression.
Regex []string `json:"Regex,omitempty"`
// Exclude records where the content of KEY matches the regular expression.
Exclude []string `json:"Exclude,omitempty"`

// Specify a logical operator:
// AND, OR or legacy (default).
// In legacy mode the behavior is either AND or OR depending on whether the grep is including (uses AND) or excluding (uses OR).
// Available from 2.1 or higher.
// Default: "legacy"
//
// +kubebuilder:validation:Enum=legacy;AND;OR
// +kubebuilder:default=legacy
LogicalOp string `json:"LogicalOp,omitempty"`
}

// FilterModify The Modify Filter plugin allows you to change records using rules and conditions.
type FilterModify struct {
// FluentbitAgent Filter Modification Rule
Expand Down
Loading
Loading