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/jul-logging-internal.h>
22 #include <lttng/event.h>
23 #include <lttng/log-level-rule.h>
25 #define IS_JUL_LOGGING_EVENT_RULE(rule) \
26 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_JUL_LOGGING)
28 static void lttng_event_rule_jul_logging_destroy(struct lttng_event_rule
*rule
)
30 struct lttng_event_rule_jul_logging
*jul_logging
;
36 jul_logging
= container_of(
37 rule
, struct lttng_event_rule_jul_logging
, parent
);
39 lttng_log_level_rule_destroy(jul_logging
->log_level_rule
);
40 free(jul_logging
->pattern
);
41 free(jul_logging
->filter_expression
);
42 free(jul_logging
->internal_filter
.filter
);
43 free(jul_logging
->internal_filter
.bytecode
);
47 static bool lttng_event_rule_jul_logging_validate(
48 const struct lttng_event_rule
*rule
)
51 struct lttng_event_rule_jul_logging
*jul_logging
;
57 jul_logging
= container_of(
58 rule
, struct lttng_event_rule_jul_logging
, parent
);
61 if (!jul_logging
->pattern
) {
62 ERR("Invalid jul_logging event rule: a pattern must be set.");
71 static int lttng_event_rule_jul_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_jul_logging
*jul_logging
;
79 struct lttng_event_rule_jul_logging_comm jul_logging_comm
;
80 struct lttng_event_rule_jul_logging_comm
*header
;
82 if (!rule
|| !IS_JUL_LOGGING_EVENT_RULE(rule
)) {
87 header_offset
= payload
->buffer
.size
;
89 DBG("Serializing jul_logging event rule.");
90 jul_logging
= container_of(
91 rule
, struct lttng_event_rule_jul_logging
, parent
);
93 pattern_len
= strlen(jul_logging
->pattern
) + 1;
95 if (jul_logging
->filter_expression
!= NULL
) {
96 filter_expression_len
=
97 strlen(jul_logging
->filter_expression
) + 1;
99 filter_expression_len
= 0;
102 jul_logging_comm
.pattern_len
= pattern_len
;
103 jul_logging_comm
.filter_expression_len
= filter_expression_len
;
105 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &jul_logging_comm
,
106 sizeof(jul_logging_comm
));
111 ret
= lttng_dynamic_buffer_append(
112 &payload
->buffer
, jul_logging
->pattern
, pattern_len
);
117 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, jul_logging
->filter_expression
,
118 filter_expression_len
);
123 size_before_log_level_rule
= payload
->buffer
.size
;
125 ret
= lttng_log_level_rule_serialize(jul_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_jul_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_jul_logging
*a
, *b
;
145 a
= container_of(_a
, struct lttng_event_rule_jul_logging
, parent
);
146 b
= container_of(_b
, struct lttng_event_rule_jul_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_jul_logging_get_name_pattern(rule
, &pattern
);
202 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
207 status
= lttng_event_rule_jul_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_jul_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_jul_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_jul_logging
*jul_logging
;
301 enum lttng_event_rule_status status
;
303 struct lttng_bytecode
*bytecode
= NULL
;
308 jul_logging
= container_of(
309 rule
, struct lttng_event_rule_jul_logging
, parent
);
311 status
= lttng_event_rule_jul_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 jul_logging
->internal_filter
.filter
= agent_filter
;
332 if (jul_logging
->internal_filter
.filter
== NULL
) {
337 ret
= run_as_generate_filter_bytecode(
338 jul_logging
->internal_filter
.filter
, creds
,
341 ret_code
= LTTNG_ERR_FILTER_INVAL
;
345 jul_logging
->internal_filter
.bytecode
= bytecode
;
355 static const char *lttng_event_rule_jul_logging_get_internal_filter(
356 const struct lttng_event_rule
*rule
)
358 struct lttng_event_rule_jul_logging
*jul_logging
;
361 jul_logging
= container_of(
362 rule
, struct lttng_event_rule_jul_logging
, parent
);
363 return jul_logging
->internal_filter
.filter
;
366 static const struct lttng_bytecode
*
367 lttng_event_rule_jul_logging_get_internal_filter_bytecode(
368 const struct lttng_event_rule
*rule
)
370 struct lttng_event_rule_jul_logging
*jul_logging
;
373 jul_logging
= container_of(
374 rule
, struct lttng_event_rule_jul_logging
, parent
);
375 return jul_logging
->internal_filter
.bytecode
;
378 static enum lttng_event_rule_generate_exclusions_status
379 lttng_event_rule_jul_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_jul_logging_hash(
389 const struct lttng_event_rule
*rule
)
392 struct lttng_event_rule_jul_logging
*tp_rule
=
393 container_of(rule
, typeof(*tp_rule
), parent
);
395 hash
= hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_JUL_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_jul_logging_generate_lttng_event(
411 const struct lttng_event_rule
*rule
)
414 const struct lttng_event_rule_jul_logging
*jul_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 jul_logging
= container_of(
423 rule
, const struct lttng_event_rule_jul_logging
, parent
);
425 local_event
= zmalloc(sizeof(*local_event
));
430 local_event
->type
= LTTNG_EVENT_TRACEPOINT
;
431 ret
= lttng_strncpy(local_event
->name
, jul_logging
->pattern
,
432 sizeof(local_event
->name
));
434 ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'",
435 jul_logging
->pattern
);
440 /* Map the log level rule to an equivalent lttng_loglevel. */
441 status
= lttng_event_rule_jul_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_jul_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
;
489 const char *filter
= NULL
;
490 const char *name_pattern
= NULL
;
491 const struct lttng_log_level_rule
*log_level_rule
= NULL
;
495 assert(IS_JUL_LOGGING_EVENT_RULE(rule
));
497 status
= lttng_event_rule_jul_logging_get_name_pattern(
498 rule
, &name_pattern
);
499 assert(status
== LTTNG_EVENT_RULE_STATUS_OK
);
500 assert(name_pattern
);
502 status
= lttng_event_rule_jul_logging_get_filter(rule
, &filter
);
503 assert(status
== LTTNG_EVENT_RULE_STATUS_OK
||
504 status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
506 status
= lttng_event_rule_jul_logging_get_log_level_rule(
507 rule
, &log_level_rule
);
508 assert(status
== LTTNG_EVENT_RULE_STATUS_OK
||
509 status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
511 /* Open event rule jul logging element. */
512 ret
= mi_lttng_writer_open_element(
513 writer
, mi_lttng_element_event_rule_jul_logging
);
519 ret
= mi_lttng_writer_write_element_string(writer
,
520 mi_lttng_element_event_rule_name_pattern
, name_pattern
);
525 /* Filter expression. */
526 if (filter
!= NULL
) {
527 ret
= mi_lttng_writer_write_element_string(writer
,
528 mi_lttng_element_event_rule_filter_expression
,
535 /* Log level rule. */
536 if (log_level_rule
) {
537 ret_code
= lttng_log_level_rule_mi_serialize(
538 log_level_rule
, writer
);
539 if (ret_code
!= LTTNG_OK
) {
544 /* Close event rule jul logging element. */
545 ret
= mi_lttng_writer_close_element(writer
);
554 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
559 struct lttng_event_rule
*lttng_event_rule_jul_logging_create(void)
561 struct lttng_event_rule
*rule
= NULL
;
562 struct lttng_event_rule_jul_logging
*tp_rule
;
563 enum lttng_event_rule_status status
;
565 tp_rule
= zmalloc(sizeof(struct lttng_event_rule_jul_logging
));
570 rule
= &tp_rule
->parent
;
571 lttng_event_rule_init(&tp_rule
->parent
, LTTNG_EVENT_RULE_TYPE_JUL_LOGGING
);
572 tp_rule
->parent
.validate
= lttng_event_rule_jul_logging_validate
;
573 tp_rule
->parent
.serialize
= lttng_event_rule_jul_logging_serialize
;
574 tp_rule
->parent
.equal
= lttng_event_rule_jul_logging_is_equal
;
575 tp_rule
->parent
.destroy
= lttng_event_rule_jul_logging_destroy
;
576 tp_rule
->parent
.generate_filter_bytecode
=
577 lttng_event_rule_jul_logging_generate_filter_bytecode
;
578 tp_rule
->parent
.get_filter
=
579 lttng_event_rule_jul_logging_get_internal_filter
;
580 tp_rule
->parent
.get_filter_bytecode
=
581 lttng_event_rule_jul_logging_get_internal_filter_bytecode
;
582 tp_rule
->parent
.generate_exclusions
=
583 lttng_event_rule_jul_logging_generate_exclusions
;
584 tp_rule
->parent
.hash
= lttng_event_rule_jul_logging_hash
;
585 tp_rule
->parent
.generate_lttng_event
=
586 lttng_event_rule_jul_logging_generate_lttng_event
;
587 tp_rule
->parent
.mi_serialize
= lttng_event_rule_jul_logging_mi_serialize
;
589 tp_rule
->log_level_rule
= NULL
;
591 /* Default pattern is '*'. */
592 status
= lttng_event_rule_jul_logging_set_name_pattern(rule
, "*");
593 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
594 lttng_event_rule_destroy(rule
);
603 ssize_t
lttng_event_rule_jul_logging_create_from_payload(
604 struct lttng_payload_view
*view
,
605 struct lttng_event_rule
**_event_rule
)
607 ssize_t ret
, offset
= 0;
608 enum lttng_event_rule_status status
;
609 const struct lttng_event_rule_jul_logging_comm
*jul_logging_comm
;
611 const char *filter_expression
= NULL
;
612 struct lttng_buffer_view current_buffer_view
;
613 struct lttng_event_rule
*rule
= NULL
;
614 struct lttng_log_level_rule
*log_level_rule
= NULL
;
621 current_buffer_view
= lttng_buffer_view_from_view(
622 &view
->buffer
, offset
, sizeof(*jul_logging_comm
));
623 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
624 ERR("Failed to initialize from malformed event rule jul_logging: buffer too short to contain header.");
629 jul_logging_comm
= (typeof(jul_logging_comm
)) current_buffer_view
.data
;
631 rule
= lttng_event_rule_jul_logging_create();
633 ERR("Failed to create event rule jul_logging.");
638 /* Skip to payload. */
639 offset
+= current_buffer_view
.size
;
641 /* Map the pattern. */
642 current_buffer_view
= lttng_buffer_view_from_view(
643 &view
->buffer
, offset
, jul_logging_comm
->pattern_len
);
645 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
650 pattern
= current_buffer_view
.data
;
651 if (!lttng_buffer_view_contains_string(¤t_buffer_view
, pattern
,
652 jul_logging_comm
->pattern_len
)) {
657 /* Skip after the pattern. */
658 offset
+= jul_logging_comm
->pattern_len
;
660 if (!jul_logging_comm
->filter_expression_len
) {
661 goto skip_filter_expression
;
664 /* Map the filter_expression. */
665 current_buffer_view
= lttng_buffer_view_from_view(&view
->buffer
, offset
,
666 jul_logging_comm
->filter_expression_len
);
667 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
672 filter_expression
= current_buffer_view
.data
;
673 if (!lttng_buffer_view_contains_string(¤t_buffer_view
,
675 jul_logging_comm
->filter_expression_len
)) {
680 /* Skip after the pattern. */
681 offset
+= jul_logging_comm
->filter_expression_len
;
683 skip_filter_expression
:
684 if (!jul_logging_comm
->log_level_rule_len
) {
685 goto skip_log_level_rule
;
689 /* Map the log level rule. */
690 struct lttng_payload_view current_payload_view
=
691 lttng_payload_view_from_view(view
, offset
,
692 jul_logging_comm
->log_level_rule_len
);
694 ret
= lttng_log_level_rule_create_from_payload(
695 ¤t_payload_view
, &log_level_rule
);
701 assert(ret
== jul_logging_comm
->log_level_rule_len
);
704 /* Skip after the log level rule. */
705 offset
+= jul_logging_comm
->log_level_rule_len
;
709 status
= lttng_event_rule_jul_logging_set_name_pattern(rule
, pattern
);
710 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
711 ERR("Failed to set event rule jul_logging pattern.");
716 if (filter_expression
) {
717 status
= lttng_event_rule_jul_logging_set_filter(
718 rule
, filter_expression
);
719 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
720 ERR("Failed to set event rule jul_logging pattern.");
726 if (log_level_rule
) {
727 status
= lttng_event_rule_jul_logging_set_log_level_rule(
728 rule
, log_level_rule
);
729 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
730 ERR("Failed to set event rule jul_logging log level rule.");
740 lttng_log_level_rule_destroy(log_level_rule
);
741 lttng_event_rule_destroy(rule
);
745 enum lttng_event_rule_status
lttng_event_rule_jul_logging_set_name_pattern(
746 struct lttng_event_rule
*rule
, const char *pattern
)
748 char *pattern_copy
= NULL
;
749 struct lttng_event_rule_jul_logging
*jul_logging
;
750 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
752 if (!rule
|| !IS_JUL_LOGGING_EVENT_RULE(rule
) || !pattern
||
753 strlen(pattern
) == 0) {
754 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
758 jul_logging
= container_of(
759 rule
, struct lttng_event_rule_jul_logging
, parent
);
760 pattern_copy
= strdup(pattern
);
762 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
766 /* Normalize the pattern. */
767 strutils_normalize_star_glob_pattern(pattern_copy
);
769 free(jul_logging
->pattern
);
771 jul_logging
->pattern
= pattern_copy
;
777 enum lttng_event_rule_status
lttng_event_rule_jul_logging_get_name_pattern(
778 const struct lttng_event_rule
*rule
, const char **pattern
)
780 struct lttng_event_rule_jul_logging
*jul_logging
;
781 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
783 if (!rule
|| !IS_JUL_LOGGING_EVENT_RULE(rule
) || !pattern
) {
784 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
788 jul_logging
= container_of(
789 rule
, struct lttng_event_rule_jul_logging
, parent
);
790 if (!jul_logging
->pattern
) {
791 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
795 *pattern
= jul_logging
->pattern
;
800 enum lttng_event_rule_status
lttng_event_rule_jul_logging_set_filter(
801 struct lttng_event_rule
*rule
, const char *expression
)
803 char *expression_copy
= NULL
;
804 struct lttng_event_rule_jul_logging
*jul_logging
;
805 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
807 if (!rule
|| !IS_JUL_LOGGING_EVENT_RULE(rule
) || !expression
||
808 strlen(expression
) == 0) {
809 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
813 jul_logging
= container_of(
814 rule
, struct lttng_event_rule_jul_logging
, parent
);
815 expression_copy
= strdup(expression
);
816 if (!expression_copy
) {
817 PERROR("Failed to copy filter expression");
818 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
822 if (jul_logging
->filter_expression
) {
823 free(jul_logging
->filter_expression
);
826 jul_logging
->filter_expression
= expression_copy
;
827 expression_copy
= NULL
;
832 enum lttng_event_rule_status
lttng_event_rule_jul_logging_get_filter(
833 const struct lttng_event_rule
*rule
, const char **expression
)
835 struct lttng_event_rule_jul_logging
*jul_logging
;
836 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
838 if (!rule
|| !IS_JUL_LOGGING_EVENT_RULE(rule
) || !expression
) {
839 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
843 jul_logging
= container_of(
844 rule
, struct lttng_event_rule_jul_logging
, parent
);
845 if (!jul_logging
->filter_expression
) {
846 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
850 *expression
= jul_logging
->filter_expression
;
855 static bool log_level_rule_valid(const struct lttng_log_level_rule
*rule
)
858 * For both JUL and LOG4J custom log level are possible and can
859 * span the entire int32 range.
864 enum lttng_event_rule_status
lttng_event_rule_jul_logging_set_log_level_rule(
865 struct lttng_event_rule
*rule
,
866 const struct lttng_log_level_rule
*log_level_rule
)
868 struct lttng_event_rule_jul_logging
*jul_logging
;
869 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
870 struct lttng_log_level_rule
*copy
= NULL
;
872 if (!rule
|| !IS_JUL_LOGGING_EVENT_RULE(rule
)) {
873 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
877 jul_logging
= container_of(
878 rule
, struct lttng_event_rule_jul_logging
, parent
);
880 if (!log_level_rule_valid(log_level_rule
)) {
881 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
885 copy
= lttng_log_level_rule_copy(log_level_rule
);
887 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
891 if (jul_logging
->log_level_rule
) {
892 lttng_log_level_rule_destroy(jul_logging
->log_level_rule
);
895 jul_logging
->log_level_rule
= copy
;
901 enum lttng_event_rule_status
lttng_event_rule_jul_logging_get_log_level_rule(
902 const struct lttng_event_rule
*rule
,
903 const struct lttng_log_level_rule
**log_level_rule
906 struct lttng_event_rule_jul_logging
*jul_logging
;
907 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
909 if (!rule
|| !IS_JUL_LOGGING_EVENT_RULE(rule
) || !log_level_rule
) {
910 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
914 jul_logging
= container_of(
915 rule
, struct lttng_event_rule_jul_logging
, parent
);
916 if (jul_logging
->log_level_rule
== NULL
) {
917 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
921 *log_level_rule
= jul_logging
->log_level_rule
;