clang-tidy: add Chrome-inspired checks
[lttng-tools.git] / src / common / event-rule / jul-logging.cpp
1 /*
2 * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
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
20 #include <lttng/event-rule/event-rule-internal.hpp>
21 #include <lttng/event-rule/jul-logging-internal.hpp>
22 #include <lttng/event.h>
23 #include <lttng/log-level-rule.h>
24
25 #define IS_JUL_LOGGING_EVENT_RULE(rule) \
26 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_JUL_LOGGING)
27
28 static void lttng_event_rule_jul_logging_destroy(struct lttng_event_rule *rule)
29 {
30 struct lttng_event_rule_jul_logging *jul_logging;
31
32 if (rule == nullptr) {
33 return;
34 }
35
36 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
37
38 lttng_log_level_rule_destroy(jul_logging->log_level_rule);
39 free(jul_logging->pattern);
40 free(jul_logging->filter_expression);
41 free(jul_logging->internal_filter.filter);
42 free(jul_logging->internal_filter.bytecode);
43 free(jul_logging);
44 }
45
46 static bool lttng_event_rule_jul_logging_validate(const struct lttng_event_rule *rule)
47 {
48 bool valid = false;
49 struct lttng_event_rule_jul_logging *jul_logging;
50
51 if (!rule) {
52 goto end;
53 }
54
55 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
56
57 /* Required field. */
58 if (!jul_logging->pattern) {
59 ERR("Invalid jul_logging event rule: a pattern must be set.");
60 goto end;
61 }
62
63 valid = true;
64 end:
65 return valid;
66 }
67
68 static int lttng_event_rule_jul_logging_serialize(const struct lttng_event_rule *rule,
69 struct lttng_payload *payload)
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_jul_logging *jul_logging;
75 struct lttng_event_rule_jul_logging_comm jul_logging_comm;
76 struct lttng_event_rule_jul_logging_comm *header;
77
78 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule)) {
79 ret = -1;
80 goto end;
81 }
82
83 header_offset = payload->buffer.size;
84
85 DBG("Serializing jul_logging event rule.");
86 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
87
88 pattern_len = strlen(jul_logging->pattern) + 1;
89
90 if (jul_logging->filter_expression != nullptr) {
91 filter_expression_len = strlen(jul_logging->filter_expression) + 1;
92 } else {
93 filter_expression_len = 0;
94 }
95
96 jul_logging_comm.pattern_len = pattern_len;
97 jul_logging_comm.filter_expression_len = filter_expression_len;
98
99 ret = lttng_dynamic_buffer_append(
100 &payload->buffer, &jul_logging_comm, sizeof(jul_logging_comm));
101 if (ret) {
102 goto end;
103 }
104
105 ret = lttng_dynamic_buffer_append(&payload->buffer, jul_logging->pattern, pattern_len);
106 if (ret) {
107 goto end;
108 }
109
110 ret = lttng_dynamic_buffer_append(
111 &payload->buffer, jul_logging->filter_expression, filter_expression_len);
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(jul_logging->log_level_rule, payload);
119 if (ret < 0) {
120 goto end;
121 }
122
123 header = (typeof(header)) ((char *) payload->buffer.data + header_offset);
124 header->log_level_rule_len = payload->buffer.size - size_before_log_level_rule;
125
126 end:
127 return ret;
128 }
129
130 static bool lttng_event_rule_jul_logging_is_equal(const struct lttng_event_rule *_a,
131 const struct lttng_event_rule *_b)
132 {
133 bool is_equal = false;
134 struct lttng_event_rule_jul_logging *a, *b;
135
136 a = lttng::utils::container_of(_a, &lttng_event_rule_jul_logging::parent);
137 b = lttng::utils::container_of(_b, &lttng_event_rule_jul_logging::parent);
138
139 /* Quick checks. */
140
141 if (!!a->filter_expression != !!b->filter_expression) {
142 goto end;
143 }
144
145 /* Long check. */
146 LTTNG_ASSERT(a->pattern);
147 LTTNG_ASSERT(b->pattern);
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
161 if (!lttng_log_level_rule_is_equal(a->log_level_rule, b->log_level_rule)) {
162 goto end;
163 }
164
165 is_equal = true;
166 end:
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 */
177 static int generate_agent_filter(const struct lttng_event_rule *rule, char **_agent_filter)
178 {
179 int err;
180 int ret = 0;
181 char *agent_filter = nullptr;
182 const char *pattern;
183 const char *filter;
184 const struct lttng_log_level_rule *log_level_rule = nullptr;
185 enum lttng_event_rule_status status;
186
187 LTTNG_ASSERT(rule);
188 LTTNG_ASSERT(_agent_filter);
189
190 status = lttng_event_rule_jul_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_jul_logging_get_filter(rule, &filter);
197 if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
198 filter = nullptr;
199 } else if (status != LTTNG_EVENT_RULE_STATUS_OK) {
200 ret = -1;
201 goto end;
202 }
203
204 /* Don't add filter for the '*' event. */
205 if (strcmp(pattern, "*") != 0) {
206 if (filter) {
207 err = asprintf(
208 &agent_filter, "(%s) && (logger_name == \"%s\")", filter, pattern);
209 } else {
210 err = asprintf(&agent_filter, "logger_name == \"%s\"", pattern);
211 }
212
213 if (err < 0) {
214 PERROR("Failed to format agent filter string");
215 ret = -1;
216 goto end;
217 }
218 }
219
220 status = lttng_event_rule_jul_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;
223 const char *op;
224 int level;
225
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);
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(
233 log_level_rule, &level);
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,
249 "(%s) && (int_loglevel %s %d)",
250 agent_filter ? agent_filter : filter,
251 op,
252 level);
253 if (agent_filter) {
254 free(agent_filter);
255 }
256 agent_filter = new_filter;
257 } else {
258 err = asprintf(&agent_filter, "int_loglevel %s %d", op, level);
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 = nullptr;
270
271 end:
272 free(agent_filter);
273 return ret;
274 }
275
276 static enum lttng_error_code
277 lttng_event_rule_jul_logging_generate_filter_bytecode(struct lttng_event_rule *rule,
278 const struct lttng_credentials *creds)
279 {
280 int ret;
281 enum lttng_error_code ret_code;
282 struct lttng_event_rule_jul_logging *jul_logging;
283 enum lttng_event_rule_status status;
284 const char *filter;
285 struct lttng_bytecode *bytecode = nullptr;
286 char *agent_filter;
287
288 LTTNG_ASSERT(rule);
289
290 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
291
292 status = lttng_event_rule_jul_logging_get_filter(rule, &filter);
293 if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
294 filter = nullptr;
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 jul_logging->internal_filter.filter = agent_filter;
312
313 if (jul_logging->internal_filter.filter == nullptr) {
314 ret_code = LTTNG_OK;
315 goto end;
316 }
317
318 ret = run_as_generate_filter_bytecode(
319 jul_logging->internal_filter.filter, creds, &bytecode);
320 if (ret) {
321 ret_code = LTTNG_ERR_FILTER_INVAL;
322 goto end;
323 }
324
325 jul_logging->internal_filter.bytecode = bytecode;
326 bytecode = nullptr;
327 ret_code = LTTNG_OK;
328
329 error:
330 end:
331 free(bytecode);
332 return ret_code;
333 }
334
335 static const char *
336 lttng_event_rule_jul_logging_get_internal_filter(const struct lttng_event_rule *rule)
337 {
338 struct lttng_event_rule_jul_logging *jul_logging;
339
340 LTTNG_ASSERT(rule);
341 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
342 return jul_logging->internal_filter.filter;
343 }
344
345 static const struct lttng_bytecode *
346 lttng_event_rule_jul_logging_get_internal_filter_bytecode(const struct lttng_event_rule *rule)
347 {
348 struct lttng_event_rule_jul_logging *jul_logging;
349
350 LTTNG_ASSERT(rule);
351 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
352 return jul_logging->internal_filter.bytecode;
353 }
354
355 static enum lttng_event_rule_generate_exclusions_status
356 lttng_event_rule_jul_logging_generate_exclusions(const struct lttng_event_rule *rule
357 __attribute__((unused)),
358 struct lttng_event_exclusion **_exclusions)
359 {
360 /* Unsupported. */
361 *_exclusions = nullptr;
362 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE;
363 }
364
365 static unsigned long lttng_event_rule_jul_logging_hash(const struct lttng_event_rule *rule)
366 {
367 unsigned long hash;
368 struct lttng_event_rule_jul_logging *tp_rule =
369 lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
370
371 hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_JUL_LOGGING, lttng_ht_seed);
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
385 static struct lttng_event *
386 lttng_event_rule_jul_logging_generate_lttng_event(const struct lttng_event_rule *rule)
387 {
388 int ret;
389 const struct lttng_event_rule_jul_logging *jul_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;
396
397 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
398
399 local_event = zmalloc<lttng_event>();
400 if (!local_event) {
401 goto error;
402 }
403
404 local_event->type = LTTNG_EVENT_TRACEPOINT;
405 ret = lttng_strncpy(local_event->name, jul_logging->pattern, sizeof(local_event->name));
406 if (ret) {
407 ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'",
408 jul_logging->pattern);
409 goto error;
410 }
411
412 /* Map the log level rule to an equivalent lttng_loglevel. */
413 status = lttng_event_rule_jul_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 = 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:
422 llr_status = lttng_log_level_rule_exactly_get_level(log_level_rule,
423 &loglevel_value);
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(
428 log_level_rule, &loglevel_value);
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 = nullptr;
448 error:
449 free(local_event);
450 return event;
451 }
452
453 static enum lttng_error_code
454 lttng_event_rule_jul_logging_mi_serialize(const struct lttng_event_rule *rule,
455 struct mi_writer *writer)
456 {
457 int ret;
458 enum lttng_error_code ret_code;
459 enum lttng_event_rule_status status;
460
461 const char *filter = nullptr;
462 const char *name_pattern = nullptr;
463 const struct lttng_log_level_rule *log_level_rule = nullptr;
464
465 LTTNG_ASSERT(rule);
466 LTTNG_ASSERT(writer);
467 LTTNG_ASSERT(IS_JUL_LOGGING_EVENT_RULE(rule));
468
469 status = lttng_event_rule_jul_logging_get_name_pattern(rule, &name_pattern);
470 LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK);
471 LTTNG_ASSERT(name_pattern);
472
473 status = lttng_event_rule_jul_logging_get_filter(rule, &filter);
474 LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK ||
475 status == LTTNG_EVENT_RULE_STATUS_UNSET);
476
477 status = lttng_event_rule_jul_logging_get_log_level_rule(rule, &log_level_rule);
478 LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK ||
479 status == LTTNG_EVENT_RULE_STATUS_UNSET);
480
481 /* Open event rule jul logging element. */
482 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_rule_jul_logging);
483 if (ret) {
484 goto mi_error;
485 }
486
487 /* Name pattern. */
488 ret = mi_lttng_writer_write_element_string(
489 writer, mi_lttng_element_event_rule_name_pattern, name_pattern);
490 if (ret) {
491 goto mi_error;
492 }
493
494 /* Filter expression. */
495 if (filter != nullptr) {
496 ret = mi_lttng_writer_write_element_string(
497 writer, mi_lttng_element_event_rule_filter_expression, filter);
498 if (ret) {
499 goto mi_error;
500 }
501 }
502
503 /* Log level rule. */
504 if (log_level_rule) {
505 ret_code = lttng_log_level_rule_mi_serialize(log_level_rule, writer);
506 if (ret_code != LTTNG_OK) {
507 goto end;
508 }
509 }
510
511 /* Close event rule jul logging element. */
512 ret = mi_lttng_writer_close_element(writer);
513 if (ret) {
514 goto mi_error;
515 }
516
517 ret_code = LTTNG_OK;
518 goto end;
519
520 mi_error:
521 ret_code = LTTNG_ERR_MI_IO_FAIL;
522 end:
523 return ret_code;
524 }
525
526 struct lttng_event_rule *lttng_event_rule_jul_logging_create(void)
527 {
528 struct lttng_event_rule *rule = nullptr;
529 struct lttng_event_rule_jul_logging *tp_rule;
530 enum lttng_event_rule_status status;
531
532 tp_rule = zmalloc<lttng_event_rule_jul_logging>();
533 if (!tp_rule) {
534 goto end;
535 }
536
537 rule = &tp_rule->parent;
538 lttng_event_rule_init(&tp_rule->parent, LTTNG_EVENT_RULE_TYPE_JUL_LOGGING);
539 tp_rule->parent.validate = lttng_event_rule_jul_logging_validate;
540 tp_rule->parent.serialize = lttng_event_rule_jul_logging_serialize;
541 tp_rule->parent.equal = lttng_event_rule_jul_logging_is_equal;
542 tp_rule->parent.destroy = lttng_event_rule_jul_logging_destroy;
543 tp_rule->parent.generate_filter_bytecode =
544 lttng_event_rule_jul_logging_generate_filter_bytecode;
545 tp_rule->parent.get_filter = lttng_event_rule_jul_logging_get_internal_filter;
546 tp_rule->parent.get_filter_bytecode =
547 lttng_event_rule_jul_logging_get_internal_filter_bytecode;
548 tp_rule->parent.generate_exclusions = lttng_event_rule_jul_logging_generate_exclusions;
549 tp_rule->parent.hash = lttng_event_rule_jul_logging_hash;
550 tp_rule->parent.generate_lttng_event = lttng_event_rule_jul_logging_generate_lttng_event;
551 tp_rule->parent.mi_serialize = lttng_event_rule_jul_logging_mi_serialize;
552
553 tp_rule->log_level_rule = nullptr;
554
555 /* Default pattern is '*'. */
556 status = lttng_event_rule_jul_logging_set_name_pattern(rule, "*");
557 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
558 lttng_event_rule_destroy(rule);
559 rule = nullptr;
560 }
561
562 end:
563 return rule;
564 }
565
566 ssize_t lttng_event_rule_jul_logging_create_from_payload(struct lttng_payload_view *view,
567 struct lttng_event_rule **_event_rule)
568 {
569 ssize_t ret, offset = 0;
570 enum lttng_event_rule_status status;
571 const struct lttng_event_rule_jul_logging_comm *jul_logging_comm;
572 const char *pattern;
573 const char *filter_expression = nullptr;
574 struct lttng_buffer_view current_buffer_view;
575 struct lttng_event_rule *rule = nullptr;
576 struct lttng_log_level_rule *log_level_rule = nullptr;
577
578 if (!_event_rule) {
579 ret = -1;
580 goto end;
581 }
582
583 current_buffer_view =
584 lttng_buffer_view_from_view(&view->buffer, offset, sizeof(*jul_logging_comm));
585 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
586 ERR("Failed to initialize from malformed event rule jul_logging: buffer too short to contain header.");
587 ret = -1;
588 goto end;
589 }
590
591 jul_logging_comm = (typeof(jul_logging_comm)) current_buffer_view.data;
592
593 rule = lttng_event_rule_jul_logging_create();
594 if (!rule) {
595 ERR("Failed to create event rule jul_logging.");
596 ret = -1;
597 goto end;
598 }
599
600 /* Skip to payload. */
601 offset += current_buffer_view.size;
602
603 /* Map the pattern. */
604 current_buffer_view =
605 lttng_buffer_view_from_view(&view->buffer, offset, jul_logging_comm->pattern_len);
606
607 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
608 ret = -1;
609 goto end;
610 }
611
612 pattern = current_buffer_view.data;
613 if (!lttng_buffer_view_contains_string(
614 &current_buffer_view, pattern, jul_logging_comm->pattern_len)) {
615 ret = -1;
616 goto end;
617 }
618
619 /* Skip after the pattern. */
620 offset += jul_logging_comm->pattern_len;
621
622 if (!jul_logging_comm->filter_expression_len) {
623 goto skip_filter_expression;
624 }
625
626 /* Map the filter_expression. */
627 current_buffer_view = lttng_buffer_view_from_view(
628 &view->buffer, offset, jul_logging_comm->filter_expression_len);
629 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
630 ret = -1;
631 goto end;
632 }
633
634 filter_expression = current_buffer_view.data;
635 if (!lttng_buffer_view_contains_string(&current_buffer_view,
636 filter_expression,
637 jul_logging_comm->filter_expression_len)) {
638 ret = -1;
639 goto end;
640 }
641
642 /* Skip after the pattern. */
643 offset += jul_logging_comm->filter_expression_len;
644
645 skip_filter_expression:
646 if (!jul_logging_comm->log_level_rule_len) {
647 goto skip_log_level_rule;
648 }
649
650 {
651 /* Map the log level rule. */
652 struct lttng_payload_view current_payload_view = lttng_payload_view_from_view(
653 view, offset, jul_logging_comm->log_level_rule_len);
654
655 ret = lttng_log_level_rule_create_from_payload(&current_payload_view,
656 &log_level_rule);
657 if (ret < 0) {
658 ret = -1;
659 goto end;
660 }
661
662 LTTNG_ASSERT(ret == jul_logging_comm->log_level_rule_len);
663 }
664
665 /* Skip after the log level rule. */
666 offset += jul_logging_comm->log_level_rule_len;
667
668 skip_log_level_rule:
669
670 status = lttng_event_rule_jul_logging_set_name_pattern(rule, pattern);
671 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
672 ERR("Failed to set event rule jul_logging pattern.");
673 ret = -1;
674 goto end;
675 }
676
677 if (filter_expression) {
678 status = lttng_event_rule_jul_logging_set_filter(rule, filter_expression);
679 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
680 ERR("Failed to set event rule jul_logging pattern.");
681 ret = -1;
682 goto end;
683 }
684 }
685
686 if (log_level_rule) {
687 status = lttng_event_rule_jul_logging_set_log_level_rule(rule, log_level_rule);
688 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
689 ERR("Failed to set event rule jul_logging log level rule.");
690 ret = -1;
691 goto end;
692 }
693 }
694
695 *_event_rule = rule;
696 rule = nullptr;
697 ret = offset;
698 end:
699 lttng_log_level_rule_destroy(log_level_rule);
700 lttng_event_rule_destroy(rule);
701 return ret;
702 }
703
704 enum lttng_event_rule_status
705 lttng_event_rule_jul_logging_set_name_pattern(struct lttng_event_rule *rule, const char *pattern)
706 {
707 char *pattern_copy = nullptr;
708 struct lttng_event_rule_jul_logging *jul_logging;
709 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
710
711 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !pattern || strlen(pattern) == 0) {
712 status = LTTNG_EVENT_RULE_STATUS_INVALID;
713 goto end;
714 }
715
716 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
717 pattern_copy = strdup(pattern);
718 if (!pattern_copy) {
719 status = LTTNG_EVENT_RULE_STATUS_ERROR;
720 goto end;
721 }
722
723 /* Normalize the pattern. */
724 strutils_normalize_star_glob_pattern(pattern_copy);
725
726 free(jul_logging->pattern);
727
728 jul_logging->pattern = pattern_copy;
729 pattern_copy = nullptr;
730 end:
731 return status;
732 }
733
734 enum lttng_event_rule_status
735 lttng_event_rule_jul_logging_get_name_pattern(const struct lttng_event_rule *rule,
736 const char **pattern)
737 {
738 struct lttng_event_rule_jul_logging *jul_logging;
739 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
740
741 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !pattern) {
742 status = LTTNG_EVENT_RULE_STATUS_INVALID;
743 goto end;
744 }
745
746 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
747 if (!jul_logging->pattern) {
748 status = LTTNG_EVENT_RULE_STATUS_UNSET;
749 goto end;
750 }
751
752 *pattern = jul_logging->pattern;
753 end:
754 return status;
755 }
756
757 enum lttng_event_rule_status lttng_event_rule_jul_logging_set_filter(struct lttng_event_rule *rule,
758 const char *expression)
759 {
760 char *expression_copy = nullptr;
761 struct lttng_event_rule_jul_logging *jul_logging;
762 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
763
764 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !expression || strlen(expression) == 0) {
765 status = LTTNG_EVENT_RULE_STATUS_INVALID;
766 goto end;
767 }
768
769 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
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 (jul_logging->filter_expression) {
778 free(jul_logging->filter_expression);
779 }
780
781 jul_logging->filter_expression = expression_copy;
782 expression_copy = nullptr;
783 end:
784 return status;
785 }
786
787 enum lttng_event_rule_status
788 lttng_event_rule_jul_logging_get_filter(const struct lttng_event_rule *rule,
789 const char **expression)
790 {
791 struct lttng_event_rule_jul_logging *jul_logging;
792 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
793
794 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !expression) {
795 status = LTTNG_EVENT_RULE_STATUS_INVALID;
796 goto end;
797 }
798
799 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
800 if (!jul_logging->filter_expression) {
801 status = LTTNG_EVENT_RULE_STATUS_UNSET;
802 goto end;
803 }
804
805 *expression = jul_logging->filter_expression;
806 end:
807 return status;
808 }
809
810 static bool log_level_rule_valid(const struct lttng_log_level_rule *rule __attribute__((unused)))
811 {
812 /*
813 * For both JUL and LOG4J custom log level are possible and can
814 * span the entire int32 range.
815 */
816 return true;
817 }
818
819 enum lttng_event_rule_status
820 lttng_event_rule_jul_logging_set_log_level_rule(struct lttng_event_rule *rule,
821 const struct lttng_log_level_rule *log_level_rule)
822 {
823 struct lttng_event_rule_jul_logging *jul_logging;
824 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
825 struct lttng_log_level_rule *copy = nullptr;
826
827 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule)) {
828 status = LTTNG_EVENT_RULE_STATUS_INVALID;
829 goto end;
830 }
831
832 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
833
834 if (!log_level_rule_valid(log_level_rule)) {
835 status = LTTNG_EVENT_RULE_STATUS_INVALID;
836 goto end;
837 }
838
839 copy = lttng_log_level_rule_copy(log_level_rule);
840 if (copy == nullptr) {
841 status = LTTNG_EVENT_RULE_STATUS_ERROR;
842 goto end;
843 }
844
845 if (jul_logging->log_level_rule) {
846 lttng_log_level_rule_destroy(jul_logging->log_level_rule);
847 }
848
849 jul_logging->log_level_rule = copy;
850
851 end:
852 return status;
853 }
854
855 enum lttng_event_rule_status
856 lttng_event_rule_jul_logging_get_log_level_rule(const struct lttng_event_rule *rule,
857 const struct lttng_log_level_rule **log_level_rule)
858 {
859 struct lttng_event_rule_jul_logging *jul_logging;
860 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
861
862 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !log_level_rule) {
863 status = LTTNG_EVENT_RULE_STATUS_INVALID;
864 goto end;
865 }
866
867 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
868 if (jul_logging->log_level_rule == nullptr) {
869 status = LTTNG_EVENT_RULE_STATUS_UNSET;
870 goto end;
871 }
872
873 *log_level_rule = jul_logging->log_level_rule;
874 end:
875 return status;
876 }
This page took 0.046719 seconds and 4 git commands to generate.