2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/credentials.hpp>
9 #include <common/error.hpp>
10 #include <common/hashtable/hashtable.hpp>
11 #include <common/hashtable/utils.hpp>
12 #include <common/macros.hpp>
13 #include <common/mi-lttng.hpp>
14 #include <common/optional.hpp>
15 #include <common/payload-view.hpp>
16 #include <common/payload.hpp>
17 #include <common/runas.hpp>
18 #include <common/string-utils/string-utils.hpp>
20 #include <lttng/event-rule/event-rule-internal.hpp>
21 #include <lttng/event-rule/log4j-logging-internal.hpp>
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
;
32 if (rule
== nullptr) {
36 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
38 lttng_log_level_rule_destroy(log4j_logging
->log_level_rule
);
39 free(log4j_logging
->pattern
);
40 free(log4j_logging
->filter_expression
);
41 free(log4j_logging
->internal_filter
.filter
);
42 free(log4j_logging
->internal_filter
.bytecode
);
46 static bool lttng_event_rule_log4j_logging_validate(const struct lttng_event_rule
*rule
)
49 struct lttng_event_rule_log4j_logging
*log4j_logging
;
55 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
58 if (!log4j_logging
->pattern
) {
59 ERR("Invalid log4j_logging event rule: a pattern must be set.");
68 static int lttng_event_rule_log4j_logging_serialize(const struct lttng_event_rule
*rule
,
69 struct lttng_payload
*payload
)
72 size_t pattern_len
, filter_expression_len
, header_offset
;
73 size_t size_before_log_level_rule
;
74 struct lttng_event_rule_log4j_logging
*log4j_logging
;
75 struct lttng_event_rule_log4j_logging_comm log4j_logging_comm
;
76 struct lttng_event_rule_log4j_logging_comm
*header
;
78 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
)) {
83 header_offset
= payload
->buffer
.size
;
85 DBG("Serializing log4j_logging event rule.");
86 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
88 pattern_len
= strlen(log4j_logging
->pattern
) + 1;
90 if (log4j_logging
->filter_expression
!= nullptr) {
91 filter_expression_len
= strlen(log4j_logging
->filter_expression
) + 1;
93 filter_expression_len
= 0;
96 log4j_logging_comm
.pattern_len
= pattern_len
;
97 log4j_logging_comm
.filter_expression_len
= filter_expression_len
;
99 ret
= lttng_dynamic_buffer_append(
100 &payload
->buffer
, &log4j_logging_comm
, sizeof(log4j_logging_comm
));
105 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, log4j_logging
->pattern
, pattern_len
);
110 ret
= lttng_dynamic_buffer_append(
111 &payload
->buffer
, log4j_logging
->filter_expression
, filter_expression_len
);
116 size_before_log_level_rule
= payload
->buffer
.size
;
118 ret
= lttng_log_level_rule_serialize(log4j_logging
->log_level_rule
, payload
);
123 header
= (typeof(header
)) ((char *) payload
->buffer
.data
+ header_offset
);
124 header
->log_level_rule_len
= payload
->buffer
.size
- size_before_log_level_rule
;
130 static bool lttng_event_rule_log4j_logging_is_equal(const struct lttng_event_rule
*_a
,
131 const struct lttng_event_rule
*_b
)
133 bool is_equal
= false;
134 struct lttng_event_rule_log4j_logging
*a
, *b
;
136 a
= lttng::utils::container_of(_a
, <tng_event_rule_log4j_logging::parent
);
137 b
= lttng::utils::container_of(_b
, <tng_event_rule_log4j_logging::parent
);
141 if (!!a
->filter_expression
!= !!b
->filter_expression
) {
146 LTTNG_ASSERT(a
->pattern
);
147 LTTNG_ASSERT(b
->pattern
);
148 if (strcmp(a
->pattern
, b
->pattern
) != 0) {
152 if (a
->filter_expression
&& b
->filter_expression
) {
153 if (strcmp(a
->filter_expression
, b
->filter_expression
) != 0) {
156 } else if (!!a
->filter_expression
!= !!b
->filter_expression
) {
157 /* One is set; not the other. */
161 if (!lttng_log_level_rule_is_equal(a
->log_level_rule
, b
->log_level_rule
)) {
171 * On success ret is 0;
173 * On error ret is negative.
175 * An event with NO loglevel and the name is * will return NULL.
177 static int generate_agent_filter(const struct lttng_event_rule
*rule
, char **_agent_filter
)
181 char *agent_filter
= nullptr;
184 const struct lttng_log_level_rule
*log_level_rule
= nullptr;
185 enum lttng_event_rule_status status
;
188 LTTNG_ASSERT(_agent_filter
);
190 status
= lttng_event_rule_log4j_logging_get_name_pattern(rule
, &pattern
);
191 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
196 status
= lttng_event_rule_log4j_logging_get_filter(rule
, &filter
);
197 if (status
== LTTNG_EVENT_RULE_STATUS_UNSET
) {
199 } else if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
204 /* Don't add filter for the '*' event. */
205 if (strcmp(pattern
, "*") != 0) {
208 &agent_filter
, "(%s) && (logger_name == \"%s\")", filter
, pattern
);
210 err
= asprintf(&agent_filter
, "logger_name == \"%s\"", pattern
);
214 PERROR("Failed to format agent filter string");
220 status
= lttng_event_rule_log4j_logging_get_log_level_rule(rule
, &log_level_rule
);
221 if (status
== LTTNG_EVENT_RULE_STATUS_OK
) {
222 enum lttng_log_level_rule_status llr_status
;
226 switch (lttng_log_level_rule_get_type(log_level_rule
)) {
227 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
228 llr_status
= lttng_log_level_rule_exactly_get_level(log_level_rule
, &level
);
231 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
232 llr_status
= lttng_log_level_rule_at_least_as_severe_as_get_level(
233 log_level_rule
, &level
);
240 if (llr_status
!= LTTNG_LOG_LEVEL_RULE_STATUS_OK
) {
245 if (filter
|| agent_filter
) {
248 err
= asprintf(&new_filter
,
249 "(%s) && (int_loglevel %s %d)",
250 agent_filter
? agent_filter
: filter
,
256 agent_filter
= new_filter
;
258 err
= asprintf(&agent_filter
, "int_loglevel %s %d", op
, level
);
262 PERROR("Failed to format agent filter string");
268 *_agent_filter
= agent_filter
;
269 agent_filter
= nullptr;
276 static enum lttng_error_code
277 lttng_event_rule_log4j_logging_generate_filter_bytecode(struct lttng_event_rule
*rule
,
278 const struct lttng_credentials
*creds
)
281 enum lttng_error_code ret_code
;
282 struct lttng_event_rule_log4j_logging
*log4j_logging
;
283 enum lttng_event_rule_status status
;
285 struct lttng_bytecode
*bytecode
= nullptr;
290 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
292 status
= lttng_event_rule_log4j_logging_get_filter(rule
, &filter
);
293 if (status
== LTTNG_EVENT_RULE_STATUS_UNSET
) {
295 } else if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
296 ret_code
= LTTNG_ERR_FILTER_INVAL
;
300 if (filter
&& filter
[0] == '\0') {
301 ret_code
= LTTNG_ERR_FILTER_INVAL
;
305 ret
= generate_agent_filter(rule
, &agent_filter
);
307 ret_code
= LTTNG_ERR_FILTER_INVAL
;
311 log4j_logging
->internal_filter
.filter
= agent_filter
;
313 if (log4j_logging
->internal_filter
.filter
== nullptr) {
318 ret
= run_as_generate_filter_bytecode(
319 log4j_logging
->internal_filter
.filter
, creds
, &bytecode
);
321 ret_code
= LTTNG_ERR_FILTER_INVAL
;
325 log4j_logging
->internal_filter
.bytecode
= bytecode
;
336 lttng_event_rule_log4j_logging_get_internal_filter(const struct lttng_event_rule
*rule
)
338 struct lttng_event_rule_log4j_logging
*log4j_logging
;
341 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
342 return log4j_logging
->internal_filter
.filter
;
345 static const struct lttng_bytecode
*
346 lttng_event_rule_log4j_logging_get_internal_filter_bytecode(const struct lttng_event_rule
*rule
)
348 struct lttng_event_rule_log4j_logging
*log4j_logging
;
351 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
352 return log4j_logging
->internal_filter
.bytecode
;
355 static enum lttng_event_rule_generate_exclusions_status
356 lttng_event_rule_log4j_logging_generate_exclusions(const struct lttng_event_rule
*rule
357 __attribute__((unused
)),
358 struct lttng_event_exclusion
**_exclusions
)
361 *_exclusions
= nullptr;
362 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE
;
365 static unsigned long lttng_event_rule_log4j_logging_hash(const struct lttng_event_rule
*rule
)
368 struct lttng_event_rule_log4j_logging
*tp_rule
=
369 lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
371 hash
= hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING
, lttng_ht_seed
);
372 hash
^= hash_key_str(tp_rule
->pattern
, lttng_ht_seed
);
374 if (tp_rule
->filter_expression
) {
375 hash
^= hash_key_str(tp_rule
->filter_expression
, lttng_ht_seed
);
378 if (tp_rule
->log_level_rule
) {
379 hash
^= lttng_log_level_rule_hash(tp_rule
->log_level_rule
);
385 static struct lttng_event
*
386 lttng_event_rule_log4j_logging_generate_lttng_event(const struct lttng_event_rule
*rule
)
389 const struct lttng_event_rule_log4j_logging
*log4j_logging
;
390 struct lttng_event
*local_event
= nullptr;
391 struct lttng_event
*event
= nullptr;
392 enum lttng_loglevel_type loglevel_type
;
393 int loglevel_value
= 0;
394 enum lttng_event_rule_status status
;
395 const struct lttng_log_level_rule
*log_level_rule
;
397 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
399 local_event
= zmalloc
<lttng_event
>();
404 local_event
->type
= LTTNG_EVENT_TRACEPOINT
;
405 ret
= lttng_strncpy(local_event
->name
, log4j_logging
->pattern
, sizeof(local_event
->name
));
407 ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'",
408 log4j_logging
->pattern
);
412 /* Map the log level rule to an equivalent lttng_loglevel. */
413 status
= lttng_event_rule_log4j_logging_get_log_level_rule(rule
, &log_level_rule
);
414 if (status
== LTTNG_EVENT_RULE_STATUS_UNSET
) {
415 loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
416 loglevel_value
= LTTNG_LOGLEVEL_LOG4J_ALL
;
417 } else if (status
== LTTNG_EVENT_RULE_STATUS_OK
) {
418 enum lttng_log_level_rule_status llr_status
;
420 switch (lttng_log_level_rule_get_type(log_level_rule
)) {
421 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
422 llr_status
= lttng_log_level_rule_exactly_get_level(log_level_rule
,
424 loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
426 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
427 llr_status
= lttng_log_level_rule_at_least_as_severe_as_get_level(
428 log_level_rule
, &loglevel_value
);
429 loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
436 if (llr_status
!= LTTNG_LOG_LEVEL_RULE_STATUS_OK
) {
443 local_event
->loglevel_type
= loglevel_type
;
444 local_event
->loglevel
= loglevel_value
;
447 local_event
= nullptr;
453 static enum lttng_error_code
454 lttng_event_rule_log4j_logging_mi_serialize(const struct lttng_event_rule
*rule
,
455 struct mi_writer
*writer
)
458 enum lttng_error_code ret_code
;
459 enum lttng_event_rule_status status
;
460 const char *filter
= nullptr;
461 const char *name_pattern
= nullptr;
462 const struct lttng_log_level_rule
*log_level_rule
= nullptr;
465 LTTNG_ASSERT(writer
);
466 LTTNG_ASSERT(IS_LOG4J_LOGGING_EVENT_RULE(rule
));
468 status
= lttng_event_rule_log4j_logging_get_name_pattern(rule
, &name_pattern
);
469 LTTNG_ASSERT(status
== LTTNG_EVENT_RULE_STATUS_OK
);
470 LTTNG_ASSERT(name_pattern
);
472 status
= lttng_event_rule_log4j_logging_get_filter(rule
, &filter
);
473 LTTNG_ASSERT(status
== LTTNG_EVENT_RULE_STATUS_OK
||
474 status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
476 status
= lttng_event_rule_log4j_logging_get_log_level_rule(rule
, &log_level_rule
);
477 LTTNG_ASSERT(status
== LTTNG_EVENT_RULE_STATUS_OK
||
478 status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
480 /* Open event rule log4j logging element. */
481 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_event_rule_log4j_logging
);
487 ret
= mi_lttng_writer_write_element_string(
488 writer
, mi_lttng_element_event_rule_name_pattern
, name_pattern
);
493 /* Filter expression. */
494 if (filter
!= nullptr) {
495 ret
= mi_lttng_writer_write_element_string(
496 writer
, mi_lttng_element_event_rule_filter_expression
, filter
);
502 /* Log level rule. */
503 if (log_level_rule
) {
504 ret_code
= lttng_log_level_rule_mi_serialize(log_level_rule
, writer
);
505 if (ret_code
!= LTTNG_OK
) {
510 /* Close event rule log4j logging element. */
511 ret
= mi_lttng_writer_close_element(writer
);
520 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
525 struct lttng_event_rule
*lttng_event_rule_log4j_logging_create(void)
527 struct lttng_event_rule
*rule
= nullptr;
528 struct lttng_event_rule_log4j_logging
*tp_rule
;
529 enum lttng_event_rule_status status
;
531 tp_rule
= zmalloc
<lttng_event_rule_log4j_logging
>();
536 rule
= &tp_rule
->parent
;
537 lttng_event_rule_init(&tp_rule
->parent
, LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING
);
538 tp_rule
->parent
.validate
= lttng_event_rule_log4j_logging_validate
;
539 tp_rule
->parent
.serialize
= lttng_event_rule_log4j_logging_serialize
;
540 tp_rule
->parent
.equal
= lttng_event_rule_log4j_logging_is_equal
;
541 tp_rule
->parent
.destroy
= lttng_event_rule_log4j_logging_destroy
;
542 tp_rule
->parent
.generate_filter_bytecode
=
543 lttng_event_rule_log4j_logging_generate_filter_bytecode
;
544 tp_rule
->parent
.get_filter
= lttng_event_rule_log4j_logging_get_internal_filter
;
545 tp_rule
->parent
.get_filter_bytecode
=
546 lttng_event_rule_log4j_logging_get_internal_filter_bytecode
;
547 tp_rule
->parent
.generate_exclusions
= lttng_event_rule_log4j_logging_generate_exclusions
;
548 tp_rule
->parent
.hash
= lttng_event_rule_log4j_logging_hash
;
549 tp_rule
->parent
.generate_lttng_event
= lttng_event_rule_log4j_logging_generate_lttng_event
;
550 tp_rule
->parent
.mi_serialize
= lttng_event_rule_log4j_logging_mi_serialize
;
552 tp_rule
->log_level_rule
= nullptr;
554 /* Default pattern is '*'. */
555 status
= lttng_event_rule_log4j_logging_set_name_pattern(rule
, "*");
556 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
557 lttng_event_rule_destroy(rule
);
565 ssize_t
lttng_event_rule_log4j_logging_create_from_payload(struct lttng_payload_view
*view
,
566 struct lttng_event_rule
**_event_rule
)
568 ssize_t ret
, offset
= 0;
569 enum lttng_event_rule_status status
;
570 const struct lttng_event_rule_log4j_logging_comm
*log4j_logging_comm
;
572 const char *filter_expression
= nullptr;
573 struct lttng_buffer_view current_buffer_view
;
574 struct lttng_event_rule
*rule
= nullptr;
575 struct lttng_log_level_rule
*log_level_rule
= nullptr;
582 current_buffer_view
=
583 lttng_buffer_view_from_view(&view
->buffer
, offset
, sizeof(*log4j_logging_comm
));
584 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
585 ERR("Failed to initialize from malformed event rule log4j_logging: buffer too short to contain header.");
590 log4j_logging_comm
= (typeof(log4j_logging_comm
)) current_buffer_view
.data
;
592 rule
= lttng_event_rule_log4j_logging_create();
594 ERR("Failed to create event rule log4j_logging.");
599 /* Skip to payload. */
600 offset
+= current_buffer_view
.size
;
602 /* Map the pattern. */
603 current_buffer_view
=
604 lttng_buffer_view_from_view(&view
->buffer
, offset
, log4j_logging_comm
->pattern_len
);
606 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
611 pattern
= current_buffer_view
.data
;
612 if (!lttng_buffer_view_contains_string(
613 ¤t_buffer_view
, pattern
, log4j_logging_comm
->pattern_len
)) {
618 /* Skip after the pattern. */
619 offset
+= log4j_logging_comm
->pattern_len
;
621 if (!log4j_logging_comm
->filter_expression_len
) {
622 goto skip_filter_expression
;
625 /* Map the filter_expression. */
626 current_buffer_view
= lttng_buffer_view_from_view(
627 &view
->buffer
, offset
, log4j_logging_comm
->filter_expression_len
);
628 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
633 filter_expression
= current_buffer_view
.data
;
634 if (!lttng_buffer_view_contains_string(¤t_buffer_view
,
636 log4j_logging_comm
->filter_expression_len
)) {
641 /* Skip after the pattern. */
642 offset
+= log4j_logging_comm
->filter_expression_len
;
644 skip_filter_expression
:
645 if (!log4j_logging_comm
->log_level_rule_len
) {
646 goto skip_log_level_rule
;
650 /* Map the log level rule. */
651 struct lttng_payload_view current_payload_view
= lttng_payload_view_from_view(
652 view
, offset
, log4j_logging_comm
->log_level_rule_len
);
654 ret
= lttng_log_level_rule_create_from_payload(¤t_payload_view
,
661 LTTNG_ASSERT(ret
== log4j_logging_comm
->log_level_rule_len
);
664 /* Skip after the log level rule. */
665 offset
+= log4j_logging_comm
->log_level_rule_len
;
669 status
= lttng_event_rule_log4j_logging_set_name_pattern(rule
, pattern
);
670 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
671 ERR("Failed to set event rule log4j_logging pattern.");
676 if (filter_expression
) {
677 status
= lttng_event_rule_log4j_logging_set_filter(rule
, filter_expression
);
678 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
679 ERR("Failed to set event rule log4j_logging pattern.");
685 if (log_level_rule
) {
686 status
= lttng_event_rule_log4j_logging_set_log_level_rule(rule
, log_level_rule
);
687 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
688 ERR("Failed to set event rule log4j_logging log level rule.");
698 lttng_log_level_rule_destroy(log_level_rule
);
699 lttng_event_rule_destroy(rule
);
703 enum lttng_event_rule_status
704 lttng_event_rule_log4j_logging_set_name_pattern(struct lttng_event_rule
*rule
, const char *pattern
)
706 char *pattern_copy
= nullptr;
707 struct lttng_event_rule_log4j_logging
*log4j_logging
;
708 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
710 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
) || !pattern
|| strlen(pattern
) == 0) {
711 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
715 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
716 pattern_copy
= strdup(pattern
);
718 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
722 /* Normalize the pattern. */
723 strutils_normalize_star_glob_pattern(pattern_copy
);
725 free(log4j_logging
->pattern
);
727 log4j_logging
->pattern
= pattern_copy
;
728 pattern_copy
= nullptr;
733 enum lttng_event_rule_status
734 lttng_event_rule_log4j_logging_get_name_pattern(const struct lttng_event_rule
*rule
,
735 const char **pattern
)
737 struct lttng_event_rule_log4j_logging
*log4j_logging
;
738 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
740 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
) || !pattern
) {
741 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
745 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
746 if (!log4j_logging
->pattern
) {
747 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
751 *pattern
= log4j_logging
->pattern
;
756 enum lttng_event_rule_status
757 lttng_event_rule_log4j_logging_set_filter(struct lttng_event_rule
*rule
, const char *expression
)
759 char *expression_copy
= nullptr;
760 struct lttng_event_rule_log4j_logging
*log4j_logging
;
761 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
763 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
) || !expression
|| strlen(expression
) == 0) {
764 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
768 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
769 expression_copy
= strdup(expression
);
770 if (!expression_copy
) {
771 PERROR("Failed to copy filter expression");
772 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
776 if (log4j_logging
->filter_expression
) {
777 free(log4j_logging
->filter_expression
);
780 log4j_logging
->filter_expression
= expression_copy
;
781 expression_copy
= nullptr;
786 enum lttng_event_rule_status
787 lttng_event_rule_log4j_logging_get_filter(const struct lttng_event_rule
*rule
,
788 const char **expression
)
790 struct lttng_event_rule_log4j_logging
*log4j_logging
;
791 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
793 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
) || !expression
) {
794 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
798 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
799 if (!log4j_logging
->filter_expression
) {
800 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
804 *expression
= log4j_logging
->filter_expression
;
809 static bool log_level_rule_valid(const struct lttng_log_level_rule
*rule
__attribute__((unused
)))
812 * For both LOG4J custom log level are possible and can
813 * span the entire int32 range.
818 enum lttng_event_rule_status
819 lttng_event_rule_log4j_logging_set_log_level_rule(struct lttng_event_rule
*rule
,
820 const struct lttng_log_level_rule
*log_level_rule
)
822 struct lttng_event_rule_log4j_logging
*log4j_logging
;
823 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
824 struct lttng_log_level_rule
*copy
= nullptr;
826 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
)) {
827 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
831 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
833 if (!log_level_rule_valid(log_level_rule
)) {
834 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
838 copy
= lttng_log_level_rule_copy(log_level_rule
);
839 if (copy
== nullptr) {
840 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
844 if (log4j_logging
->log_level_rule
) {
845 lttng_log_level_rule_destroy(log4j_logging
->log_level_rule
);
848 log4j_logging
->log_level_rule
= copy
;
854 enum lttng_event_rule_status
lttng_event_rule_log4j_logging_get_log_level_rule(
855 const struct lttng_event_rule
*rule
, const struct lttng_log_level_rule
**log_level_rule
)
857 struct lttng_event_rule_log4j_logging
*log4j_logging
;
858 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
860 if (!rule
|| !IS_LOG4J_LOGGING_EVENT_RULE(rule
) || !log_level_rule
) {
861 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
865 log4j_logging
= lttng::utils::container_of(rule
, <tng_event_rule_log4j_logging::parent
);
866 if (log4j_logging
->log_level_rule
== nullptr) {
867 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
871 *log_level_rule
= log4j_logging
->log_level_rule
;