Skip to content

Commit 3931547

Browse files
committed
add systemd input and lua filter support
Signed-off-by: wanjunlei <[email protected]>
1 parent f90947c commit 3931547

25 files changed

+579
-2
lines changed

api/v1alpha2/filter_types.go

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ type FilterItem struct {
5252
Nest *filter.Nest `json:"nest,omitempty"`
5353
// Parser defines Parser Filter configuration.
5454
Parser *filter.Parser `json:"parser,omitempty"`
55+
// Lua defines Lua Filter configuration.
56+
Lua *filter.Lua `json:"lua,omitempty"`
5557
}
5658

5759
// +kubebuilder:object:root=true

api/v1alpha2/fluentbitconfig_types.go

+18
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,21 @@ func (cfg FluentBitConfig) RenderParserConfig(sl plugins.SecretLoader, parsers P
167167

168168
return buf.String(), nil
169169
}
170+
171+
func (cfg FluentBitConfig) RenderLuaScript(cl plugins.ConfigMapLoader, filters FilterList) (map[string]string, error) {
172+
173+
scripts := make(map[string]string)
174+
for _, f := range filters.Items {
175+
for _, p := range f.Spec.FilterItems {
176+
if p.Lua != nil {
177+
script, err := cl.LoadConfigMap(p.Lua.Script)
178+
if err != nil {
179+
return nil, err
180+
}
181+
scripts[p.Lua.Script.Key] = script
182+
}
183+
}
184+
}
185+
186+
return scripts, nil
187+
}

api/v1alpha2/input_types.go

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ type InputSpec struct {
3333
Dummy *input.Dummy `json:"dummy,omitempty"`
3434
// Tail defines Tail Input configuration.
3535
Tail *input.Tail `json:"tail,omitempty"`
36+
// Systemd defines Systemd Input configuration.
37+
Systemd *input.Systemd `json:"systemd,omitempty"`
3638
}
3739

3840
// +kubebuilder:object:root=true
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package plugins
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/go-openapi/errors"
7+
"k8s.io/api/core/v1"
8+
"sigs.k8s.io/controller-runtime/pkg/client"
9+
"strings"
10+
)
11+
12+
type ConfigMapLoader struct {
13+
client client.Client
14+
namespace string
15+
}
16+
17+
func NewConfigMapLoader(c client.Client, ns string) ConfigMapLoader {
18+
return ConfigMapLoader{
19+
client: c,
20+
namespace: ns,
21+
}
22+
}
23+
24+
func (cl ConfigMapLoader) LoadConfigMap(selector v1.ConfigMapKeySelector) (string, error) {
25+
var configMap v1.ConfigMap
26+
if err := cl.client.Get(context.Background(), client.ObjectKey{Name: selector.Name, Namespace: cl.namespace}, &configMap); err != nil {
27+
return "", err
28+
}
29+
30+
if v, ok := configMap.Data[selector.Key]; !ok {
31+
return "", errors.NotFound(fmt.Sprintf("The key %s is not found.", selector.Key))
32+
} else {
33+
return strings.TrimSuffix(fmt.Sprintf("%s", v), "\n"), nil
34+
}
35+
}
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package filter
2+
3+
import (
4+
v1 "k8s.io/api/core/v1"
5+
"kubesphere.io/fluentbit-operator/api/v1alpha2/plugins"
6+
"kubesphere.io/fluentbit-operator/pkg/utils"
7+
"strconv"
8+
)
9+
10+
// +kubebuilder:object:generate:=true
11+
12+
// The Lua Filter allows you to modify the incoming records using custom Lua Scripts.
13+
type Lua struct {
14+
15+
// Path to the Lua script that will be used.
16+
Script v1.ConfigMapKeySelector `json:"script"`
17+
// Lua function name that will be triggered to do filtering.
18+
// It's assumed that the function is declared inside the Script defined above.
19+
Call string `json:"call"`
20+
// If these keys are matched, the fields are converted to integer.
21+
// If more than one key, delimit by space.
22+
// Note that starting from Fluent Bit v1.6 integer data types are preserved
23+
// and not converted to double as in previous versions.
24+
TypeIntKey []string `json:"typeIntKey,omitempty"`
25+
// If enabled, Lua script will be executed in protected mode.
26+
// It prevents to crash when invalid Lua script is executed. Default is true.
27+
ProtectedMode *bool `json:"protectedMode,omitempty"`
28+
// By default when the Lua script is invoked, the record timestamp is passed as a
29+
// Floating number which might lead to loss precision when the data is converted back.
30+
// If you desire timestamp precision enabling this option will pass the timestamp as
31+
// a Lua table with keys sec for seconds since epoch and nsec for nanoseconds.
32+
TimeAsTable bool `json:"timeAsTable,omitempty"`
33+
}
34+
35+
func (l *Lua) Name() string {
36+
return "lua"
37+
}
38+
39+
func (l *Lua) Params(_ plugins.SecretLoader) (*plugins.KVs, error) {
40+
kvs := plugins.NewKVs()
41+
42+
kvs.Insert("script", "/fluent-bit/config/"+l.Script.Key)
43+
kvs.Insert("call", l.Call)
44+
45+
if l.TypeIntKey != nil && len(l.TypeIntKey) > 0 {
46+
kvs.Insert("type_int_key", utils.ConcatString(l.TypeIntKey, " "))
47+
}
48+
49+
if l.ProtectedMode != nil {
50+
kvs.Insert("protected_mode", strconv.FormatBool(*l.ProtectedMode))
51+
}
52+
53+
if l.TimeAsTable {
54+
kvs.Insert("time_as_table", "true")
55+
}
56+
return kvs, nil
57+
}

