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>
19 #include <lttng/event-rule/event-rule-internal.hpp>
20 #include <lttng/event-rule/python-logging-internal.hpp>
21 #include <lttng/event.h>
22 #include <lttng/log-level-rule.h>
24 #define IS_PYTHON_LOGGING_EVENT_RULE(rule) \
25 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING)
27 static void lttng_event_rule_python_logging_destroy(struct lttng_event_rule
*rule
)
29 struct lttng_event_rule_python_logging
*python_logging
;
35 python_logging
= container_of(
36 rule
, struct lttng_event_rule_python_logging
, parent
);
38 lttng_log_level_rule_destroy(python_logging
->log_level_rule
);
39 free(python_logging
->pattern
);
40 free(python_logging
->filter_expression
);
41 free(python_logging
->internal_filter
.filter
);
42 free(python_logging
->internal_filter
.bytecode
);
46 static bool lttng_event_rule_python_logging_validate(
47 const struct lttng_event_rule
*rule
)
50 struct lttng_event_rule_python_logging
*python_logging
;
56 python_logging
= container_of(
57 rule
, struct lttng_event_rule_python_logging
, parent
);
60 if (!python_logging
->pattern
) {
61 ERR("Invalid python_logging event rule: a pattern must be set.");
70 static int lttng_event_rule_python_logging_serialize(
71 const struct lttng_event_rule
*rule
,
72 struct lttng_payload
*payload
)
75 size_t pattern_len
, filter_expression_len
, header_offset
;
76 size_t size_before_log_level_rule
;
77 struct lttng_event_rule_python_logging
*python_logging
;
78 struct lttng_event_rule_python_logging_comm python_logging_comm
;
79 struct lttng_event_rule_python_logging_comm
*header
;
81 if (!rule
|| !IS_PYTHON_LOGGING_EVENT_RULE(rule
)) {
86 header_offset
= payload
->buffer
.size
;
88 DBG("Serializing python_logging event rule.");
89 python_logging
= container_of(
90 rule
, struct lttng_event_rule_python_logging
, parent
);
92 pattern_len
= strlen(python_logging
->pattern
) + 1;
94 if (python_logging
->filter_expression
!= NULL
) {
95 filter_expression_len
=
96 strlen(python_logging
->filter_expression
) + 1;
98 filter_expression_len
= 0;
101 python_logging_comm
.pattern_len
= pattern_len
;
102 python_logging_comm
.filter_expression_len
= filter_expression_len
;
104 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &python_logging_comm
,
105 sizeof(python_logging_comm
));
110 ret
= lttng_dynamic_buffer_append(
111 &payload
->buffer
, python_logging
->pattern
, pattern_len
);
116 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, python_logging
->filter_expression
,
117 filter_expression_len
);
122 size_before_log_level_rule
= payload
->buffer
.size
;
124 ret
= lttng_log_level_rule_serialize(python_logging
->log_level_rule
, payload
);
129 header
= (typeof(header
)) ((char *) payload
->buffer
.data
+ header_offset
);
130 header
->log_level_rule_len
=
131 payload
->buffer
.size
- size_before_log_level_rule
;
137 static bool lttng_event_rule_python_logging_is_equal(
138 const struct lttng_event_rule
*_a
,
139 const struct lttng_event_rule
*_b
)
141 bool is_equal
= false;
142 struct lttng_event_rule_python_logging
*a
, *b
;
144 a
= container_of(_a
, struct lttng_event_rule_python_logging
, parent
);
145 b
= container_of(_b
, struct lttng_event_rule_python_logging
, parent
);
149 if (!!a
->filter_expression
!= !!b
->filter_expression
) {
154 LTTNG_ASSERT(a
->pattern
);
155 LTTNG_ASSERT(b
->pattern
);
156 if (strcmp(a
->pattern
, b
->pattern
)) {
160 if (a
->filter_expression
&& b
->filter_expression
) {
161 if (strcmp(a
->filter_expression
, b
->filter_expression
)) {
164 } else if (!!a
->filter_expression
!= !!b
->filter_expression
) {
165 /* One is set; not the other. */
169 if (!lttng_log_level_rule_is_equal(
170 a
->log_level_rule
, b
->log_level_rule
)) {
180 * On success ret is 0;
182 * On error ret is negative.
184 * An event with NO loglevel and the name is * will return NULL.
186 static int generate_agent_filter(
187 const struct lttng_event_rule
*rule
, char **_agent_filter
)
191 char *agent_filter
= NULL
;
194 const struct lttng_log_level_rule
*log_level_rule
= NULL
;
195 enum lttng_event_rule_status status
;
198 LTTNG_ASSERT(_agent_filter
);
200 status
= lttng_event_rule_python_logging_get_name_pattern(rule
, &pattern
);
201 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
206 status
= lttng_event_rule_python_logging_get_filter(rule
, &filter
);
207 if (status
== LTTNG_EVENT_RULE_STATUS_UNSET
) {
209 } else if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
215 /* Don't add filter for the '*' event. */
216 if (strcmp(pattern
, "*") != 0) {
218 err
= asprintf(&agent_filter
,
219 "(%s) && (logger_name == \"%s\")",
222 err
= asprintf(&agent_filter
, "logger_name == \"%s\"",
227 PERROR("Failed to format agent filter string");
233 status
= lttng_event_rule_python_logging_get_log_level_rule(
234 rule
, &log_level_rule
);
235 if (status
== LTTNG_EVENT_RULE_STATUS_OK
) {
236 enum lttng_log_level_rule_status llr_status
;
240 switch (lttng_log_level_rule_get_type(log_level_rule
))
242 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
243 llr_status
= lttng_log_level_rule_exactly_get_level(
244 log_level_rule
, &level
);
247 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
248 llr_status
= lttng_log_level_rule_at_least_as_severe_as_get_level(
249 log_level_rule
, &level
);
256 if (llr_status
!= LTTNG_LOG_LEVEL_RULE_STATUS_OK
) {
261 if (filter
|| agent_filter
) {
264 err
= asprintf(&new_filter
,
265 "(%s) && (int_loglevel %s %d)",
266 agent_filter
? agent_filter
: filter
,
271 agent_filter
= new_filter
;
273 err
= asprintf(&agent_filter
, "int_loglevel %s %d", op
,
278 PERROR("Failed to format agent filter string");
284 *_agent_filter
= agent_filter
;
292 static enum lttng_error_code
293 lttng_event_rule_python_logging_generate_filter_bytecode(
294 struct lttng_event_rule
*rule
,
295 const struct lttng_credentials
*creds
)
298 enum lttng_error_code ret_code
;
299 struct lttng_event_rule_python_logging
*python_logging
;
300 enum lttng_event_rule_status status
;
302 struct lttng_bytecode
*bytecode
= NULL
;
307 python_logging
= container_of(
308 rule
, struct lttng_event_rule_python_logging
, parent
);
310 status
= lttng_event_rule_python_logging_get_filter(rule
, &filter
);
311 if (status
== LTTNG_EVENT_RULE_STATUS_UNSET
) {
313 } else if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
314 ret_code
= LTTNG_ERR_FILTER_INVAL
;
318 if (filter
&& filter
[0] == '\0') {
319 ret_code
= LTTNG_ERR_FILTER_INVAL
;
323 ret
= generate_agent_filter(rule
, &agent_filter
);
325 ret_code
= LTTNG_ERR_FILTER_INVAL
;
329 python_logging
->internal_filter
.filter
= agent_filter
;
331 if (python_logging
->internal_filter
.filter
== NULL
) {
336 ret
= run_as_generate_filter_bytecode(
337 python_logging
->internal_filter
.filter
, creds
,
340 ret_code
= LTTNG_ERR_FILTER_INVAL
;
344 python_logging
->internal_filter
.bytecode
= bytecode
;
354 static const char *lttng_event_rule_python_logging_get_internal_filter(
355 const struct lttng_event_rule
*rule
)
357 struct lttng_event_rule_python_logging
*python_logging
;
360 python_logging
= container_of(
361 rule
, struct lttng_event_rule_python_logging
, parent
);
362 return python_logging
->internal_filter
.filter
;
365 static const struct lttng_bytecode
*
366 lttng_event_rule_python_logging_get_internal_filter_bytecode(
367 const struct lttng_event_rule
*rule
)
369 struct lttng_event_rule_python_logging
*python_logging
;
372 python_logging
= container_of(
373 rule
, struct lttng_event_rule_python_logging
, parent
);
374 return python_logging
->internal_filter
.bytecode
;
377 static enum lttng_event_rule_generate_exclusions_status
378 lttng_event_rule_python_logging_generate_exclusions(
379 const struct lttng_event_rule
*rule
__attribute__((unused
)),
380 struct lttng_event_exclusion
**_exclusions
)
384 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE
;
387 static unsigned long lttng_event_rule_python_logging_hash(
388 const struct lttng_event_rule
*rule
)
391 struct lttng_event_rule_python_logging
*tp_rule
=
392 container_of(rule
, typeof(*tp_rule
), parent
);
394 hash
= hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING
,
396 hash
^= hash_key_str(tp_rule
->pattern
, lttng_ht_seed
);
398 if (tp_rule
->filter_expression
) {
399 hash
^= hash_key_str(tp_rule
->filter_expression
, lttng_ht_seed
);
402 if (tp_rule
->log_level_rule
) {
403 hash
^= lttng_log_level_rule_hash(tp_rule
->log_level_rule
);
409 static struct lttng_event
*lttng_event_rule_python_logging_generate_lttng_event(
410 const struct lttng_event_rule
*rule
)
413 const struct lttng_event_rule_python_logging
*python_logging
;
414 struct lttng_event
*local_event
= NULL
;
415 struct lttng_event
*event
= NULL
;
416 enum lttng_loglevel_type loglevel_type
;
417 int loglevel_value
= 0;
418 enum lttng_event_rule_status status
;
419 const struct lttng_log_level_rule
*log_level_rule
;
421 python_logging
= container_of(
422 rule
, const struct lttng_event_rule_python_logging
, parent
);
424 local_event
= (lttng_event
*) zmalloc(sizeof(*local_event
));
429 local_event
->type
= LTTNG_EVENT_TRACEPOINT
;
430 ret
= lttng_strncpy(local_event
->name
, python_logging
->pattern
,
431 sizeof(local_event
->name
));
433 ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'",
434 python_logging
->pattern
);
439 /* Map the log level rule to an equivalent lttng_loglevel. */
440 status
= lttng_event_rule_python_logging_get_log_level_rule(
441 rule
, &log_level_rule
);
442 if (status
== LTTNG_EVENT_RULE_STATUS_UNSET
) {
443 loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
445 } else if (status
== LTTNG_EVENT_RULE_STATUS_OK
) {
446 enum lttng_log_level_rule_status llr_status
;
448 switch (lttng_log_level_rule_get_type(log_level_rule
)) {
449 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
450 llr_status
= lttng_log_level_rule_exactly_get_level(
451 log_level_rule
, &loglevel_value
);
452 loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
454 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
455 llr_status
= lttng_log_level_rule_at_least_as_severe_as_get_level(
456 log_level_rule
, &loglevel_value
);
457 loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
464 if (llr_status
!= LTTNG_LOG_LEVEL_RULE_STATUS_OK
) {
471 local_event
->loglevel_type
= loglevel_type
;
472 local_event
->loglevel
= loglevel_value
;
481 static enum lttng_error_code
lttng_event_rule_python_logging_mi_serialize(
482 const struct lttng_event_rule
*rule
, struct mi_writer
*writer
)
485 enum lttng_error_code ret_code
;
486 enum lttng_event_rule_status status
;
487 const char *filter
= NULL
;
488 const char *name_pattern
= NULL
;
489 const struct lttng_log_level_rule
*log_level_rule
= NULL
;
492 LTTNG_ASSERT(writer
);
493 LTTNG_ASSERT(IS_PYTHON_LOGGING_EVENT_RULE(rule
));
495 status
= lttng_event_rule_python_logging_get_name_pattern(
496 rule
, &name_pattern
);
497 LTTNG_ASSERT(status
== LTTNG_EVENT_RULE_STATUS_OK
);
498 LTTNG_ASSERT(name_pattern
);
500 status
= lttng_event_rule_python_logging_get_filter(rule
, &filter
);
501 LTTNG_ASSERT(status
== LTTNG_EVENT_RULE_STATUS_OK
||
502 status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
504 status
= lttng_event_rule_python_logging_get_log_level_rule(
505 rule
, &log_level_rule
);
506 LTTNG_ASSERT(status
== LTTNG_EVENT_RULE_STATUS_OK
||
507 status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
509 /* Open event rule python logging element. */
510 ret
= mi_lttng_writer_open_element(
511 writer
, mi_lttng_element_event_rule_python_logging
);
517 ret
= mi_lttng_writer_write_element_string(writer
,
518 mi_lttng_element_event_rule_name_pattern
, name_pattern
);
523 /* Filter expression. */
524 if (filter
!= NULL
) {
525 ret
= mi_lttng_writer_write_element_string(writer
,
526 mi_lttng_element_event_rule_filter_expression
,
533 /* Log level rule. */
534 if (log_level_rule
) {
535 ret_code
= lttng_log_level_rule_mi_serialize(
536 log_level_rule
, writer
);
537 if (ret_code
!= LTTNG_OK
) {
542 /* Close event rule python logging element. */
543 ret
= mi_lttng_writer_close_element(writer
);
552 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
557 struct lttng_event_rule
*lttng_event_rule_python_logging_create(void)
559 struct lttng_event_rule
*rule
= NULL
;
560 struct lttng_event_rule_python_logging
*tp_rule
;
561 enum lttng_event_rule_status status
;
563 tp_rule
= (lttng_event_rule_python_logging
*) zmalloc(sizeof(struct lttng_event_rule_python_logging
));
568 rule
= &tp_rule
->parent
;
569 lttng_event_rule_init(&tp_rule
->parent
, LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING
);
570 tp_rule
->parent
.validate
= lttng_event_rule_python_logging_validate
;
571 tp_rule
->parent
.serialize
= lttng_event_rule_python_logging_serialize
;
572 tp_rule
->parent
.equal
= lttng_event_rule_python_logging_is_equal
;
573 tp_rule
->parent
.destroy
= lttng_event_rule_python_logging_destroy
;
574 tp_rule
->parent
.generate_filter_bytecode
=
575 lttng_event_rule_python_logging_generate_filter_bytecode
;
576 tp_rule
->parent
.get_filter
=
577 lttng_event_rule_python_logging_get_internal_filter
;
578 tp_rule
->parent
.get_filter_bytecode
=
579 lttng_event_rule_python_logging_get_internal_filter_bytecode
;
580 tp_rule
->parent
.generate_exclusions
=
581 lttng_event_rule_python_logging_generate_exclusions
;
582 tp_rule
->parent
.hash
= lttng_event_rule_python_logging_hash
;
583 tp_rule
->parent
.generate_lttng_event
=
584 lttng_event_rule_python_logging_generate_lttng_event
;
585 tp_rule
->parent
.mi_serialize
= lttng_event_rule_python_logging_mi_serialize
;
587 tp_rule
->log_level_rule
= NULL
;
589 /* Default pattern is '*'. */
590 status
= lttng_event_rule_python_logging_set_name_pattern(rule
, "*");
591 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
592 lttng_event_rule_destroy(rule
);
600 ssize_t
lttng_event_rule_python_logging_create_from_payload(
601 struct lttng_payload_view
*view
,
602 struct lttng_event_rule
**_event_rule
)
604 ssize_t ret
, offset
= 0;
605 enum lttng_event_rule_status status
;
606 const struct lttng_event_rule_python_logging_comm
*python_logging_comm
;
608 const char *filter_expression
= NULL
;
609 struct lttng_buffer_view current_buffer_view
;
610 struct lttng_event_rule
*rule
= NULL
;
611 struct lttng_log_level_rule
*log_level_rule
= NULL
;
618 current_buffer_view
= lttng_buffer_view_from_view(
619 &view
->buffer
, offset
, sizeof(*python_logging_comm
));
620 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
621 ERR("Failed to initialize from malformed event rule python_logging: buffer too short to contain header.");
626 python_logging_comm
= (typeof(python_logging_comm
)) current_buffer_view
.data
;
628 rule
= lttng_event_rule_python_logging_create();
630 ERR("Failed to create event rule python_logging.");
635 /* Skip to payload. */
636 offset
+= current_buffer_view
.size
;
638 /* Map the pattern. */
639 current_buffer_view
= lttng_buffer_view_from_view(
640 &view
->buffer
, offset
, python_logging_comm
->pattern_len
);
642 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
647 pattern
= current_buffer_view
.data
;
648 if (!lttng_buffer_view_contains_string(¤t_buffer_view
, pattern
,
649 python_logging_comm
->pattern_len
)) {
654 /* Skip after the pattern. */
655 offset
+= python_logging_comm
->pattern_len
;
657 if (!python_logging_comm
->filter_expression_len
) {
658 goto skip_filter_expression
;
661 /* Map the filter_expression. */
662 current_buffer_view
= lttng_buffer_view_from_view(&view
->buffer
, offset
,
663 python_logging_comm
->filter_expression_len
);
664 if (!lttng_buffer_view_is_valid(¤t_buffer_view
)) {
669 filter_expression
= current_buffer_view
.data
;
670 if (!lttng_buffer_view_contains_string(¤t_buffer_view
,
672 python_logging_comm
->filter_expression_len
)) {
677 /* Skip after the pattern. */
678 offset
+= python_logging_comm
->filter_expression_len
;
680 skip_filter_expression
:
681 if (!python_logging_comm
->log_level_rule_len
) {
682 goto skip_log_level_rule
;
686 /* Map the log level rule. */
687 struct lttng_payload_view current_payload_view
=
688 lttng_payload_view_from_view(view
, offset
,
689 python_logging_comm
->log_level_rule_len
);
691 ret
= lttng_log_level_rule_create_from_payload(
692 ¤t_payload_view
, &log_level_rule
);
698 LTTNG_ASSERT(ret
== python_logging_comm
->log_level_rule_len
);
701 /* Skip after the log level rule. */
702 offset
+= python_logging_comm
->log_level_rule_len
;
706 status
= lttng_event_rule_python_logging_set_name_pattern(rule
, pattern
);
707 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
708 ERR("Failed to set event rule python_logging pattern.");
713 if (filter_expression
) {
714 status
= lttng_event_rule_python_logging_set_filter(
715 rule
, filter_expression
);
716 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
717 ERR("Failed to set event rule python_logging pattern.");
723 if (log_level_rule
) {
724 status
= lttng_event_rule_python_logging_set_log_level_rule(
725 rule
, log_level_rule
);
726 if (status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
727 ERR("Failed to set event rule python_logging log level rule.");
737 lttng_log_level_rule_destroy(log_level_rule
);
738 lttng_event_rule_destroy(rule
);
742 enum lttng_event_rule_status
lttng_event_rule_python_logging_set_name_pattern(
743 struct lttng_event_rule
*rule
, const char *pattern
)
745 char *pattern_copy
= NULL
;
746 struct lttng_event_rule_python_logging
*python_logging
;
747 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
749 if (!rule
|| !IS_PYTHON_LOGGING_EVENT_RULE(rule
) || !pattern
||
750 strlen(pattern
) == 0) {
751 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
755 python_logging
= container_of(
756 rule
, struct lttng_event_rule_python_logging
, parent
);
757 pattern_copy
= strdup(pattern
);
759 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
763 /* Normalize the pattern. */
764 strutils_normalize_star_glob_pattern(pattern_copy
);
766 free(python_logging
->pattern
);
768 python_logging
->pattern
= pattern_copy
;
774 enum lttng_event_rule_status
lttng_event_rule_python_logging_get_name_pattern(
775 const struct lttng_event_rule
*rule
, const char **pattern
)
777 struct lttng_event_rule_python_logging
*python_logging
;
778 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
780 if (!rule
|| !IS_PYTHON_LOGGING_EVENT_RULE(rule
) || !pattern
) {
781 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
785 python_logging
= container_of(
786 rule
, struct lttng_event_rule_python_logging
, parent
);
787 if (!python_logging
->pattern
) {
788 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
792 *pattern
= python_logging
->pattern
;
797 enum lttng_event_rule_status
lttng_event_rule_python_logging_set_filter(
798 struct lttng_event_rule
*rule
, const char *expression
)
800 char *expression_copy
= NULL
;
801 struct lttng_event_rule_python_logging
*python_logging
;
802 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
804 if (!rule
|| !IS_PYTHON_LOGGING_EVENT_RULE(rule
) || !expression
||
805 strlen(expression
) == 0) {
806 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
810 python_logging
= container_of(
811 rule
, struct lttng_event_rule_python_logging
, parent
);
812 expression_copy
= strdup(expression
);
813 if (!expression_copy
) {
814 PERROR("Failed to copy filter expression");
815 status
= LTTNG_EVENT_RULE_STATUS_ERROR
;
819 if (python_logging
->filter_expression
) {
820 free(python_logging
->filter_expression
);
823 python_logging
->filter_expression
= expression_copy
;
824 expression_copy
= NULL
;
829 enum lttng_event_rule_status
lttng_event_rule_python_logging_get_filter(
830 const struct lttng_event_rule
*rule
, const char **expression
)
832 struct lttng_event_rule_python_logging
*python_logging
;
833 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
835 if (!rule
|| !IS_PYTHON_LOGGING_EVENT_RULE(rule
) || !expression
) {
836 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
840 python_logging
= container_of(
841 rule
, struct lttng_event_rule_python_logging
, parent
);
842 if (!python_logging
->filter_expression
) {
843 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
847 *expression
= python_logging
->filter_expression
;
852 static bool log_level_rule_valid(
853 const struct lttng_log_level_rule
*rule
__attribute__((unused
)))
856 * For python, custom log level are possible, it is not clear if
857 * negative value are accepted (NOTSET == 0) but the source code
858 * validates against the int type implying that negative values
864 enum lttng_event_rule_status
lttng_event_rule_python_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_python_logging
*python_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_PYTHON_LOGGING_EVENT_RULE(rule
)) {
873 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
877 python_logging
= container_of(
878 rule
, struct lttng_event_rule_python_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 (python_logging
->log_level_rule
) {
892 lttng_log_level_rule_destroy(python_logging
->log_level_rule
);
895 python_logging
->log_level_rule
= copy
;
901 enum lttng_event_rule_status
lttng_event_rule_python_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_python_logging
*python_logging
;
907 enum lttng_event_rule_status status
= LTTNG_EVENT_RULE_STATUS_OK
;
909 if (!rule
|| !IS_PYTHON_LOGGING_EVENT_RULE(rule
) || !log_level_rule
) {
910 status
= LTTNG_EVENT_RULE_STATUS_INVALID
;
914 python_logging
= container_of(
915 rule
, struct lttng_event_rule_python_logging
, parent
);
916 if (python_logging
->log_level_rule
== NULL
) {
917 status
= LTTNG_EVENT_RULE_STATUS_UNSET
;
921 *log_level_rule
= python_logging
->log_level_rule
;