MI: implement all objects related to trigger machine interface
[lttng-tools.git] / src / common / event-rule / jul-logging.c
CommitLineData
d440991b
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
8#include <assert.h>
9#include <common/credentials.h>
10#include <common/error.h>
0f7c2963
JR
11#include <common/hashtable/hashtable.h>
12#include <common/hashtable/utils.h>
d440991b 13#include <common/macros.h>
0f7c2963 14#include <common/mi-lttng.h>
d440991b 15#include <common/optional.h>
d440991b 16#include <common/payload-view.h>
0f7c2963 17#include <common/payload.h>
d440991b 18#include <common/runas.h>
d440991b
JR
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>
d440991b 22#include <lttng/event.h>
0f7c2963 23#include <lttng/log-level-rule.h>
d440991b
JR
24
25#define IS_JUL_LOGGING_EVENT_RULE(rule) \
26 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_JUL_LOGGING)
27
28static 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 == NULL) {
33 return;
34 }
35
36 jul_logging = container_of(
37 rule, struct lttng_event_rule_jul_logging, parent);
38
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);
44 free(jul_logging);
45}
46
47static bool lttng_event_rule_jul_logging_validate(
48 const struct lttng_event_rule *rule)
49{
50 bool valid = false;
51 struct lttng_event_rule_jul_logging *jul_logging;
52
53 if (!rule) {
54 goto end;
55 }
56
57 jul_logging = container_of(
58 rule, struct lttng_event_rule_jul_logging, parent);
59
60 /* Required field. */
61 if (!jul_logging->pattern) {
62 ERR("Invalid jul_logging event rule: a pattern must be set.");
63 goto end;
64 }
65
66 valid = true;
67end:
68 return valid;
69}
70
71static int lttng_event_rule_jul_logging_serialize(
72 const struct lttng_event_rule *rule,
73 struct lttng_payload *payload)
74{
75 int ret;
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;
81
82 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule)) {
83 ret = -1;
84 goto end;
85 }
86
87 header_offset = payload->buffer.size;
88
89 DBG("Serializing jul_logging event rule.");
90 jul_logging = container_of(
91 rule, struct lttng_event_rule_jul_logging, parent);
92
93 pattern_len = strlen(jul_logging->pattern) + 1;
94
95 if (jul_logging->filter_expression != NULL) {
96 filter_expression_len =
97 strlen(jul_logging->filter_expression) + 1;
98 } else {
99 filter_expression_len = 0;
100 }
101
102 jul_logging_comm.pattern_len = pattern_len;
103 jul_logging_comm.filter_expression_len = filter_expression_len;
104
105 ret = lttng_dynamic_buffer_append(&payload->buffer, &jul_logging_comm,
106 sizeof(jul_logging_comm));
107 if (ret) {
108 goto end;
109 }
110
111 ret = lttng_dynamic_buffer_append(
112 &payload->buffer, jul_logging->pattern, pattern_len);
113 if (ret) {
114 goto end;
115 }
116
117 ret = lttng_dynamic_buffer_append(&payload->buffer, jul_logging->filter_expression,
118 filter_expression_len);
119 if (ret) {
120 goto end;
121 }
122
123 size_before_log_level_rule = payload->buffer.size;
124
125 ret = lttng_log_level_rule_serialize(jul_logging->log_level_rule, payload);
126 if (ret < 0) {
127 goto end;
128 }
129
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;
133
134end:
135 return ret;
136}
137
138static bool lttng_event_rule_jul_logging_is_equal(
139 const struct lttng_event_rule *_a,
140 const struct lttng_event_rule *_b)
141{
142 bool is_equal = false;
143 struct lttng_event_rule_jul_logging *a, *b;
144
145 a = container_of(_a, struct lttng_event_rule_jul_logging, parent);
146 b = container_of(_b, struct lttng_event_rule_jul_logging, parent);
147
148 /* Quick checks. */
149
150 if (!!a->filter_expression != !!b->filter_expression) {
151 goto end;
152 }
153
154 /* Long check. */
155 assert(a->pattern);
156 assert(b->pattern);
157 if (strcmp(a->pattern, b->pattern)) {
158 goto end;
159 }
160
161 if (a->filter_expression && b->filter_expression) {
162 if (strcmp(a->filter_expression, b->filter_expression)) {
163 goto end;
164 }
165 } else if (!!a->filter_expression != !!b->filter_expression) {
166 /* One is set; not the other. */
167 goto end;
168 }
169
170 if (!lttng_log_level_rule_is_equal(
171 a->log_level_rule, b->log_level_rule)) {
172 goto end;
173 }
174
175 is_equal = true;
176end:
177 return is_equal;
178}
179
180/*
181 * On success ret is 0;
182 *
183 * On error ret is negative.
184 *
185 * An event with NO loglevel and the name is * will return NULL.
186 */
187static int generate_agent_filter(
188 const struct lttng_event_rule *rule, char **_agent_filter)
189{
190 int err;
191 int ret = 0;
192 char *agent_filter = NULL;
193 const char *pattern;
194 const char *filter;
195 const struct lttng_log_level_rule *log_level_rule = NULL;
196 enum lttng_event_rule_status status;
197
198 assert(rule);
199 assert(_agent_filter);
200
201 status = lttng_event_rule_jul_logging_get_name_pattern(rule, &pattern);
202 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
203 ret = -1;
204 goto end;
205 }
206
207 status = lttng_event_rule_jul_logging_get_filter(rule, &filter);
208 if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
209 filter = NULL;
210 } else if (status != LTTNG_EVENT_RULE_STATUS_OK) {
211 ret = -1;
212 goto end;
213 }
214
215
216 /* Don't add filter for the '*' event. */
217 if (strcmp(pattern, "*") != 0) {
218 if (filter) {
219 err = asprintf(&agent_filter,
220 "(%s) && (logger_name == \"%s\")",
221 filter, pattern);
222 } else {
223 err = asprintf(&agent_filter, "logger_name == \"%s\"",
224 pattern);
225 }
226
227 if (err < 0) {
228 PERROR("Failed to format agent filter string");
229 ret = -1;
230 goto end;
231 }
232 }
233
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;
238 const char *op;
239 int level;
240
241 switch (lttng_log_level_rule_get_type(log_level_rule))
242 {
243 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
244 llr_status = lttng_log_level_rule_exactly_get_level(
245 log_level_rule, &level);
246 op = "==";
247 break;
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);
251 op = ">=";
252 break;
253 default:
254 abort();
255 }
256
257 if (llr_status != LTTNG_LOG_LEVEL_RULE_STATUS_OK) {
258 ret = -1;
259 goto end;
260 }
261
262 if (filter || agent_filter) {
263 char *new_filter;
264
265 err = asprintf(&new_filter,
266 "(%s) && (int_loglevel %s %d)",
267 agent_filter ? agent_filter : filter,
268 op, level);
269 if (agent_filter) {
270 free(agent_filter);
271 }
272 agent_filter = new_filter;
273 } else {
274 err = asprintf(&agent_filter, "int_loglevel %s %d", op,
275 level);
276 }
277
278 if (err < 0) {
279 PERROR("Failed to format agent filter string");
280 ret = -1;
281 goto end;
282 }
283 }
284
285 *_agent_filter = agent_filter;
286 agent_filter = NULL;
287
288end:
289 free(agent_filter);
290 return ret;
291}
292
293static enum lttng_error_code
294lttng_event_rule_jul_logging_generate_filter_bytecode(
295 struct lttng_event_rule *rule,
296 const struct lttng_credentials *creds)
297{
298 int ret;
299 enum lttng_error_code ret_code;
300 struct lttng_event_rule_jul_logging *jul_logging;
301 enum lttng_event_rule_status status;
302 const char *filter;
303 struct lttng_bytecode *bytecode = NULL;
304 char *agent_filter;
305
306 assert(rule);
307
308 jul_logging = container_of(
309 rule, struct lttng_event_rule_jul_logging, parent);
310
311 status = lttng_event_rule_jul_logging_get_filter(rule, &filter);
312 if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
313 filter = NULL;
314 } else if (status != LTTNG_EVENT_RULE_STATUS_OK) {
315 ret_code = LTTNG_ERR_FILTER_INVAL;
316 goto end;
317 }
318
319 if (filter && filter[0] == '\0') {
320 ret_code = LTTNG_ERR_FILTER_INVAL;
321 goto error;
322 }
323
324 ret = generate_agent_filter(rule, &agent_filter);
325 if (ret) {
326 ret_code = LTTNG_ERR_FILTER_INVAL;
327 goto error;
328 }
329
330 jul_logging->internal_filter.filter = agent_filter;
331
332 if (jul_logging->internal_filter.filter == NULL) {
333 ret_code = LTTNG_OK;
334 goto end;
335 }
336
337 ret = run_as_generate_filter_bytecode(
338 jul_logging->internal_filter.filter, creds,
339 &bytecode);
340 if (ret) {
341 ret_code = LTTNG_ERR_FILTER_INVAL;
342 goto end;
343 }
344
345 jul_logging->internal_filter.bytecode = bytecode;
346 bytecode = NULL;
347 ret_code = LTTNG_OK;
348
349error:
350end:
351 free(bytecode);
352 return ret_code;
353}
354
355static const char *lttng_event_rule_jul_logging_get_internal_filter(
356 const struct lttng_event_rule *rule)
357{
358 struct lttng_event_rule_jul_logging *jul_logging;
359
360 assert(rule);
361 jul_logging = container_of(
362 rule, struct lttng_event_rule_jul_logging, parent);
363 return jul_logging->internal_filter.filter;
364}
365
366static const struct lttng_bytecode *
367lttng_event_rule_jul_logging_get_internal_filter_bytecode(
368 const struct lttng_event_rule *rule)
369{
370 struct lttng_event_rule_jul_logging *jul_logging;
371
372 assert(rule);
373 jul_logging = container_of(
374 rule, struct lttng_event_rule_jul_logging, parent);
375 return jul_logging->internal_filter.bytecode;
376}
377
378static enum lttng_event_rule_generate_exclusions_status
379lttng_event_rule_jul_logging_generate_exclusions(
380 const struct lttng_event_rule *rule,
381 struct lttng_event_exclusion **_exclusions)
382{
383 /* Unsupported. */
384 *_exclusions = NULL;
385 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE;
386}
387
388static unsigned long lttng_event_rule_jul_logging_hash(
389 const struct lttng_event_rule *rule)
390{
391 unsigned long hash;
392 struct lttng_event_rule_jul_logging *tp_rule =
393 container_of(rule, typeof(*tp_rule), parent);
394
395 hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_JUL_LOGGING,
396 lttng_ht_seed);
397 hash ^= hash_key_str(tp_rule->pattern, lttng_ht_seed);
398
399 if (tp_rule->filter_expression) {
400 hash ^= hash_key_str(tp_rule->filter_expression, lttng_ht_seed);
401 }
402
403 if (tp_rule->log_level_rule) {
404 hash ^= lttng_log_level_rule_hash(tp_rule->log_level_rule);
405 }
406
407 return hash;
408}
409
410static struct lttng_event *lttng_event_rule_jul_logging_generate_lttng_event(
411 const struct lttng_event_rule *rule)
412{
413 int ret;
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;
421
422 jul_logging = container_of(
423 rule, const struct lttng_event_rule_jul_logging, parent);
424
425 local_event = zmalloc(sizeof(*local_event));
426 if (!local_event) {
427 goto error;
428 }
429
430 local_event->type = LTTNG_EVENT_TRACEPOINT;
431 ret = lttng_strncpy(local_event->name, jul_logging->pattern,
432 sizeof(local_event->name));
433 if (ret) {
434 ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'",
435 jul_logging->pattern);
436 goto error;
437 }
438
439
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;
445 loglevel_value = 0;
446 } else if (status == LTTNG_EVENT_RULE_STATUS_OK) {
447 enum lttng_log_level_rule_status llr_status;
448
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;
454 break;
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;
459 break;
460 default:
461 abort();
462 break;
463 }
464
465 if (llr_status != LTTNG_LOG_LEVEL_RULE_STATUS_OK) {
466 goto error;
467 }
468 } else {
469 goto error;
470 }
471
472 local_event->loglevel_type = loglevel_type;
473 local_event->loglevel = loglevel_value;
474
475 event = local_event;
476 local_event = NULL;
477error:
478 free(local_event);
479 return event;
480}
481
0f7c2963
JR
482static enum lttng_error_code lttng_event_rule_jul_logging_mi_serialize(
483 const struct lttng_event_rule *rule, struct mi_writer *writer)
484{
485 int ret;
486 enum lttng_error_code ret_code;
487 enum lttng_event_rule_status status;
488
489 const char *filter = NULL;
490 const char *name_pattern = NULL;
491 const struct lttng_log_level_rule *log_level_rule = NULL;
492
493 assert(rule);
494 assert(writer);
495 assert(IS_JUL_LOGGING_EVENT_RULE(rule));
496
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);
501
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);
505
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);
510
511 /* Open event rule jul logging element. */
512 ret = mi_lttng_writer_open_element(
513 writer, mi_lttng_element_event_rule_jul_logging);
514 if (ret) {
515 goto mi_error;
516 }
517
518 /* Name pattern. */
519 ret = mi_lttng_writer_write_element_string(writer,
520 mi_lttng_element_event_rule_name_pattern, name_pattern);
521 if (ret) {
522 goto mi_error;
523 }
524
525 /* Filter expression. */
526 if (filter != NULL) {
527 ret = mi_lttng_writer_write_element_string(writer,
528 mi_lttng_element_event_rule_filter_expression,
529 filter);
530 if (ret) {
531 goto mi_error;
532 }
533 }
534
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) {
540 goto end;
541 }
542 }
543
544 /* Close event rule jul logging element. */
545 ret = mi_lttng_writer_close_element(writer);
546 if (ret) {
547 goto mi_error;
548 }
549
550 ret_code = LTTNG_OK;
551 goto end;
552
553mi_error:
554 ret_code = LTTNG_ERR_MI_IO_FAIL;
555end:
556 return ret_code;
557}
558
d440991b
JR
559struct lttng_event_rule *lttng_event_rule_jul_logging_create(void)
560{
561 struct lttng_event_rule *rule = NULL;
562 struct lttng_event_rule_jul_logging *tp_rule;
563 enum lttng_event_rule_status status;
564
565 tp_rule = zmalloc(sizeof(struct lttng_event_rule_jul_logging));
566 if (!tp_rule) {
567 goto end;
568 }
569
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;
0f7c2963 587 tp_rule->parent.mi_serialize = lttng_event_rule_jul_logging_mi_serialize;
d440991b
JR
588
589 tp_rule->log_level_rule = NULL;
590
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);
595 rule = NULL;
596 }
597
598end:
599 return rule;
600}
601
602LTTNG_HIDDEN
603ssize_t lttng_event_rule_jul_logging_create_from_payload(
604 struct lttng_payload_view *view,
605 struct lttng_event_rule **_event_rule)
606{
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;
610 const char *pattern;
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;
615
616 if (!_event_rule) {
617 ret = -1;
618 goto end;
619 }
620
621 current_buffer_view = lttng_buffer_view_from_view(
622 &view->buffer, offset, sizeof(*jul_logging_comm));
623 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
624 ERR("Failed to initialize from malformed event rule jul_logging: buffer too short to contain header.");
625 ret = -1;
626 goto end;
627 }
628
629 jul_logging_comm = (typeof(jul_logging_comm)) current_buffer_view.data;
630
631 rule = lttng_event_rule_jul_logging_create();
632 if (!rule) {
633 ERR("Failed to create event rule jul_logging.");
634 ret = -1;
635 goto end;
636 }
637
638 /* Skip to payload. */
639 offset += current_buffer_view.size;
640
641 /* Map the pattern. */
642 current_buffer_view = lttng_buffer_view_from_view(
643 &view->buffer, offset, jul_logging_comm->pattern_len);
644
645 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
646 ret = -1;
647 goto end;
648 }
649
650 pattern = current_buffer_view.data;
651 if (!lttng_buffer_view_contains_string(&current_buffer_view, pattern,
652 jul_logging_comm->pattern_len)) {
653 ret = -1;
654 goto end;
655 }
656
657 /* Skip after the pattern. */
658 offset += jul_logging_comm->pattern_len;
659
660 if (!jul_logging_comm->filter_expression_len) {
661 goto skip_filter_expression;
662 }
663
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(&current_buffer_view)) {
668 ret = -1;
669 goto end;
670 }
671
672 filter_expression = current_buffer_view.data;
673 if (!lttng_buffer_view_contains_string(&current_buffer_view,
674 filter_expression,
675 jul_logging_comm->filter_expression_len)) {
676 ret = -1;
677 goto end;
678 }
679
680 /* Skip after the pattern. */
681 offset += jul_logging_comm->filter_expression_len;
682
683skip_filter_expression:
684 if (!jul_logging_comm->log_level_rule_len) {
685 goto skip_log_level_rule;
686 }
687
688 {
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);
693
694 ret = lttng_log_level_rule_create_from_payload(
695 &current_payload_view, &log_level_rule);
696 if (ret < 0) {
697 ret = -1;
698 goto end;
699 }
700
701 assert(ret == jul_logging_comm->log_level_rule_len);
702 }
703
704 /* Skip after the log level rule. */
705 offset += jul_logging_comm->log_level_rule_len;
706
707skip_log_level_rule:
708
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.");
712 ret = -1;
713 goto end;
714 }
715
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.");
721 ret = -1;
722 goto end;
723 }
724 }
725
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.");
731 ret = -1;
732 goto end;
733 }
734 }
735
736 *_event_rule = rule;
737 rule = NULL;
738 ret = offset;
739end:
740 lttng_log_level_rule_destroy(log_level_rule);
741 lttng_event_rule_destroy(rule);
742 return ret;
743}
744
745enum lttng_event_rule_status lttng_event_rule_jul_logging_set_name_pattern(
746 struct lttng_event_rule *rule, const char *pattern)
747{
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;
751
752 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !pattern ||
753 strlen(pattern) == 0) {
754 status = LTTNG_EVENT_RULE_STATUS_INVALID;
755 goto end;
756 }
757
758 jul_logging = container_of(
759 rule, struct lttng_event_rule_jul_logging, parent);
760 pattern_copy = strdup(pattern);
761 if (!pattern_copy) {
762 status = LTTNG_EVENT_RULE_STATUS_ERROR;
763 goto end;
764 }
765
766 /* Normalize the pattern. */
767 strutils_normalize_star_glob_pattern(pattern_copy);
768
769 free(jul_logging->pattern);
770
771 jul_logging->pattern = pattern_copy;
772 pattern_copy = NULL;
773end:
774 return status;
775}
776
777enum lttng_event_rule_status lttng_event_rule_jul_logging_get_name_pattern(
778 const struct lttng_event_rule *rule, const char **pattern)
779{
780 struct lttng_event_rule_jul_logging *jul_logging;
781 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
782
783 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !pattern) {
784 status = LTTNG_EVENT_RULE_STATUS_INVALID;
785 goto end;
786 }
787
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;
792 goto end;
793 }
794
795 *pattern = jul_logging->pattern;
796end:
797 return status;
798}
799
800enum lttng_event_rule_status lttng_event_rule_jul_logging_set_filter(
801 struct lttng_event_rule *rule, const char *expression)
802{
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;
806
807 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !expression ||
808 strlen(expression) == 0) {
809 status = LTTNG_EVENT_RULE_STATUS_INVALID;
810 goto end;
811 }
812
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;
819 goto end;
820 }
821
822 if (jul_logging->filter_expression) {
823 free(jul_logging->filter_expression);
824 }
825
826 jul_logging->filter_expression = expression_copy;
827 expression_copy = NULL;
828end:
829 return status;
830}
831
832enum lttng_event_rule_status lttng_event_rule_jul_logging_get_filter(
833 const struct lttng_event_rule *rule, const char **expression)
834{
835 struct lttng_event_rule_jul_logging *jul_logging;
836 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
837
838 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !expression) {
839 status = LTTNG_EVENT_RULE_STATUS_INVALID;
840 goto end;
841 }
842
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;
847 goto end;
848 }
849
850 *expression = jul_logging->filter_expression;
851end:
852 return status;
853}
854
855static bool log_level_rule_valid(const struct lttng_log_level_rule *rule)
856{
857 /*
858 * For both JUL and LOG4J custom log level are possible and can
859 * span the entire int32 range.
860 */
861 return true;
862}
863
864enum 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)
867{
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;
871
872 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule)) {
873 status = LTTNG_EVENT_RULE_STATUS_INVALID;
874 goto end;
875 }
876
877 jul_logging = container_of(
878 rule, struct lttng_event_rule_jul_logging, parent);
879
880 if (!log_level_rule_valid(log_level_rule)) {
881 status = LTTNG_EVENT_RULE_STATUS_INVALID;
882 goto end;
883 }
884
885 copy = lttng_log_level_rule_copy(log_level_rule);
886 if (copy == NULL) {
887 status = LTTNG_EVENT_RULE_STATUS_ERROR;
888 goto end;
889 }
890
891 if (jul_logging->log_level_rule) {
892 lttng_log_level_rule_destroy(jul_logging->log_level_rule);
893 }
894
895 jul_logging->log_level_rule = copy;
896
897end:
898 return status;
899}
900
901enum 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
904 )
905{
906 struct lttng_event_rule_jul_logging *jul_logging;
907 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
908
909 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !log_level_rule) {
910 status = LTTNG_EVENT_RULE_STATUS_INVALID;
911 goto end;
912 }
913
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;
918 goto end;
919 }
920
921 *log_level_rule = jul_logging->log_level_rule;
922end:
923 return status;
924}
This page took 0.058426 seconds and 5 git commands to generate.