api/v1alpha2/plugins/filter/zz_generated.deepcopy.go

+26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package input
2+
3+
import (
4+
"kubesphere.io/fluentbit-operator/api/v1alpha2/plugins"
5+
)
6+
7+
// +kubebuilder:object:generate:=true
8+
9+
// The Systemd input plugin allows to collect log messages from the Journald daemon on Linux environments.
10+
type Systemd struct {
11+
// Optional path to the Systemd journal directory,
12+
// if not set, the plugin will use default paths to read local-only logs.
13+
Path string `json:"path,omitempty"`
14+
// Specify the database file to keep track of monitored files and offsets.
15+
DB string `json:"db,omitempty"`
16+
// Set a default synchronization (I/O) method. values: Extra, Full, Normal, Off.
17+
// This flag affects how the internal SQLite engine do synchronization to disk,
18+
// for more details about each option please refer to this section.
19+
// note: this option was introduced on Fluent Bit v1.4.6.
20+
// +kubebuilder:validation:Enum:=Extra;Full;Normal;Off
21+
DBSync string `json:"dbSync,omitempty"`
22+
// The tag is used to route messages but on Systemd plugin there is an extra functionality:
23+
// if the tag includes a star/wildcard, it will be expanded with the Systemd Unit file (e.g: host.* => host.UNIT_NAME).
24+
Tag string `json:"tag,omitempty"`
25+
// Set a maximum number of fields (keys) allowed per record.
26+
MaxFields int `json:"maxFields,omitempty"`
27+
// When Fluent Bit starts, the Journal might have a high number of logs in the queue.
28+
// In order to avoid delays and reduce memory usage, this option allows to specify the maximum number of log entries that can be processed per round.
29+
// Once the limit is reached, Fluent Bit will continue processing the remaining log entries once Journald performs the notification.
30+
MaxEntries int `json:"maxEntries,omitempty"`
31+
// Allows to perform a query over logs that contains a specific Journald key/value pairs, e.g: _SYSTEMD_UNIT=UNIT.
32+
// The Systemd_Filter option can be specified multiple times in the input section to apply multiple filters as required.
33+
SystemdFilter []string `json:"systemdFilter,omitempty"`
34+
// Define the filter type when Systemd_Filter is specified multiple times. Allowed values are And and Or.
35+
// With And a record is matched only when all of the Systemd_Filter have a match.
36+
// With Or a record is matched when any of the Systemd_Filter has a match.
37+
// +kubebuilder:validation:Enum:=And;Or
38+
SystemdFilterType string `json:"systemdFilterType,omitempty"`
39+
// Start reading new entries. Skip entries already stored in Journald.
40+
// +kubebuilder:validation:Enum:=on;off
41+
ReadFromTail string `json:"readFromTail,omitempty"`
42+
// Remove the leading underscore of the Journald field (key). For example the Journald field _PID becomes the key PID.
43+
// +kubebuilder:validation:Enum:=on;off
44+
StripUnderscores string `json:"stripUnderscores,omitempty"`
45+
}
46+
47+
func (_ *Systemd) Name() string {
48+
return "systemd"
49+
}
50+
51+
func (s *Systemd) Params(_ plugins.SecretLoader) (*plugins.KVs, error) {
52+
kvs := plugins.NewKVs()
53+
54+
if s.Path != "" {
55+
kvs.Insert("Path", s.Path)
56+
}
57+
if s.DB != "" {
58+
kvs.Insert("DB", s.DB)
59+
}
60+
if s.DBSync != "" {
61+
kvs.Insert("DB.Sync", s.DBSync)
62+
}
63+
if s.Tag != "" {
64+
kvs.Insert("Tag", s.Tag)
65+
}
66+
if s.MaxFields > 0 {
67+
kvs.Insert("Max_Fields", string(rune(s.MaxFields)))
68+
}
69+
if s.MaxEntries > 0 {
70+
kvs.Insert("Max_Entries", string(rune(s.MaxEntries)))
71+
}
72+
if s.SystemdFilter != nil && len(s.SystemdFilter) > 0 {
73+
for _, v := range s.SystemdFilter {
74+
kvs.Insert("Systemd_Filter", v)
75+
}
76+
}
77+
if s.SystemdFilterType != "" {
78+
kvs.Insert("Systemd_Filter_Type", s.SystemdFilterType)
79+
}
80+
if s.ReadFromTail != "" {
81+
kvs.Insert("Read_From_Tail", s.ReadFromTail)
82+
}
83+
if s.StripUnderscores != "" {
84+
kvs.Insert("Strip_Underscores", s.StripUnderscores)
85+
}
86+
87+
return kvs, nil
88+
}

