Run clang-format on the whole tree
[lttng-tools.git] / src / common / event-rule / python-logging.cpp
CommitLineData
6530ec7d
JR
1/*
2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
c9e313bc
SM
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>
28ab034a 19
c9e313bc
SM
20#include <lttng/event-rule/event-rule-internal.hpp>
21#include <lttng/event-rule/python-logging-internal.hpp>
6530ec7d 22#include <lttng/event.h>
6a751b95 23#include <lttng/log-level-rule.h>
6530ec7d
JR
24
25#define IS_PYTHON_LOGGING_EVENT_RULE(rule) \
26 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING)
27
28static void lttng_event_rule_python_logging_destroy(struct lttng_event_rule *rule)
29{
30 struct lttng_event_rule_python_logging *python_logging;
31
32 if (rule == NULL) {
33 return;
34 }
35
28ab034a 36 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
37
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);
43 free(python_logging);
44}
45
28ab034a 46static bool lttng_event_rule_python_logging_validate(const struct lttng_event_rule *rule)
6530ec7d
JR
47{
48 bool valid = false;
49 struct lttng_event_rule_python_logging *python_logging;
50
51 if (!rule) {
52 goto end;
53 }
54
28ab034a 55 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
56
57 /* Required field. */
58 if (!python_logging->pattern) {
59 ERR("Invalid python_logging event rule: a pattern must be set.");
60 goto end;
61 }
62
63 valid = true;
64end:
65 return valid;
66}
67
28ab034a
JG
68static int lttng_event_rule_python_logging_serialize(const struct lttng_event_rule *rule,
69 struct lttng_payload *payload)
6530ec7d
JR
70{
71 int ret;
72 size_t pattern_len, filter_expression_len, header_offset;
73 size_t size_before_log_level_rule;
74 struct lttng_event_rule_python_logging *python_logging;
75 struct lttng_event_rule_python_logging_comm python_logging_comm;
76 struct lttng_event_rule_python_logging_comm *header;
77
78 if (!rule || !IS_PYTHON_LOGGING_EVENT_RULE(rule)) {
79 ret = -1;
80 goto end;
81 }
82
83 header_offset = payload->buffer.size;
84
85 DBG("Serializing python_logging event rule.");
28ab034a 86 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
87
88 pattern_len = strlen(python_logging->pattern) + 1;
89
90 if (python_logging->filter_expression != NULL) {
28ab034a 91 filter_expression_len = strlen(python_logging->filter_expression) + 1;
6530ec7d
JR
92 } else {
93 filter_expression_len = 0;
94 }
95
96 python_logging_comm.pattern_len = pattern_len;
97 python_logging_comm.filter_expression_len = filter_expression_len;
98
28ab034a
JG
99 ret = lttng_dynamic_buffer_append(
100 &payload->buffer, &python_logging_comm, sizeof(python_logging_comm));
6530ec7d
JR
101 if (ret) {
102 goto end;
103 }
104
28ab034a 105 ret = lttng_dynamic_buffer_append(&payload->buffer, python_logging->pattern, pattern_len);
6530ec7d
JR
106 if (ret) {
107 goto end;
108 }
109
28ab034a
JG
110 ret = lttng_dynamic_buffer_append(
111 &payload->buffer, python_logging->filter_expression, filter_expression_len);
6530ec7d
JR
112 if (ret) {
113 goto end;
114 }
115
116 size_before_log_level_rule = payload->buffer.size;
117
118 ret = lttng_log_level_rule_serialize(python_logging->log_level_rule, payload);
119 if (ret < 0) {
120 goto end;
121 }
122
123 header = (typeof(header)) ((char *) payload->buffer.data + header_offset);
28ab034a 124 header->log_level_rule_len = payload->buffer.size - size_before_log_level_rule;
6530ec7d
JR
125
126end:
127 return ret;
128}
129
28ab034a
JG
130static bool lttng_event_rule_python_logging_is_equal(const struct lttng_event_rule *_a,
131 const struct lttng_event_rule *_b)
6530ec7d
JR
132{
133 bool is_equal = false;
134 struct lttng_event_rule_python_logging *a, *b;
135
0114db0e
JG
136 a = lttng::utils::container_of(_a, &lttng_event_rule_python_logging::parent);
137 b = lttng::utils::container_of(_b, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
138
139 /* Quick checks. */
140
141 if (!!a->filter_expression != !!b->filter_expression) {
142 goto end;
143 }
144
145 /* Long check. */
a0377dfe
FD
146 LTTNG_ASSERT(a->pattern);
147 LTTNG_ASSERT(b->pattern);
6530ec7d
JR
148 if (strcmp(a->pattern, b->pattern)) {
149 goto end;
150 }
151
152 if (a->filter_expression && b->filter_expression) {
153 if (strcmp(a->filter_expression, b->filter_expression)) {
154 goto end;
155 }
156 } else if (!!a->filter_expression != !!b->filter_expression) {
157 /* One is set; not the other. */
158 goto end;
159 }
160
28ab034a 161 if (!lttng_log_level_rule_is_equal(a->log_level_rule, b->log_level_rule)) {
6530ec7d
JR
162 goto end;
163 }
164
165 is_equal = true;
166end:
167 return is_equal;
168}
169
170/*
171 * On success ret is 0;
172 *
173 * On error ret is negative.
174 *
175 * An event with NO loglevel and the name is * will return NULL.
176 */
28ab034a 177static int generate_agent_filter(const struct lttng_event_rule *rule, char **_agent_filter)
6530ec7d
JR
178{
179 int err;
180 int ret = 0;
181 char *agent_filter = NULL;
182 const char *pattern;
183 const char *filter;
184 const struct lttng_log_level_rule *log_level_rule = NULL;
185 enum lttng_event_rule_status status;
186
a0377dfe
FD
187 LTTNG_ASSERT(rule);
188 LTTNG_ASSERT(_agent_filter);
6530ec7d
JR
189
190 status = lttng_event_rule_python_logging_get_name_pattern(rule, &pattern);
191 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
192 ret = -1;
193 goto end;
194 }
195
196 status = lttng_event_rule_python_logging_get_filter(rule, &filter);
197 if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
198 filter = NULL;
199 } else if (status != LTTNG_EVENT_RULE_STATUS_OK) {
200 ret = -1;
201 goto end;
202 }
203
6530ec7d
JR
204 /* Don't add filter for the '*' event. */
205 if (strcmp(pattern, "*") != 0) {
206 if (filter) {
28ab034a
JG
207 err = asprintf(
208 &agent_filter, "(%s) && (logger_name == \"%s\")", filter, pattern);
6530ec7d 209 } else {
28ab034a 210 err = asprintf(&agent_filter, "logger_name == \"%s\"", pattern);
6530ec7d
JR
211 }
212
213 if (err < 0) {
214 PERROR("Failed to format agent filter string");
215 ret = -1;
216 goto end;
217 }
218 }
219
28ab034a 220 status = lttng_event_rule_python_logging_get_log_level_rule(rule, &log_level_rule);
6530ec7d
JR
221 if (status == LTTNG_EVENT_RULE_STATUS_OK) {
222 enum lttng_log_level_rule_status llr_status;
223 const char *op;
224 int level;
225
28ab034a 226 switch (lttng_log_level_rule_get_type(log_level_rule)) {
6530ec7d 227 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
28ab034a 228 llr_status = lttng_log_level_rule_exactly_get_level(log_level_rule, &level);
6530ec7d
JR
229 op = "==";
230 break;
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(
28ab034a 233 log_level_rule, &level);
6530ec7d
JR
234 op = ">=";
235 break;
236 default:
237 abort();
238 }
239
240 if (llr_status != LTTNG_LOG_LEVEL_RULE_STATUS_OK) {
241 ret = -1;
242 goto end;
243 }
244
245 if (filter || agent_filter) {
246 char *new_filter;
247
248 err = asprintf(&new_filter,
28ab034a
JG
249 "(%s) && (int_loglevel %s %d)",
250 agent_filter ? agent_filter : filter,
251 op,
252 level);
6530ec7d
JR
253 if (agent_filter) {
254 free(agent_filter);
255 }
256 agent_filter = new_filter;
257 } else {
28ab034a 258 err = asprintf(&agent_filter, "int_loglevel %s %d", op, level);
6530ec7d
JR
259 }
260
261 if (err < 0) {
262 PERROR("Failed to format agent filter string");
263 ret = -1;
264 goto end;
265 }
266 }
267
268 *_agent_filter = agent_filter;
269 agent_filter = NULL;
270
271end:
272 free(agent_filter);
273 return ret;
274}
275
276static enum lttng_error_code
28ab034a
JG
277lttng_event_rule_python_logging_generate_filter_bytecode(struct lttng_event_rule *rule,
278 const struct lttng_credentials *creds)
6530ec7d
JR
279{
280 int ret;
281 enum lttng_error_code ret_code;
282 struct lttng_event_rule_python_logging *python_logging;
283 enum lttng_event_rule_status status;
284 const char *filter;
285 struct lttng_bytecode *bytecode = NULL;
286 char *agent_filter;
287
a0377dfe 288 LTTNG_ASSERT(rule);
6530ec7d 289
28ab034a 290 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
291
292 status = lttng_event_rule_python_logging_get_filter(rule, &filter);
293 if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
294 filter = NULL;
295 } else if (status != LTTNG_EVENT_RULE_STATUS_OK) {
296 ret_code = LTTNG_ERR_FILTER_INVAL;
297 goto end;
298 }
299
300 if (filter && filter[0] == '\0') {
301 ret_code = LTTNG_ERR_FILTER_INVAL;
302 goto error;
303 }
304
305 ret = generate_agent_filter(rule, &agent_filter);
306 if (ret) {
307 ret_code = LTTNG_ERR_FILTER_INVAL;
308 goto error;
309 }
310
311 python_logging->internal_filter.filter = agent_filter;
312
313 if (python_logging->internal_filter.filter == NULL) {
314 ret_code = LTTNG_OK;
315 goto end;
316 }
317
318 ret = run_as_generate_filter_bytecode(
28ab034a 319 python_logging->internal_filter.filter, creds, &bytecode);
6530ec7d
JR
320 if (ret) {
321 ret_code = LTTNG_ERR_FILTER_INVAL;
322 goto end;
323 }
324
325 python_logging->internal_filter.bytecode = bytecode;
326 bytecode = NULL;
327 ret_code = LTTNG_OK;
328
329error:
330end:
331 free(bytecode);
332 return ret_code;
333}
334
28ab034a
JG
335static const char *
336lttng_event_rule_python_logging_get_internal_filter(const struct lttng_event_rule *rule)
6530ec7d
JR
337{
338 struct lttng_event_rule_python_logging *python_logging;
339
a0377dfe 340 LTTNG_ASSERT(rule);
28ab034a 341 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
342 return python_logging->internal_filter.filter;
343}
344
345static const struct lttng_bytecode *
28ab034a 346lttng_event_rule_python_logging_get_internal_filter_bytecode(const struct lttng_event_rule *rule)
6530ec7d
JR
347{
348 struct lttng_event_rule_python_logging *python_logging;
349
a0377dfe 350 LTTNG_ASSERT(rule);
28ab034a 351 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
352 return python_logging->internal_filter.bytecode;
353}
354
355static enum lttng_event_rule_generate_exclusions_status
28ab034a
JG
356lttng_event_rule_python_logging_generate_exclusions(const struct lttng_event_rule *rule
357 __attribute__((unused)),
358 struct lttng_event_exclusion **_exclusions)
6530ec7d
JR
359{
360 /* Unsupported. */
361 *_exclusions = NULL;
362 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE;
363}
364
28ab034a 365static unsigned long lttng_event_rule_python_logging_hash(const struct lttng_event_rule *rule)
6530ec7d
JR
366{
367 unsigned long hash;
368 struct lttng_event_rule_python_logging *tp_rule =
28ab034a 369 lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d 370
28ab034a 371 hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING, lttng_ht_seed);
6530ec7d
JR
372 hash ^= hash_key_str(tp_rule->pattern, lttng_ht_seed);
373
374 if (tp_rule->filter_expression) {
375 hash ^= hash_key_str(tp_rule->filter_expression, lttng_ht_seed);
376 }
377
378 if (tp_rule->log_level_rule) {
379 hash ^= lttng_log_level_rule_hash(tp_rule->log_level_rule);
380 }
381
382 return hash;
383}
384
28ab034a
JG
385static struct lttng_event *
386lttng_event_rule_python_logging_generate_lttng_event(const struct lttng_event_rule *rule)
6530ec7d
JR
387{
388 int ret;
389 const struct lttng_event_rule_python_logging *python_logging;
390 struct lttng_event *local_event = NULL;
391 struct lttng_event *event = NULL;
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;
396
28ab034a 397 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d 398
64803277 399 local_event = zmalloc<lttng_event>();
6530ec7d
JR
400 if (!local_event) {
401 goto error;
402 }
403
404 local_event->type = LTTNG_EVENT_TRACEPOINT;
28ab034a 405 ret = lttng_strncpy(local_event->name, python_logging->pattern, sizeof(local_event->name));
6530ec7d
JR
406 if (ret) {
407 ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'",
28ab034a 408 python_logging->pattern);
6530ec7d
JR
409 goto error;
410 }
411
6530ec7d 412 /* Map the log level rule to an equivalent lttng_loglevel. */
28ab034a 413 status = lttng_event_rule_python_logging_get_log_level_rule(rule, &log_level_rule);
6530ec7d
JR
414 if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
415 loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
416 loglevel_value = 0;
417 } else if (status == LTTNG_EVENT_RULE_STATUS_OK) {
418 enum lttng_log_level_rule_status llr_status;
419
420 switch (lttng_log_level_rule_get_type(log_level_rule)) {
421 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
28ab034a
JG
422 llr_status = lttng_log_level_rule_exactly_get_level(log_level_rule,
423 &loglevel_value);
6530ec7d
JR
424 loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
425 break;
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(
28ab034a 428 log_level_rule, &loglevel_value);
6530ec7d
JR
429 loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
430 break;
431 default:
432 abort();
433 break;
434 }
435
436 if (llr_status != LTTNG_LOG_LEVEL_RULE_STATUS_OK) {
437 goto error;
438 }
439 } else {
440 goto error;
441 }
442
443 local_event->loglevel_type = loglevel_type;
444 local_event->loglevel = loglevel_value;
445
446 event = local_event;
447 local_event = NULL;
448error:
449 free(local_event);
450 return event;
451}
452
28ab034a
JG
453static enum lttng_error_code
454lttng_event_rule_python_logging_mi_serialize(const struct lttng_event_rule *rule,
455 struct mi_writer *writer)
6a751b95
JR
456{
457 int ret;
458 enum lttng_error_code ret_code;
459 enum lttng_event_rule_status status;
460 const char *filter = NULL;
461 const char *name_pattern = NULL;
462 const struct lttng_log_level_rule *log_level_rule = NULL;
463
a0377dfe
FD
464 LTTNG_ASSERT(rule);
465 LTTNG_ASSERT(writer);
466 LTTNG_ASSERT(IS_PYTHON_LOGGING_EVENT_RULE(rule));
6a751b95 467
28ab034a 468 status = lttng_event_rule_python_logging_get_name_pattern(rule, &name_pattern);
a0377dfe
FD
469 LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK);
470 LTTNG_ASSERT(name_pattern);
6a751b95
JR
471
472 status = lttng_event_rule_python_logging_get_filter(rule, &filter);
a0377dfe 473 LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK ||
28ab034a 474 status == LTTNG_EVENT_RULE_STATUS_UNSET);
6a751b95 475
28ab034a 476 status = lttng_event_rule_python_logging_get_log_level_rule(rule, &log_level_rule);
a0377dfe 477 LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK ||
28ab034a 478 status == LTTNG_EVENT_RULE_STATUS_UNSET);
6a751b95
JR
479
480 /* Open event rule python logging element. */
28ab034a 481 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_rule_python_logging);
6a751b95
JR
482 if (ret) {
483 goto mi_error;
484 }
485
486 /* Name pattern. */
28ab034a
JG
487 ret = mi_lttng_writer_write_element_string(
488 writer, mi_lttng_element_event_rule_name_pattern, name_pattern);
6a751b95
JR
489 if (ret) {
490 goto mi_error;
491 }
492
493 /* Filter expression. */
494 if (filter != NULL) {
28ab034a
JG
495 ret = mi_lttng_writer_write_element_string(
496 writer, mi_lttng_element_event_rule_filter_expression, filter);
6a751b95
JR
497 if (ret) {
498 goto mi_error;
499 }
500 }
501
502 /* Log level rule. */
503 if (log_level_rule) {
28ab034a 504 ret_code = lttng_log_level_rule_mi_serialize(log_level_rule, writer);
6a751b95
JR
505 if (ret_code != LTTNG_OK) {
506 goto end;
507 }
508 }
509
510 /* Close event rule python logging element. */
511 ret = mi_lttng_writer_close_element(writer);
512 if (ret) {
513 goto mi_error;
514 }
515
516 ret_code = LTTNG_OK;
517 goto end;
518
519mi_error:
520 ret_code = LTTNG_ERR_MI_IO_FAIL;
521end:
522 return ret_code;
523}
524
6530ec7d
JR
525struct lttng_event_rule *lttng_event_rule_python_logging_create(void)
526{
527 struct lttng_event_rule *rule = NULL;
528 struct lttng_event_rule_python_logging *tp_rule;
529 enum lttng_event_rule_status status;
530
64803277 531 tp_rule = zmalloc<lttng_event_rule_python_logging>();
6530ec7d
JR
532 if (!tp_rule) {
533 goto end;
534 }
535
536 rule = &tp_rule->parent;
537 lttng_event_rule_init(&tp_rule->parent, LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING);
538 tp_rule->parent.validate = lttng_event_rule_python_logging_validate;
539 tp_rule->parent.serialize = lttng_event_rule_python_logging_serialize;
540 tp_rule->parent.equal = lttng_event_rule_python_logging_is_equal;
541 tp_rule->parent.destroy = lttng_event_rule_python_logging_destroy;
542 tp_rule->parent.generate_filter_bytecode =
28ab034a
JG
543 lttng_event_rule_python_logging_generate_filter_bytecode;
544 tp_rule->parent.get_filter = lttng_event_rule_python_logging_get_internal_filter;
6530ec7d 545 tp_rule->parent.get_filter_bytecode =
28ab034a
JG
546 lttng_event_rule_python_logging_get_internal_filter_bytecode;
547 tp_rule->parent.generate_exclusions = lttng_event_rule_python_logging_generate_exclusions;
6530ec7d 548 tp_rule->parent.hash = lttng_event_rule_python_logging_hash;
28ab034a 549 tp_rule->parent.generate_lttng_event = lttng_event_rule_python_logging_generate_lttng_event;
6a751b95 550 tp_rule->parent.mi_serialize = lttng_event_rule_python_logging_mi_serialize;
6530ec7d
JR
551
552 tp_rule->log_level_rule = NULL;
553
554 /* Default pattern is '*'. */
555 status = lttng_event_rule_python_logging_set_name_pattern(rule, "*");
556 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
557 lttng_event_rule_destroy(rule);
558 rule = NULL;
559 }
560
561end:
562 return rule;
563}
564
28ab034a
JG
565ssize_t lttng_event_rule_python_logging_create_from_payload(struct lttng_payload_view *view,
566 struct lttng_event_rule **_event_rule)
6530ec7d
JR
567{
568 ssize_t ret, offset = 0;
569 enum lttng_event_rule_status status;
570 const struct lttng_event_rule_python_logging_comm *python_logging_comm;
571 const char *pattern;
572 const char *filter_expression = NULL;
573 struct lttng_buffer_view current_buffer_view;
574 struct lttng_event_rule *rule = NULL;
575 struct lttng_log_level_rule *log_level_rule = NULL;
576
577 if (!_event_rule) {
578 ret = -1;
579 goto end;
580 }
581
28ab034a
JG
582 current_buffer_view =
583 lttng_buffer_view_from_view(&view->buffer, offset, sizeof(*python_logging_comm));
6530ec7d
JR
584 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
585 ERR("Failed to initialize from malformed event rule python_logging: buffer too short to contain header.");
586 ret = -1;
587 goto end;
588 }
589
590 python_logging_comm = (typeof(python_logging_comm)) current_buffer_view.data;
591
592 rule = lttng_event_rule_python_logging_create();
593 if (!rule) {
594 ERR("Failed to create event rule python_logging.");
595 ret = -1;
596 goto end;
597 }
598
599 /* Skip to payload. */
600 offset += current_buffer_view.size;
601
602 /* Map the pattern. */
603 current_buffer_view = lttng_buffer_view_from_view(
28ab034a 604 &view->buffer, offset, python_logging_comm->pattern_len);
6530ec7d
JR
605
606 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
607 ret = -1;
608 goto end;
609 }
610
611 pattern = current_buffer_view.data;
28ab034a
JG
612 if (!lttng_buffer_view_contains_string(
613 &current_buffer_view, pattern, python_logging_comm->pattern_len)) {
6530ec7d
JR
614 ret = -1;
615 goto end;
616 }
617
618 /* Skip after the pattern. */
619 offset += python_logging_comm->pattern_len;
620
621 if (!python_logging_comm->filter_expression_len) {
622 goto skip_filter_expression;
623 }
624
625 /* Map the filter_expression. */
28ab034a
JG
626 current_buffer_view = lttng_buffer_view_from_view(
627 &view->buffer, offset, python_logging_comm->filter_expression_len);
6530ec7d
JR
628 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
629 ret = -1;
630 goto end;
631 }
632
633 filter_expression = current_buffer_view.data;
634 if (!lttng_buffer_view_contains_string(&current_buffer_view,
28ab034a
JG
635 filter_expression,
636 python_logging_comm->filter_expression_len)) {
6530ec7d
JR
637 ret = -1;
638 goto end;
639 }
640
641 /* Skip after the pattern. */
642 offset += python_logging_comm->filter_expression_len;
643
644skip_filter_expression:
645 if (!python_logging_comm->log_level_rule_len) {
646 goto skip_log_level_rule;
647 }
648
649 {
650 /* Map the log level rule. */
28ab034a
JG
651 struct lttng_payload_view current_payload_view = lttng_payload_view_from_view(
652 view, offset, python_logging_comm->log_level_rule_len);
6530ec7d 653
28ab034a
JG
654 ret = lttng_log_level_rule_create_from_payload(&current_payload_view,
655 &log_level_rule);
6530ec7d
JR
656 if (ret < 0) {
657 ret = -1;
658 goto end;
659 }
660
a0377dfe 661 LTTNG_ASSERT(ret == python_logging_comm->log_level_rule_len);
6530ec7d
JR
662 }
663
664 /* Skip after the log level rule. */
665 offset += python_logging_comm->log_level_rule_len;
666
667skip_log_level_rule:
668
669 status = lttng_event_rule_python_logging_set_name_pattern(rule, pattern);
670 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
671 ERR("Failed to set event rule python_logging pattern.");
672 ret = -1;
673 goto end;
674 }
675
676 if (filter_expression) {
28ab034a 677 status = lttng_event_rule_python_logging_set_filter(rule, filter_expression);
6530ec7d
JR
678 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
679 ERR("Failed to set event rule python_logging pattern.");
680 ret = -1;
681 goto end;
682 }
683 }
684
685 if (log_level_rule) {
28ab034a 686 status = lttng_event_rule_python_logging_set_log_level_rule(rule, log_level_rule);
6530ec7d
JR
687 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
688 ERR("Failed to set event rule python_logging log level rule.");
689 ret = -1;
690 goto end;
691 }
692 }
693
694 *_event_rule = rule;
695 rule = NULL;
696 ret = offset;
697end:
698 lttng_log_level_rule_destroy(log_level_rule);
699 lttng_event_rule_destroy(rule);
700 return ret;
701}
702
28ab034a
JG
703enum lttng_event_rule_status
704lttng_event_rule_python_logging_set_name_pattern(struct lttng_event_rule *rule, const char *pattern)
6530ec7d
JR
705{
706 char *pattern_copy = NULL;
707 struct lttng_event_rule_python_logging *python_logging;
708 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
709
28ab034a 710 if (!rule || !IS_PYTHON_LOGGING_EVENT_RULE(rule) || !pattern || strlen(pattern) == 0) {
6530ec7d
JR
711 status = LTTNG_EVENT_RULE_STATUS_INVALID;
712 goto end;
713 }
714
28ab034a 715 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
716 pattern_copy = strdup(pattern);
717 if (!pattern_copy) {
718 status = LTTNG_EVENT_RULE_STATUS_ERROR;
719 goto end;
720 }
721
722 /* Normalize the pattern. */
723 strutils_normalize_star_glob_pattern(pattern_copy);
724
725 free(python_logging->pattern);
726
727 python_logging->pattern = pattern_copy;
728 pattern_copy = NULL;
729end:
730 return status;
731}
732
28ab034a
JG
733enum lttng_event_rule_status
734lttng_event_rule_python_logging_get_name_pattern(const struct lttng_event_rule *rule,
735 const char **pattern)
6530ec7d
JR
736{
737 struct lttng_event_rule_python_logging *python_logging;
738 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
739
740 if (!rule || !IS_PYTHON_LOGGING_EVENT_RULE(rule) || !pattern) {
741 status = LTTNG_EVENT_RULE_STATUS_INVALID;
742 goto end;
743 }
744
28ab034a 745 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
746 if (!python_logging->pattern) {
747 status = LTTNG_EVENT_RULE_STATUS_UNSET;
748 goto end;
749 }
750
751 *pattern = python_logging->pattern;
752end:
753 return status;
754}
755
28ab034a
JG
756enum lttng_event_rule_status
757lttng_event_rule_python_logging_set_filter(struct lttng_event_rule *rule, const char *expression)
6530ec7d
JR
758{
759 char *expression_copy = NULL;
760 struct lttng_event_rule_python_logging *python_logging;
761 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
762
763 if (!rule || !IS_PYTHON_LOGGING_EVENT_RULE(rule) || !expression ||
28ab034a 764 strlen(expression) == 0) {
6530ec7d
JR
765 status = LTTNG_EVENT_RULE_STATUS_INVALID;
766 goto end;
767 }
768
28ab034a 769 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
770 expression_copy = strdup(expression);
771 if (!expression_copy) {
772 PERROR("Failed to copy filter expression");
773 status = LTTNG_EVENT_RULE_STATUS_ERROR;
774 goto end;
775 }
776
777 if (python_logging->filter_expression) {
778 free(python_logging->filter_expression);
779 }
780
781 python_logging->filter_expression = expression_copy;
782 expression_copy = NULL;
783end:
784 return status;
785}
786
28ab034a
JG
787enum lttng_event_rule_status
788lttng_event_rule_python_logging_get_filter(const struct lttng_event_rule *rule,
789 const char **expression)
6530ec7d 790{
0114db0e 791 const struct lttng_event_rule_python_logging *python_logging;
6530ec7d
JR
792 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
793
794 if (!rule || !IS_PYTHON_LOGGING_EVENT_RULE(rule) || !expression) {
795 status = LTTNG_EVENT_RULE_STATUS_INVALID;
796 goto end;
797 }
798
28ab034a 799 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
800 if (!python_logging->filter_expression) {
801 status = LTTNG_EVENT_RULE_STATUS_UNSET;
802 goto end;
803 }
804
805 *expression = python_logging->filter_expression;
806end:
807 return status;
808}
809
28ab034a 810static bool log_level_rule_valid(const struct lttng_log_level_rule *rule __attribute__((unused)))
6530ec7d
JR
811{
812 /*
813 * For python, custom log level are possible, it is not clear if
814 * negative value are accepted (NOTSET == 0) but the source code
815 * validates against the int type implying that negative values
816 * are accepted.
817 */
818 return true;
819}
820
821enum lttng_event_rule_status lttng_event_rule_python_logging_set_log_level_rule(
28ab034a 822 struct lttng_event_rule *rule, const struct lttng_log_level_rule *log_level_rule)
6530ec7d
JR
823{
824 struct lttng_event_rule_python_logging *python_logging;
825 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
826 struct lttng_log_level_rule *copy = NULL;
827
828 if (!rule || !IS_PYTHON_LOGGING_EVENT_RULE(rule)) {
829 status = LTTNG_EVENT_RULE_STATUS_INVALID;
830 goto end;
831 }
832
28ab034a 833 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
834
835 if (!log_level_rule_valid(log_level_rule)) {
836 status = LTTNG_EVENT_RULE_STATUS_INVALID;
837 goto end;
838 }
839
840 copy = lttng_log_level_rule_copy(log_level_rule);
841 if (copy == NULL) {
842 status = LTTNG_EVENT_RULE_STATUS_ERROR;
843 goto end;
844 }
845
846 if (python_logging->log_level_rule) {
847 lttng_log_level_rule_destroy(python_logging->log_level_rule);
848 }
849
850 python_logging->log_level_rule = copy;
851
852end:
853 return status;
854}
855
856enum lttng_event_rule_status lttng_event_rule_python_logging_get_log_level_rule(
28ab034a 857 const struct lttng_event_rule *rule, const struct lttng_log_level_rule **log_level_rule)
6530ec7d
JR
858{
859 struct lttng_event_rule_python_logging *python_logging;
860 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
861
862 if (!rule || !IS_PYTHON_LOGGING_EVENT_RULE(rule) || !log_level_rule) {
863 status = LTTNG_EVENT_RULE_STATUS_INVALID;
864 goto end;
865 }
866
28ab034a 867 python_logging = lttng::utils::container_of(rule, &lttng_event_rule_python_logging::parent);
6530ec7d
JR
868 if (python_logging->log_level_rule == NULL) {
869 status = LTTNG_EVENT_RULE_STATUS_UNSET;
870 goto end;
871 }
872
873 *log_level_rule = python_logging->log_level_rule;
874end:
875 return status;
876}
This page took 0.075736 seconds and 4 git commands to generate.