2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/credentials.h>
10 #include <common/error.h>
11 #include <common/hashtable/hashtable.h>
12 #include <common/hashtable/utils.h>
13 #include <common/macros.h>
14 #include <common/mi-lttng.h>
15 #include <common/optional.h>
16 #include <common/payload-view.h>
17 #include <common/payload.h>
18 #include <common/runas.h>
19 #include <common/string-utils/string-utils.h>
20 #include <lttng/event-rule/event-rule-internal.h>
21 #include <lttng/event-rule/log4j-logging-internal.h>
22 #include <lttng/event.h>
23 #include <lttng/log-level-rule.h>
25 #define IS_LOG4J_LOGGING_EVENT_RULE(rule) \
26 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING)
28 static void lttng_event_rule_log4j_logging_destroy(struct lttng_event_rule
*rule
)
30 struct lttng_event_rule_log4j_logging
*log4j_logging
;
36 log4j_logging
= container_of(
37 rule
, struct lttng_event_rule_log4j_logging
, parent
);
39 lttng_log_level_rule_destroy(log4j_logging
->log_level_rule
);
40 free(log4j_logging
->pattern
);
41 free(log4j_logging
->filter_expression
);
42 free(log4j_logging
->internal_filter
.filter
);
43 free(log4j_logging
->internal_filter
.bytecode
);
47 static bool lttng_event_rule_log4j_logging_validate(
48 const struct lttng_event_rule
*rule
)
51 struct lttng_event_rule_log4j_logging
*log4j_logging
;
57 log4j_logging
= container_of(
58 rule
, struct lttng_event_rule_log4j_logging
, parent
);
61 if (!log4j_logging
->pattern
) {
62 ERR("Invalid log4j_logging event rule: a pattern must be set.");
71 static int lttng_event_rule_log4j_logging_serialize(
72 const struct lttng_event_rule
*rule
,
73 struct lttng_payload
*payload
)
76 size_t pattern_len
, filter_expression_len
, header_offset
;
77 size_t size_before_log_level_rule
;
78 struct lttng_event_rule_log4j_logging
*log4j_logging
;
79 struct lttng_event_rule_log4j_logging_comm log4j_logging_comm
;
80 struct lttng_event_rule_log4j_logging_comm
*header
;
82 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
)) {
87 header_offset
= payload
->buffer
.size
;
89 DBG("Serializing log4j_logging event rule.");
90 log4j_logging
= container_of(
91 rule
, struct lttng_event_rule_log4j_logging
, parent
);
93 pattern_len
= strlen(log4j_logging
->pattern
) + 1;
95 if (log4j_logging
->filter_expression
!= NULL
) {
96 filter_expression_len
=
97 strlen(log4j_logging
->filter_expression
) + 1;
99 filter_expression_len
= 0;
102 log4j_logging_comm
.pattern_len
= pattern_len
;
103 log4j_logging_comm
.filter_expression_len
= filter_expression_len
;
105 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &log4j_logging_comm
,
106 sizeof(log4j_logging_comm
));
111 ret
= lttng_dynamic_buffer_append(
112 &payload
->buffer
, log4j_logging
->pattern
, pattern_len
);
117 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, log4j_logging
->filter_expression
,
118 filter_expression_len
);
123 size_before_log_level_rule
= payload
->buffer
.size
;
125 ret
= lttng_log_level_rule_serialize(log4j_logging
->log_level_rule
, payload
);
130 header
= (typeof(header
)) ((char *) payload
->buffer
.data
+ header_offset
);
131 header
->log_level_rule_len
=
132 payload
->buffer
.size
- size_before_log_level_rule
;
138 static bool lttng_event_rule_log4j_logging_is_equal(
139 const struct lttng_event_rule
*_a
,
140 const struct lttng_event_rule
*_b
)
142 bool is_equal
= false;
143 struct lttng_event_rule_log4j_logging
*a
, *b
;
145 a
= container_of(_a
, struct lttng_event_rule_log4j_logging
, parent
);
146 b
= container_of(_b
, struct lttng_event_rule_log4j_logging
, parent
);
150 if (!!a
->filter_expression
!= !!b
->filter_expression
) {
157 if (strcmp(a
->pattern
, b
->pattern
)) {
161 if (a
->filter_expression
&& b
->filter_expression
) {
162 if (strcmp(a
->filter_expression
, b
->filter_expression
)) {
165 } else if (!!a
->filter_expression
!= !!b
->filter_expression
) {
166 /* One is set; not the other. */
170 if (!lttng_log_level_rule_is_equal(
171 a
->log_level_rule
, b
->log_level_rule
)) {
181 * On success ret is 0;
183 * On error ret is negative.
185 * An event with NO loglevel and the name is * will return NULL.
187 static int generate_agent_filter(
188 const struct lttng_event_rule
*rule
, char **_agent_filter
)
192 char *agent_filter
= NULL
;
195 const struct lttng_log_level_rule
*log_level_rule
= NULL
;
196 enum lttng_event_rule_status status
;
199 assert(_agent_filter
);
201 status
= lttng_event_rule_log4j_logging_get_name_pattern(rule
, &pattern
);
202 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
207 status
= lttng_event_rule_log4j_logging_get_filter(rule
, &filter
);
208 if (status
== LTTNG_EVENT_RULE_STATUS_UNSET
) {
210 } else if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
216 /* Don't add filter for the '*' event. */
217 if (strcmp(pattern
, "*") != 0) {
219 err
= asprintf(&agent_filter
,
220 "(%s) && (logger_name == \"%s\")",
223 err
= asprintf(&agent_filter
, "logger_name == \"%s\"",
228 PERROR("Failed to format agent filter string");
234 status
= lttng_event_rule_log4j_logging_get_log_level_rule(
235 rule
, &log_level_rule
);
236 if (status
== LTTNG_EVENT_RULE_STATUS_OK
) {
237 enum lttng_log_level_rule_status llr_status
;
241 switch (lttng_log_level_rule_get_type(log_level_rule
))
243 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
244 llr_status
= lttng_log_level_rule_exactly_get_level(
245 log_level_rule
, &level
);
248 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
249 llr_status
= lttng_log_level_rule_at_least_as_severe_as_get_level(
250 log_level_rule
, &level
);
257 if (llr_status
!= LTTNG_LOG_LEVEL_RULE_STATUS_OK
) {
262 if (filter
|| agent_filter
) {
265 err
= asprintf(&new_filter
,
266 "(%s) && (int_loglevel %s %d)",
267 agent_filter
? agent_filter
: filter
,
272 agent_filter
= new_filter
;
274 err
= asprintf(&agent_filter
, "int_loglevel %s %d", op
,
279 PERROR("Failed to format agent filter string");
285 *_agent_filter
= agent_filter
;
293 static enum lttng_error_code
294 lttng_event_rule_log4j_logging_generate_filter_bytecode(
295 struct lttng_event_rule
*rule
,
296 const struct lttng_credentials
*creds
)
299 enum lttng_error_code ret_code
;
300 struct lttng_event_rule_log4j_logging
*log4j_logging
;
301 enum lttng_event_rule_status status
;
303 struct lttng_bytecode
*bytecode
= NULL
;
308 log4j_logging
= container_of(
309 rule
, struct lttng_event_rule_log4j_logging
, parent
);
311 status
= lttng_event_rule_log4j_logging_get_filter(rule
, &filter
);
312 if (status
== LTTNG_EVENT_RULE_STATUS_UNSET
) {
314 } else if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
315 ret_code
= LTTNG_ERR_FILTER_INVAL
;
319 if (filter
&& filter
[0] == '\0') {
320 ret_code
= LTTNG_ERR_FILTER_INVAL
;
324 ret
= generate_agent_filter(rule
, &agent_filter
);
326 ret_code
= LTTNG_ERR_FILTER_INVAL
;
330 log4j_logging
->internal_filter
.filter
= agent_filter
;
332 if (log4j_logging
->internal_filter
.filter
== NULL
) {
337 ret
= run_as_generate_filter_bytecode(
338 log4j_logging
->internal_filter
.filter
, creds
,
341 ret_code
= LTTNG_ERR_FILTER_INVAL
;
345 log4j_logging
->internal_filter
.bytecode
= bytecode
;
355 static const char *lttng_event_rule_log4j_logging_get_internal_filter(
356 const struct lttng_event_rule
*rule
)
358 struct lttng_event_rule_log4j_logging
*log4j_logging
;
361 log4j_logging
= container_of(
362 rule
, struct lttng_event_rule_log4j_logging
, parent
);
363 return log4j_logging
->internal_filter
.filter
;
366 static const struct lttng_bytecode
*
367 lttng_event_rule_log4j_logging_get_internal_filter_bytecode(
368 const struct lttng_event_rule
*rule
)
370 struct lttng_event_rule_log4j_logging
*log4j_logging
;
373 log4j_logging
= container_of(
374 rule
, struct lttng_event_rule_log4j_logging
, parent
);
375 return log4j_logging
->internal_filter
.bytecode
;
378 static enum lttng_event_rule_generate_exclusions_status
379 lttng_event_rule_log4j_logging_generate_exclusions(
380 const struct lttng_event_rule
*rule
,
381 struct lttng_event_exclusion
**_exclusions
)
385 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE
;
388 static unsigned long lttng_event_rule_log4j_logging_hash(
389 const struct lttng_event_rule
*rule
)
392 struct lttng_event_rule_log4j_logging
*tp_rule
=
393 container_of(rule
, typeof(*tp_rule
), parent
);
395 hash
= hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING
,
397 hash
^= hash_key_str(tp_rule
->pattern
, lttng_ht_seed
);
399 if (tp_rule
->filter_expression
) {
400 hash
^= hash_key_str(tp_rule
->filter_expression
, lttng_ht_seed
);
403 if (tp_rule
->log_level_rule
) {
404 hash
^= lttng_log_level_rule_hash(tp_rule
->log_level_rule
);
410 static struct lttng_event
*lttng_event_rule_log4j_logging_generate_lttng_event(
411 const struct lttng_event_rule
*rule
)
414 const struct lttng_event_rule_log4j_logging
*log4j_logging
;
415 struct lttng_event
*local_event
= NULL
;
416 struct lttng_event
*event
= NULL
;
417 enum lttng_loglevel_type loglevel_type
;
418 int loglevel_value
= 0;
419 enum lttng_event_rule_status status
;
420 const struct lttng_log_level_rule
*log_level_rule
;
422 log4j_logging
= container_of(
423 rule
, const struct lttng_event_rule_log4j_logging
, parent
);
425 local_event
= zmalloc(sizeof(*local_event
));
430 local_event
->type
= LTTNG_EVENT_TRACEPOINT
;
431 ret
= lttng_strncpy(local_event
->name
, log4j_logging
->pattern
,
432 sizeof(local_event
->name
));
434 ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'",
435 log4j_logging
->pattern
);
440 /* Map the log level rule to an equivalent lttng_loglevel. */
441 status
= lttng_event_rule_log4j_logging_get_log_level_rule(
442 rule
, &log_level_rule
);
443 if (status
== LTTNG_EVENT_RULE_STATUS_UNSET
) {
444 loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
446 } else if (status
== LTTNG_EVENT_RULE_STATUS_OK
) {
447 enum lttng_log_level_rule_status llr_status
;
449 switch (lttng_log_level_rule_get_type(log_level_rule
)) {
450 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
451 llr_status
= lttng_log_level_rule_exactly_get_level(
452 log_level_rule
, &loglevel_value
);
453 loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
455 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
456 llr_status
= lttng_log_level_rule_at_least_as_severe_as_get_level(
457 log_level_rule
, &loglevel_value
);
458 loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
465 if (llr_status
!= LTTNG_LOG_LEVEL_RULE_STATUS_OK
) {
472 local_event
->loglevel_type
= loglevel_type
;
473 local_event
->loglevel
= loglevel_value
;
482 static enum lttng_error_code
lttng_event_rule_log4j_logging_mi_serialize(
483 const struct lttng_event_rule
*rule
, struct mi_writer
*writer
)
486 enum lttng_error_code ret_code
;
487 enum lttng_event_rule_status status
;
488 const char *filter
= NULL
;
489 const char *name_pattern
= NULL
;
490 const struct lttng_log_level_rule
*log_level_rule
= NULL
;
494 assert(IS_LOG4J_LOGGING_EVENT_RULE(rule
));
496 status
= lttng_event_rule_log4j_logging_get_name_pattern(
497 rule
, &name_pattern
);
498 assert(status
== LTTNG_EVENT_RULE_STATUS_OK
);
499 assert(name_pattern
);
501 status
= lttng_event_rule_log4j_logging_get_filter(rule
, &filter
);
502 assert(status
== LTTNG_EVENT_RULE_STATUS_OK
||
503 status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
505 status
= lttng_event_rule_log4j_logging_get_log_level_rule(
506 rule
, &log_level_rule
);
507 assert(status
== LTTNG_EVENT_RULE_STATUS_OK
||
508 status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
510 /* Open event rule log4j logging element. */
511 ret
= mi_lttng_writer_open_element(
512 writer
, mi_lttng_element_event_rule_log4j_logging
);
518 ret
= mi_lttng_writer_write_element_string(writer
,
519 mi_lttng_element_event_rule_name_pattern
, name_pattern
);
524 /* Filter expression. */
525 if (filter
!= NULL
) {
526 ret
= mi_lttng_writer_write_element_string(writer
,
527 mi_lttng_element_event_rule_filter_expression
,
534 /* Log level rule. */
535 if (log_level_rule
) {
536 ret_code
= lttng_log_level_rule_mi_serialize(
537 log_level_rule
, writer
);
538 if (ret_code
!= LTTNG_OK
) {
543 /* Close event rule log4j logging element. */
544 ret
= mi_lttng_writer_close_element(writer
);
553 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
558 struct lttng_event_rule
*lttng_event_rule_log4j_logging_create(void)
560 struct lttng_event_rule
*rule
= NULL
;
561 struct lttng_event_rule_log4j_logging
*tp_rule
;
562 enum lttng_event_rule_status status
;
564 tp_rule
= zmalloc(sizeof(struct lttng_event_rule_log4j_logging
));
569 rule
= &tp_rule
->parent
;
570 lttng_event_rule_init(&tp_rule
->parent
, LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING
);
571 tp_rule
->parent
.validate
= lttng_event_rule_log4j_logging_validate
;
572 tp_rule
->parent
.serialize
= lttng_event_rule_log4j_logging_serialize
;
573 tp_rule
->parent
.equal
= lttng_event_rule_log4j_logging_is_equal
;
574 tp_rule
->parent
.destroy
= lttng_event_rule_log4j_logging_destroy
;
575 tp_rule
->parent
.generate_filter_bytecode
=
576 lttng_event_rule_log4j_logging_generate_filter_bytecode
;
577 tp_rule
->parent
.get_filter
=
578 lttng_event_rule_log4j_logging_get_internal_filter
;
579 tp_rule
->parent
.get_filter_bytecode
=
580 lttng_event_rule_log4j_logging_get_internal_filter_bytecode
;
581 tp_rule
->parent
.generate_exclusions
=
582 lttng_event_rule_log4j_logging_generate_exclusions
;
583 tp_rule
->parent
.hash
= lttng_event_rule_log4j_logging_hash
;
584 tp_rule
->parent
.generate_lttng_event
=
585 lttng_event_rule_log4j_logging_generate_lttng_event
;
586 tp_rule
->parent
.mi_serialize
= lttng_event_rule_log4j_logging_mi_serialize
;
588 tp_rule
->log_level_rule
= NULL
;
590 /* Default pattern is '*'. */
591 status
= lttng_event_rule_log4j_logging_set_name_pattern(rule
, "*");
592 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
593 lttng_event_rule_destroy(rule
);
602 ssize_t
lttng_event_rule_log4j_logging_create_from_payload(
603 struct lttng_payload_view
*view
,
604 struct lttng_event_rule
**_event_rule
)
606 ssize_t ret
, offset
= 0;
607 enum lttng_event_rule_status status
;
608 const struct lttng_event_rule_log4j_logging_comm
*log4j_logging_comm
;
610 const char *filter_expression
= NULL
;
611 struct lttng_buffer_view current_buffer_view
;
612 struct lttng_event_rule
*rule
= NULL
;
613 struct lttng_log_level_rule
*log_level_rule
= NULL
;
620 current_buffer_view
= lttng_buffer_view_from_view(
621 &view
->buffer
, offset
, sizeof(*log4j_logging_comm
));
622 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
623 ERR("Failed to initialize from malformed event rule log4j_logging: buffer too short to contain header.");
628 log4j_logging_comm
= (typeof(log4j_logging_comm
)) current_buffer_view
.data
;
630 rule
= lttng_event_rule_log4j_logging_create();
632 ERR("Failed to create event rule log4j_logging.");
637 /* Skip to payload. */
638 offset
+= current_buffer_view
.size
;
640 /* Map the pattern. */
641 current_buffer_view
= lttng_buffer_view_from_view(
642 &view
->buffer
, offset
, log4j_logging_comm
->pattern_len
);
644 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
649 pattern
= current_buffer_view
.data
;
650 if (!lttng_buffer_view_contains_string(¤t_buffer_view
, pattern
,
651 log4j_logging_comm
->pattern_len
)) {
656 /* Skip after the pattern. */
657 offset
+= log4j_logging_comm
->pattern_len
;
659 if (!log4j_logging_comm
->filter_expression_len
) {
660 goto skip_filter_expression
;
663 /* Map the filter_expression. */
664 current_buffer_view
= lttng_buffer_view_from_view(&view
->buffer
, offset
,
665 log4j_logging_comm
->filter_expression_len
);
666 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
671 filter_expression
= current_buffer_view
.data
;
672 if (!lttng_buffer_view_contains_string(¤t_buffer_view
,
674 log4j_logging_comm
->filter_expression_len
)) {
679 /* Skip after the pattern. */
680 offset
+= log4j_logging_comm
->filter_expression_len
;
682 skip_filter_expression
:
683 if (!log4j_logging_comm
->log_level_rule_len
) {
684 goto skip_log_level_rule
;
688 /* Map the log level rule. */
689 struct lttng_payload_view current_payload_view
=
690 lttng_payload_view_from_view(view
, offset
,
691 log4j_logging_comm
->log_level_rule_len
);
693 ret
= lttng_log_level_rule_create_from_payload(
694 ¤t_payload_view
, &log_level_rule
);
700 assert(ret
== log4j_logging_comm
->log_level_rule_len
);
703 /* Skip after the log level rule. */
704 offset
+= log4j_logging_comm
->log_level_rule_len
;
708 status
= lttng_event_rule_log4j_logging_set_name_pattern(rule
, pattern
);
709 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
710 ERR("Failed to set event rule log4j_logging pattern.");
715 if (filter_expression
) {
716 status
= lttng_event_rule_log4j_logging_set_filter(
717 rule
, filter_expression
);
718 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
719 ERR("Failed to set event rule log4j_logging pattern.");
725 if (log_level_rule
) {
726 status
= lttng_event_rule_log4j_logging_set_log_level_rule(
727 rule
, log_level_rule
);
728 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
729 ERR("Failed to set event rule log4j_logging log level rule.");
739 lttng_log_level_rule_destroy(log_level_rule
);
740 lttng_event_rule_destroy(rule
);
744 enum lttng_event_rule_status
lttng_event_rule_log4j_logging_set_name_pattern(
745 struct lttng_event_rule
*rule
, const char *pattern
)
747 char *pattern_copy
= NULL
;
748 struct lttng_event_rule_log4j_logging
*log4j_logging
;
749 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
751 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
) || !pattern
||
752 strlen(pattern
) == 0) {
753 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
757 log4j_logging
= container_of(
758 rule
, struct lttng_event_rule_log4j_logging
, parent
);
759 pattern_copy
= strdup(pattern
);
761 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
765 /* Normalize the pattern. */
766 strutils_normalize_star_glob_pattern(pattern_copy
);
768 free(log4j_logging
->pattern
);
770 log4j_logging
->pattern
= pattern_copy
;
776 enum lttng_event_rule_status
lttng_event_rule_log4j_logging_get_name_pattern(
777 const struct lttng_event_rule
*rule
, const char **pattern
)
779 struct lttng_event_rule_log4j_logging
*log4j_logging
;
780 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
782 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
) || !pattern
) {
783 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
787 log4j_logging
= container_of(
788 rule
, struct lttng_event_rule_log4j_logging
, parent
);
789 if (!log4j_logging
->pattern
) {
790 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
794 *pattern
= log4j_logging
->pattern
;
799 enum lttng_event_rule_status
lttng_event_rule_log4j_logging_set_filter(
800 struct lttng_event_rule
*rule
, const char *expression
)
802 char *expression_copy
= NULL
;
803 struct lttng_event_rule_log4j_logging
*log4j_logging
;
804 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
806 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
) || !expression
||
807 strlen(expression
) == 0) {
808 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
812 log4j_logging
= container_of(
813 rule
, struct lttng_event_rule_log4j_logging
, parent
);
814 expression_copy
= strdup(expression
);
815 if (!expression_copy
) {
816 PERROR("Failed to copy filter expression");
817 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
821 if (log4j_logging
->filter_expression
) {
822 free(log4j_logging
->filter_expression
);
825 log4j_logging
->filter_expression
= expression_copy
;
826 expression_copy
= NULL
;
831 enum lttng_event_rule_status
lttng_event_rule_log4j_logging_get_filter(
832 const struct lttng_event_rule
*rule
, const char **expression
)
834 struct lttng_event_rule_log4j_logging
*log4j_logging
;
835 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
837 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
) || !expression
) {
838 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
842 log4j_logging
= container_of(
843 rule
, struct lttng_event_rule_log4j_logging
, parent
);
844 if (!log4j_logging
->filter_expression
) {
845 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
849 *expression
= log4j_logging
->filter_expression
;
854 static bool log_level_rule_valid(const struct lttng_log_level_rule
*rule
)
857 * For both LOG4J custom log level are possible and can
858 * span the entire int32 range.
863 enum lttng_event_rule_status
lttng_event_rule_log4j_logging_set_log_level_rule(
864 struct lttng_event_rule
*rule
,
865 const struct lttng_log_level_rule
*log_level_rule
)
867 struct lttng_event_rule_log4j_logging
*log4j_logging
;
868 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
869 struct lttng_log_level_rule
*copy
= NULL
;
871 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
)) {
872 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
876 log4j_logging
= container_of(
877 rule
, struct lttng_event_rule_log4j_logging
, parent
);
879 if (!log_level_rule_valid(log_level_rule
)) {
880 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
884 copy
= lttng_log_level_rule_copy(log_level_rule
);
886 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
890 if (log4j_logging
->log_level_rule
) {
891 lttng_log_level_rule_destroy(log4j_logging
->log_level_rule
);
894 log4j_logging
->log_level_rule
= copy
;
900 enum lttng_event_rule_status
lttng_event_rule_log4j_logging_get_log_level_rule(
901 const struct lttng_event_rule
*rule
,
902 const struct lttng_log_level_rule
**log_level_rule
905 struct lttng_event_rule_log4j_logging
*log4j_logging
;
906 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
908 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
) || !log_level_rule
) {
909 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
913 log4j_logging
= container_of(
914 rule
, struct lttng_event_rule_log4j_logging
, parent
);
915 if (log4j_logging
->log_level_rule
== NULL
) {
916 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
920 *log_level_rule
= log4j_logging
->log_level_rule
;