api/v1alpha2/plugins/input/zz_generated.deepcopy.go

+20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha2/zz_generated.deepcopy.go

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/logging.kubesphere.io_filters.yaml

+50
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,56 @@ spec:
147147
Journald format.
148148
type: boolean
149149
type: object
150+
lua:
151+
description: Lua defines Lua Filter configuration.
152+
properties:
153+
call:
154+
description: Lua function name that will be triggered to do
155+
filtering. It's assumed that the function is declared inside
156+
the Script defined above.
157+
type: string
158+
protectedMode:
159+
description: If enabled, Lua script will be executed in protected
160+
mode. It prevents to crash when invalid Lua script is executed.
161+
Default is true.
162+
type: boolean
163+
script:
164+
description: Path to the Lua script that will be used.
165+
properties:
166+
key:
167+
description: The key to select.
168+
type: string
169+
name:
170+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
171+
TODO: Add other useful fields. apiVersion, kind, uid?'
172+
type: string
173+
optional:
174+
description: Specify whether the ConfigMap or its key
175+
must be defined
176+
type: boolean
177+
required:
178+
- key
179+
type: object
180+
timeAsTable:
181+
description: By default when the Lua script is invoked, the
182+
record timestamp is passed as a Floating number which might
183+
lead to loss precision when the data is converted back.
184+
If you desire timestamp precision enabling this option will
185+
pass the timestamp as a Lua table with keys sec for seconds
186+
since epoch and nsec for nanoseconds.
187+
type: boolean
188+
typeIntKey:
189+
description: If these keys are matched, the fields are converted
190+
to integer. If more than one key, delimit by space. Note
191+
that starting from Fluent Bit v1.6 integer data types are
192+
preserved and not converted to double as in previous versions.
193+
items:
194+
type: string
195+
type: array
196+
required:
197+
- call
198+
- script
199+
type: object
150200
modify:
151201
description: Modify defines Modify Filter configuration.
152202
properties:

0 commit comments

Comments
 (0)