/src/fluent-bit/src/multiline/flb_ml_parser_go.c
Line | Count | Source |
1 | | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* Fluent Bit |
4 | | * ========== |
5 | | * Copyright (C) 2015-2026 The Fluent Bit Authors |
6 | | * |
7 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
8 | | * you may not use this file except in compliance with the License. |
9 | | * You may obtain a copy of the License at |
10 | | * |
11 | | * http://www.apache.org/licenses/LICENSE-2.0 |
12 | | * |
13 | | * Unless required by applicable law or agreed to in writing, software |
14 | | * distributed under the License is distributed on an "AS IS" BASIS, |
15 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | | * See the License for the specific language governing permissions and |
17 | | * limitations under the License. |
18 | | */ |
19 | | |
20 | | #include <fluent-bit/flb_info.h> |
21 | | #include <fluent-bit/multiline/flb_ml.h> |
22 | | #include <fluent-bit/multiline/flb_ml_rule.h> |
23 | | #include <fluent-bit/multiline/flb_ml_parser.h> |
24 | | |
25 | 740k | #define rule flb_ml_rule_create |
26 | | |
27 | | static void rule_error(struct flb_ml_parser *mlp) |
28 | 88 | { |
29 | 88 | int id; |
30 | | |
31 | 88 | id = mk_list_size(&mlp->regex_rules); |
32 | 88 | flb_error("[multiline: go] rule #%i could not be created", id); |
33 | 88 | flb_ml_parser_destroy(mlp); |
34 | 88 | } |
35 | | |
36 | | /* Go mode */ |
37 | | struct flb_ml_parser *flb_ml_parser_go(struct flb_config *config, char *key) |
38 | 92.5k | { |
39 | 92.5k | int ret; |
40 | 92.5k | struct flb_ml_parser *mlp; |
41 | | |
42 | 92.5k | mlp = flb_ml_parser_create(config, /* Fluent Bit context */ |
43 | 92.5k | "go", /* name */ |
44 | 92.5k | FLB_ML_REGEX, /* type */ |
45 | 92.5k | NULL, /* match_str */ |
46 | 92.5k | FLB_FALSE, /* negate */ |
47 | 92.5k | FLB_ML_FLUSH_TIMEOUT, /* flush_ms */ |
48 | 92.5k | key, /* key_content */ |
49 | 92.5k | NULL, /* key_group */ |
50 | 92.5k | NULL, /* key_pattern */ |
51 | 92.5k | NULL, /* parser ctx */ |
52 | 92.5k | NULL); /* parser name */ |
53 | | |
54 | 92.5k | if (!mlp) { |
55 | 6 | flb_error("[multiline] could not create 'go mode'"); |
56 | 6 | return NULL; |
57 | 6 | } |
58 | | |
59 | 92.5k | ret = rule(mlp, |
60 | 92.5k | "start_state", |
61 | 92.5k | "/\\bpanic: /", |
62 | 92.5k | "go_after_panic", NULL); |
63 | 92.5k | if (ret != 0) { |
64 | 9 | rule_error(mlp); |
65 | 9 | return NULL; |
66 | 9 | } |
67 | | |
68 | 92.5k | ret = rule(mlp, |
69 | 92.5k | "start_state", |
70 | 92.5k | "/http: panic serving/", |
71 | 92.5k | "go_goroutine", NULL); |
72 | 92.5k | if (ret != 0) { |
73 | 14 | rule_error(mlp); |
74 | 14 | return NULL; |
75 | 14 | } |
76 | | |
77 | 92.5k | ret = rule(mlp, |
78 | 92.5k | "go_after_panic", |
79 | 92.5k | "/^$/", |
80 | 92.5k | "go_goroutine", NULL); |
81 | 92.5k | if (ret != 0) { |
82 | 13 | rule_error(mlp); |
83 | 13 | return NULL; |
84 | 13 | } |
85 | | |
86 | 92.5k | ret = rule(mlp, |
87 | 92.5k | "go_after_panic, go_after_signal, go_frame_1", |
88 | 92.5k | "/^$/", |
89 | 92.5k | "go_goroutine", NULL); |
90 | 92.5k | if (ret != 0) { |
91 | 12 | rule_error(mlp); |
92 | 12 | return NULL; |
93 | 12 | } |
94 | | |
95 | 92.5k | ret = rule(mlp, |
96 | 92.5k | "go_after_panic", |
97 | 92.5k | "/^\\[signal /", |
98 | 92.5k | "go_after_signal", NULL); |
99 | 92.5k | if (ret != 0) { |
100 | 9 | rule_error(mlp); |
101 | 9 | return NULL; |
102 | 9 | } |
103 | | |
104 | 92.5k | ret = rule(mlp, |
105 | 92.5k | "go_goroutine", |
106 | 92.5k | "/^goroutine \\d+ \\[[^\\]]+\\]:$/", |
107 | 92.5k | "go_frame_1", NULL); |
108 | 92.5k | if (ret != 0) { |
109 | 12 | rule_error(mlp); |
110 | 12 | return NULL; |
111 | 12 | } |
112 | | |
113 | 92.5k | ret = rule(mlp, |
114 | 92.5k | "go_frame_1", |
115 | 92.5k | "/^(?:[^\\s.:]+\\.)*[^\\s.():]+\\(|^created by /", |
116 | 92.5k | "go_frame_2", NULL); |
117 | 92.5k | if (ret != 0) { |
118 | 10 | rule_error(mlp); |
119 | 10 | return NULL; |
120 | 10 | } |
121 | | |
122 | 92.5k | ret = rule(mlp, |
123 | 92.5k | "go_frame_2", |
124 | 92.5k | "/^\\s/", |
125 | 92.5k | "go_frame_1", NULL); |
126 | 92.5k | if (ret != 0) { |
127 | 9 | rule_error(mlp); |
128 | 9 | return NULL; |
129 | 9 | } |
130 | | |
131 | | /* Map the rules (mandatory for regex rules) */ |
132 | 92.4k | ret = flb_ml_parser_init(mlp); |
133 | 92.4k | if (ret != 0) { |
134 | 9 | flb_error("[multiline: go] error on mapping rules"); |
135 | 9 | flb_ml_parser_destroy(mlp); |
136 | 9 | return NULL; |
137 | 9 | } |
138 | | |
139 | 92.4k | return mlp; |
140 | 92.4k | } |