@@ -2,6 +2,7 @@ package k8sutil
22
33import (
44 "embed"
5+ "strings"
56
67 "github.com/marklogic/marklogic-operator-kubernetes/pkg/result"
78 corev1 "k8s.io/api/core/v1"
@@ -156,144 +157,156 @@ func (oc *OperatorContext) getScriptsForConfigMap() map[string]string {
156157func (oc * OperatorContext ) getFluentBitData () map [string ]string {
157158 fluentBitData := make (map [string ]string )
158159
159- fluentBitData [ "fluent-bit.conf" ] = `
160- [SERVICE]
161- Flush 5
162- Log_Level info
163- Daemon off
164- Parsers_File parsers.conf
160+ // Main YAML configuration file
161+ fluentBitData [ "fluent-bit.yaml" ] = `service:
162+ flush: 5
163+ log_level: info
164+ daemon: off
165+ parsers_file: parsers.yaml
165166
166- @INCLUDE inputs.conf
167- @INCLUDE filters.conf
168- @INCLUDE outputs.conf
169- `
170-
171- fluentBitData ["inputs.conf" ] = ""
167+ pipeline:
168+ inputs:`
172169
170+ // Add INPUT sections based on enabled log types
173171 if oc .MarklogicGroup .Spec .LogCollection .Files .ErrorLogs {
174- errorLog := `
175- [INPUT]
176- Name tail
177- Path /var/opt/MarkLogic/Logs/*ErrorLog.txt
178- Read_from_head true
179- Tag kube.marklogic.logs.error
180- Path_Key path
181- Parser error_parser
182- Mem_Buf_Limit 4MB
183- `
184- fluentBitData ["inputs.conf" ] += errorLog
172+ fluentBitData ["fluent-bit.yaml" ] += `
173+ - name: tail
174+ path: /var/opt/MarkLogic/Logs/*ErrorLog.txt
175+ read_from_head: true
176+ tag: kube.marklogic.logs.error
177+ path_key: path
178+ parser: error_parser
179+ mem_buf_limit: 4MB`
185180 }
186181
187182 if oc .MarklogicGroup .Spec .LogCollection .Files .AccessLogs {
188- accessLog := `
189- [INPUT]
190- Name tail
191- Path /var/opt/MarkLogic/Logs/*AccessLog.txt
192- Read_from_head true
193- tag kube.marklogic.logs.access
194- Path_Key path
195- Parser access_parser
196- Mem_Buf_Limit 4MB
197- `
198- fluentBitData ["inputs.conf" ] += accessLog
183+ fluentBitData ["fluent-bit.yaml" ] += `
184+ - name: tail
185+ path: /var/opt/MarkLogic/Logs/*AccessLog.txt
186+ read_from_head: true
187+ tag: kube.marklogic.logs.access
188+ path_key: path
189+ parser: access_parser
190+ mem_buf_limit: 4MB`
199191 }
200192
201193 if oc .MarklogicGroup .Spec .LogCollection .Files .RequestLogs {
202- requestLog := `
203- [INPUT]
204- Name tail
205- Path /var/opt/MarkLogic/Logs/*RequestLog.txt
206- Read_from_head true
207- tag kube.marklogic.logs.request
208- Path_Key path
209- Parser json_parser
210- Mem_Buf_Limit 4MB
211- `
212- fluentBitData ["inputs.conf" ] += requestLog
194+ fluentBitData ["fluent-bit.yaml" ] += `
195+ - name: tail
196+ path: /var/opt/MarkLogic/Logs/*RequestLog.txt
197+ read_from_head: true
198+ tag: kube.marklogic.logs.request
199+ path_key: path
200+ parser: json_parser
201+ mem_buf_limit: 4MB`
213202 }
214203
215204 if oc .MarklogicGroup .Spec .LogCollection .Files .CrashLogs {
216- crashLog := `
217- [INPUT]
218- Name tail
219- Path /var/opt/MarkLogic/Logs/CrashLog.txt
220- Read_from_head true
221- tag kube.marklogic.logs.crash
222- Path_Key path
223- Mem_Buf_Limit 4MB
224- `
225- fluentBitData ["inputs.conf" ] += crashLog
205+ fluentBitData ["fluent-bit.yaml" ] += `
206+ - name: tail
207+ path: /var/opt/MarkLogic/Logs/CrashLog.txt
208+ read_from_head: true
209+ tag: kube.marklogic.logs.crash
210+ path_key: path
211+ mem_buf_limit: 4MB`
226212 }
227213
228214 if oc .MarklogicGroup .Spec .LogCollection .Files .AuditLogs {
229- auditLog := `
230- [INPUT]
231- Name tail
232- Path /var/opt/MarkLogic/Logs/AuditLog.txt
233- Read_from_head true
234- tag kube.marklogic.logs.audit
235- Path_Key path
236- Mem_Buf_Limit 4MB
237- `
238- fluentBitData ["inputs.conf" ] += auditLog
215+ fluentBitData ["fluent-bit.yaml" ] += `
216+ - name: tail
217+ path: /var/opt/MarkLogic/Logs/AuditLog.txt
218+ read_from_head: true
219+ tag: kube.marklogic.logs.audit
220+ path_key: path
221+ mem_buf_limit: 4MB`
222+ }
223+
224+ // Add FILTER sections
225+ fluentBitData ["fluent-bit.yaml" ] += `
226+
227+ filters:
228+ - name: modify
229+ match: "*"
230+ add: pod ${POD_NAME}
231+ add: namespace ${NAMESPACE}
232+ - name: modify
233+ match: kube.marklogic.logs.error
234+ add: tag kube.marklogic.logs.error
235+ - name: modify
236+ match: kube.marklogic.logs.access
237+ add: tag kube.marklogic.logs.access
238+ - name: modify
239+ match: kube.marklogic.logs.request
240+ add: tag kube.marklogic.logs.request
241+ - name: modify
242+ match: kube.marklogic.logs.audit
243+ add: tag kube.marklogic.logs.audit
244+ - name: modify
245+ match: kube.marklogic.logs.crash
246+ add: tag kube.marklogic.logs.crash
247+
248+ outputs:`
249+
250+ // Handle user-defined outputs from LogCollection.Outputs
251+ if oc .MarklogicGroup .Spec .LogCollection .Outputs != "" {
252+ // Process user-defined outputs, adjusting indentation to match pipeline level
253+ outputs := oc .MarklogicGroup .Spec .LogCollection .Outputs
254+ // Split into lines and process indentation
255+ lines := strings .Split (outputs , "\n " )
256+ processedLines := make ([]string , 0 , len (lines ))
257+ for _ , line := range lines {
258+ if strings .TrimSpace (line ) == "" {
259+ continue // Skip empty lines
260+ }
261+ // Count leading spaces in original line
262+ leadingSpaces := len (line ) - len (strings .TrimLeft (line , " " ))
263+ content := strings .TrimLeft (line , " " )
264+ if content != "" {
265+ // For YAML list items starting with "-", use 4 spaces base indentation
266+ // For properties under list items, use 6 spaces base indentation
267+ var newIndent int
268+ const yamlListItemIndent = 4
269+ const yamlPropertyIndent = 6
270+ if strings .HasPrefix (content , "- " ) {
271+ newIndent = yamlListItemIndent // List items at pipeline outputs level
272+ } else {
273+ newIndent = yamlPropertyIndent // Properties under list items
274+ }
275+ // Add any additional relative indentation beyond the first level
276+ const baseIndentOffset = 2
277+ if leadingSpaces > baseIndentOffset {
278+ newIndent += leadingSpaces - baseIndentOffset
279+ }
280+ processedLines = append (processedLines , strings .Repeat (" " , newIndent )+ content )
281+ }
282+ }
283+ fluentBitData ["fluent-bit.yaml" ] += "\n " + strings .Join (processedLines , "\n " )
284+ } else {
285+ // Default stdout output if none specified
286+ fluentBitData ["fluent-bit.yaml" ] += `
287+ - name: stdout
288+ match: "*"
289+ format: json_lines`
239290 }
240291
241- fluentBitData ["outputs.conf" ] = oc .MarklogicGroup .Spec .LogCollection .Outputs
242-
243- fluentBitData ["filters.conf" ] = `
244- [FILTER]
245- Name modify
246- Match *
247- Add pod ${POD_NAME}
248- Add namespace ${NAMESPACE}
249-
250- [FILTER]
251- Name modify
252- Match kube.marklogic.logs.error
253- Add tag kube.marklogic.logs.error
254-
255- [FILTER]
256- Name modify
257- Match kube.marklogic.logs.access
258- Add tag kube.marklogic.logs.access
259-
260- [FILTER]
261- Name modify
262- Match kube.marklogic.logs.request
263- Add tag kube.marklogic.logs.request
264-
265- [FILTER]
266- Name modify
267- Match kube.marklogic.logs.audit
268- Add tag kube.marklogic.logs.audit
269-
270- [FILTER]
271- Name modify
272- Match kube.marklogic.logs.crash
273- Add tag kube.marklogic.logs.crash
274- `
275-
276- fluentBitData ["parsers.conf" ] = `
277- [PARSER]
278- Name error_parser
279- Format regex
280- Regex ^(?<time>(.+?)(?=[a-zA-Z]))(?<log_level>(.+?)(?=:))(.+?)(?=[a-zA-Z])(?<log>.*)
281- Time_Key time
282- Time_Format %Y-%m-%d %H:%M:%S.%L
283-
284- [PARSER]
285- Name access_parser
286- Format regex
287- Regex ^(?<host>[^ ]*)(.+?)(?<=\- )(?<user>(.+?)(?=\[))(.+?)(?<=\[)(?<time>(.+?)(?=\]))(.+?)(?<=")(?<request>[^\ ]+[^\"]+)(.+?)(?=\d)(?<response_code>[^\ ]*)(.+?)(?=\d|-)(?<response_obj_size>[^\ ]*)(.+?)(?=")(?<request_info>.*)
288- Time_Key time
289- Time_Format %d/%b/%Y:%H:%M:%S %z
290-
291- [PARSER]
292- Name json_parser
293- Format json
294- Time_Key time
295- Time_Format %Y-%m-%dT%H:%M:%S%z
296- `
292+ // Parsers in YAML format
293+ fluentBitData ["parsers.yaml" ] = `parsers:
294+ - name: error_parser
295+ format: regex
296+ regex: ^(?<time>(.+?)(?=[a-zA-Z]))(?<log_level>(.+?)(?=:))(.+?)(?=[a-zA-Z])(?<log>.*)
297+ time_key: time
298+ time_format: "%Y-%m-%d %H:%M:%S.%L"
299+
300+ - name: access_parser
301+ format: regex
302+ regex: ^(?<host>[^ ]*)(.+?)(?<=\- )(?<user>(.+?)(?=\[))(.+?)(?<=\[)(?<time>(.+?)(?=\]))(.+?)(?<=")(?<request>[^\ ]+[^\"]+)(.+?)(?=\d)(?<response_code>[^\ ]*)(.+?)(?=\d|-)(?<response_obj_size>[^\ ]*)(.+?)(?=")(?<request_info>.*)
303+ time_key: time
304+ time_format: "%d/%b/%Y:%H:%M:%S %z"
305+
306+ - name: json_parser
307+ format: json
308+ time_key: time
309+ time_format: "%Y-%m-%dT%H:%M:%S%z"`
297310
298311 return fluentBitData
299312}
0 commit comments