Skip to content

Commit ed6db59

Browse files
committed
confd: extend syslogd support with property-based filtering
This is the last commit in the series that extend syslog matching and sorting to the level of sysklogd 2.7.0 and later. Like hostname filtering, property based filtering is not supported natively in the IETF RFC, and the modeling is unfortunately a bit clunky. The most confusing part is probably 'negate' which is the '!' operator that inverts the matching, e.g., !icase_regex match everthing *not* in the regexp. Fixes #1091 Signed-off-by: Joachim Wiberg <[email protected]>
1 parent efb3d88 commit ed6db59

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

src/confd/src/ietf-syslog.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,40 @@ static size_t selector(sr_session_ctx_t *session, struct action *act)
118118
count = 0;
119119
}
120120

121+
/* Check for property-filter (infix-syslog augment) */
122+
char *property = srx_get_str(session, "%s/infix-syslog:property-filter/property", act->xpath);
123+
if (property) {
124+
char *operator = srx_get_str(session, "%s/infix-syslog:property-filter/operator", act->xpath);
125+
char *value = srx_get_str(session, "%s/infix-syslog:property-filter/value", act->xpath);
126+
char *case_str = srx_get_str(session, "%s/infix-syslog:property-filter/case-insensitive", act->xpath);
127+
char *negate_str = srx_get_str(session, "%s/infix-syslog:property-filter/negate", act->xpath);
128+
129+
if (operator && value) {
130+
/* Build operator prefix: [!][icase_]operator */
131+
char op_prefix[32] = "";
132+
133+
/* Only apply negate if explicitly set to true */
134+
if (negate_str && !strcmp(negate_str, "true"))
135+
strlcat(op_prefix, "!", sizeof(op_prefix));
136+
137+
/* Only apply icase_ if explicitly set to true */
138+
if (case_str && !strcmp(case_str, "true"))
139+
strlcat(op_prefix, "icase_", sizeof(op_prefix));
140+
141+
strlcat(op_prefix, operator, sizeof(op_prefix));
142+
143+
/* Property-based filter: :property, [!][icase_]operator, "value" */
144+
fprintf(act->fp, ":%s, %s, \"%s\"\n", property, op_prefix, value);
145+
has_pattern = true;
146+
}
147+
148+
free(property);
149+
free(operator);
150+
free(value);
151+
free(case_str);
152+
free(negate_str);
153+
}
154+
121155
/* Check for pattern-match (select-match feature) */
122156
pattern = srx_get_str(session, "%s/pattern-match", act->xpath);
123157
if (pattern) {

src/confd/yang/confd/infix-syslog.yang

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,83 @@ module infix-syslog {
175175
description "Filter messages by hostname. Messages from the listed
176176
hostnames will be logged to this file.";
177177
}
178+
179+
container property-filter {
180+
presence "Enable property-based filtering";
181+
description "Advanced property-based message filtering. Allows filtering
182+
on specific message fields with various comparison operators.";
183+
184+
leaf property {
185+
type enumeration {
186+
enum msg {
187+
description "The message body (SYSLOG-MSG field).";
188+
}
189+
enum msgid {
190+
description "The RFC5424 message identifier (MSGID field).";
191+
}
192+
enum programname {
193+
description "The originating program or tag name.";
194+
}
195+
enum hostname {
196+
description "The message source hostname.";
197+
}
198+
enum source {
199+
description "The message source (alias for hostname).";
200+
}
201+
enum data {
202+
description "The RFC5424 structured data (SD field).";
203+
}
204+
}
205+
mandatory true;
206+
description "The message property to match against.";
207+
}
208+
209+
leaf operator {
210+
type enumeration {
211+
enum contains {
212+
description "Substring match (case-sensitive).";
213+
}
214+
enum isequal {
215+
description "Exact equality match.";
216+
}
217+
enum startswith {
218+
description "Prefix match.";
219+
}
220+
enum regex {
221+
description "Basic regular expression match.";
222+
}
223+
enum ereregex {
224+
description "Extended regular expression match (POSIX ERE).";
225+
}
226+
}
227+
mandatory true;
228+
description "The comparison operator to use.";
229+
}
230+
231+
leaf value {
232+
type string;
233+
mandatory true;
234+
description "The value to compare against.";
235+
}
236+
237+
leaf case-insensitive {
238+
type boolean;
239+
description "Perform case-insensitive comparison.";
240+
}
241+
242+
leaf negate {
243+
type boolean;
244+
description "Negate the comparison result. When set to true, the
245+
filter matches messages that do NOT satisfy the
246+
specified condition.
247+
248+
For example:
249+
- operator: contains, value: 'ERROR', negate: false
250+
→ matches messages containing 'ERROR'
251+
- operator: contains, value: 'ERROR', negate: true
252+
→ matches messages NOT containing 'ERROR'";
253+
}
254+
}
178255
}
179256

180257
augment "/syslog:syslog/syslog:actions/syslog:remote/syslog:destination" {

0 commit comments

Comments
 (0)