clang-tidy: add most bugprone warnings
[lttng-tools.git] / src / common / event-rule / jul-logging.cpp
CommitLineData
b47b01d8
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/jul-logging-internal.hpp>
b47b01d8 22#include <lttng/event.h>
6a751b95 23#include <lttng/log-level-rule.h>
b47b01d8
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
cd9adb8b 32 if (rule == nullptr) {
b47b01d8
JR
33 return;
34 }
35
28ab034a 36 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
JR
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
28ab034a 46static bool lttng_event_rule_jul_logging_validate(const struct lttng_event_rule *rule)
b47b01d8
JR
47{
48 bool valid = false;
49 struct lttng_event_rule_jul_logging *jul_logging;
50
51 if (!rule) {
52 goto end;
53 }
54
28ab034a 55 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
JR
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;
64end:
65 return valid;
66}
67
28ab034a
JG
68static int lttng_event_rule_jul_logging_serialize(const struct lttng_event_rule *rule,
69 struct lttng_payload *payload)
b47b01d8
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_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.");
28ab034a 86 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
JR
87
88 pattern_len = strlen(jul_logging->pattern) + 1;
89
cd9adb8b 90 if (jul_logging->filter_expression != nullptr) {
28ab034a 91 filter_expression_len = strlen(jul_logging->filter_expression) + 1;
b47b01d8
JR
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
28ab034a
JG
99 ret = lttng_dynamic_buffer_append(
100 &payload->buffer, &jul_logging_comm, sizeof(jul_logging_comm));
b47b01d8
JR
101 if (ret) {
102 goto end;
103 }
104
28ab034a 105 ret = lttng_dynamic_buffer_append(&payload->buffer, jul_logging->pattern, pattern_len);
b47b01d8
JR
106 if (ret) {
107 goto end;
108 }
109
28ab034a
JG
110 ret = lttng_dynamic_buffer_append(
111 &payload->buffer, jul_logging->filter_expression, filter_expression_len);
b47b01d8
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(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);
28ab034a 124 header->log_level_rule_len = payload->buffer.size - size_before_log_level_rule;
b47b01d8
JR
125
126end:
127 return ret;
128}
129
28ab034a
JG
130static bool lttng_event_rule_jul_logging_is_equal(const struct lttng_event_rule *_a,
131 const struct lttng_event_rule *_b)
b47b01d8
JR
132{
133 bool is_equal = false;
134 struct lttng_event_rule_jul_logging *a, *b;
135
0114db0e
JG
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);
b47b01d8
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);
5c7248cd 148 if (strcmp(a->pattern, b->pattern) != 0) {
b47b01d8
JR
149 goto end;
150 }
151
152 if (a->filter_expression && b->filter_expression) {
5c7248cd 153 if (strcmp(a->filter_expression, b->filter_expression) != 0) {
b47b01d8
JR
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)) {
b47b01d8
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)
b47b01d8
JR
178{
179 int err;
180 int ret = 0;
cd9adb8b 181 char *agent_filter = nullptr;
b47b01d8
JR
182 const char *pattern;
183 const char *filter;
cd9adb8b 184 const struct lttng_log_level_rule *log_level_rule = nullptr;
b47b01d8
JR
185 enum lttng_event_rule_status status;
186
a0377dfe
FD
187 LTTNG_ASSERT(rule);
188 LTTNG_ASSERT(_agent_filter);
b47b01d8
JR
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) {
cd9adb8b 198 filter = nullptr;
b47b01d8
JR
199 } else if (status != LTTNG_EVENT_RULE_STATUS_OK) {
200 ret = -1;
201 goto end;
202 }
203
b47b01d8
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);
b47b01d8 209 } else {
28ab034a 210 err = asprintf(&agent_filter, "logger_name == \"%s\"", pattern);
b47b01d8
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_jul_logging_get_log_level_rule(rule, &log_level_rule);
b47b01d8
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)) {
b47b01d8 227 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
28ab034a 228 llr_status = lttng_log_level_rule_exactly_get_level(log_level_rule, &level);
b47b01d8
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);
b47b01d8
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);
b47b01d8
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);
b47b01d8
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;
cd9adb8b 269 agent_filter = nullptr;
b47b01d8
JR
270
271end:
272 free(agent_filter);
273 return ret;
274}
275
276static enum lttng_error_code
28ab034a
JG
277lttng_event_rule_jul_logging_generate_filter_bytecode(struct lttng_event_rule *rule,
278 const struct lttng_credentials *creds)
b47b01d8
JR
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;
cd9adb8b 285 struct lttng_bytecode *bytecode = nullptr;
b47b01d8
JR
286 char *agent_filter;
287
a0377dfe 288 LTTNG_ASSERT(rule);
b47b01d8 289
28ab034a 290 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
JR
291
292 status = lttng_event_rule_jul_logging_get_filter(rule, &filter);
293 if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
cd9adb8b 294 filter = nullptr;
b47b01d8
JR
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
cd9adb8b 313 if (jul_logging->internal_filter.filter == nullptr) {
b47b01d8
JR
314 ret_code = LTTNG_OK;
315 goto end;
316 }
317
318 ret = run_as_generate_filter_bytecode(
28ab034a 319 jul_logging->internal_filter.filter, creds, &bytecode);
b47b01d8
JR
320 if (ret) {
321 ret_code = LTTNG_ERR_FILTER_INVAL;
322 goto end;
323 }
324
325 jul_logging->internal_filter.bytecode = bytecode;
cd9adb8b 326 bytecode = nullptr;
b47b01d8
JR
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_jul_logging_get_internal_filter(const struct lttng_event_rule *rule)
b47b01d8
JR
337{
338 struct lttng_event_rule_jul_logging *jul_logging;
339
a0377dfe 340 LTTNG_ASSERT(rule);
28ab034a 341 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
JR
342 return jul_logging->internal_filter.filter;
343}
344
345static const struct lttng_bytecode *
28ab034a 346lttng_event_rule_jul_logging_get_internal_filter_bytecode(const struct lttng_event_rule *rule)
b47b01d8
JR
347{
348 struct lttng_event_rule_jul_logging *jul_logging;
349
a0377dfe 350 LTTNG_ASSERT(rule);
28ab034a 351 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
JR
352 return jul_logging->internal_filter.bytecode;
353}
354
355static enum lttng_event_rule_generate_exclusions_status
28ab034a
JG
356lttng_event_rule_jul_logging_generate_exclusions(const struct lttng_event_rule *rule
357 __attribute__((unused)),
358 struct lttng_event_exclusion **_exclusions)
b47b01d8
JR
359{
360 /* Unsupported. */
cd9adb8b 361 *_exclusions = nullptr;
b47b01d8
JR
362 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE;
363}
364
28ab034a 365static unsigned long lttng_event_rule_jul_logging_hash(const struct lttng_event_rule *rule)
b47b01d8
JR
366{
367 unsigned long hash;
368 struct lttng_event_rule_jul_logging *tp_rule =
28ab034a 369 lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8 370
28ab034a 371 hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_JUL_LOGGING, lttng_ht_seed);
b47b01d8
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_jul_logging_generate_lttng_event(const struct lttng_event_rule *rule)
b47b01d8
JR
387{
388 int ret;
389 const struct lttng_event_rule_jul_logging *jul_logging;
cd9adb8b
JG
390 struct lttng_event *local_event = nullptr;
391 struct lttng_event *event = nullptr;
b47b01d8
JR
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 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8 398
64803277 399 local_event = zmalloc<lttng_event>();
b47b01d8
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, jul_logging->pattern, sizeof(local_event->name));
b47b01d8
JR
406 if (ret) {
407 ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'",
28ab034a 408 jul_logging->pattern);
b47b01d8
JR
409 goto error;
410 }
411
b47b01d8 412 /* Map the log level rule to an equivalent lttng_loglevel. */
28ab034a 413 status = lttng_event_rule_jul_logging_get_log_level_rule(rule, &log_level_rule);
b47b01d8
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);
b47b01d8
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);
b47b01d8
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;
cd9adb8b 447 local_event = nullptr;
b47b01d8
JR
448error:
449 free(local_event);
450 return event;
451}
452
28ab034a
JG
453static enum lttng_error_code
454lttng_event_rule_jul_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
cd9adb8b
JG
461 const char *filter = nullptr;
462 const char *name_pattern = nullptr;
463 const struct lttng_log_level_rule *log_level_rule = nullptr;
6a751b95 464
a0377dfe
FD
465 LTTNG_ASSERT(rule);
466 LTTNG_ASSERT(writer);
467 LTTNG_ASSERT(IS_JUL_LOGGING_EVENT_RULE(rule));
6a751b95 468
28ab034a 469 status = lttng_event_rule_jul_logging_get_name_pattern(rule, &name_pattern);
a0377dfe
FD
470 LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK);
471 LTTNG_ASSERT(name_pattern);
6a751b95
JR
472
473 status = lttng_event_rule_jul_logging_get_filter(rule, &filter);
a0377dfe 474 LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK ||
28ab034a 475 status == LTTNG_EVENT_RULE_STATUS_UNSET);
6a751b95 476
28ab034a 477 status = lttng_event_rule_jul_logging_get_log_level_rule(rule, &log_level_rule);
a0377dfe 478 LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK ||
28ab034a 479 status == LTTNG_EVENT_RULE_STATUS_UNSET);
6a751b95
JR
480
481 /* Open event rule jul logging element. */
28ab034a 482 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_rule_jul_logging);
6a751b95
JR
483 if (ret) {
484 goto mi_error;
485 }
486
487 /* Name pattern. */
28ab034a
JG
488 ret = mi_lttng_writer_write_element_string(
489 writer, mi_lttng_element_event_rule_name_pattern, name_pattern);
6a751b95
JR
490 if (ret) {
491 goto mi_error;
492 }
493
494 /* Filter expression. */
cd9adb8b 495 if (filter != nullptr) {
28ab034a
JG
496 ret = mi_lttng_writer_write_element_string(
497 writer, mi_lttng_element_event_rule_filter_expression, filter);
6a751b95
JR
498 if (ret) {
499 goto mi_error;
500 }
501 }
502
503 /* Log level rule. */
504 if (log_level_rule) {
28ab034a 505 ret_code = lttng_log_level_rule_mi_serialize(log_level_rule, writer);
6a751b95
JR
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
520mi_error:
521 ret_code = LTTNG_ERR_MI_IO_FAIL;
522end:
523 return ret_code;
524}
525
b47b01d8
JR
526struct lttng_event_rule *lttng_event_rule_jul_logging_create(void)
527{
cd9adb8b 528 struct lttng_event_rule *rule = nullptr;
b47b01d8
JR
529 struct lttng_event_rule_jul_logging *tp_rule;
530 enum lttng_event_rule_status status;
531
64803277 532 tp_rule = zmalloc<lttng_event_rule_jul_logging>();
b47b01d8
JR
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 =
28ab034a
JG
544 lttng_event_rule_jul_logging_generate_filter_bytecode;
545 tp_rule->parent.get_filter = lttng_event_rule_jul_logging_get_internal_filter;
b47b01d8 546 tp_rule->parent.get_filter_bytecode =
28ab034a
JG
547 lttng_event_rule_jul_logging_get_internal_filter_bytecode;
548 tp_rule->parent.generate_exclusions = lttng_event_rule_jul_logging_generate_exclusions;
b47b01d8 549 tp_rule->parent.hash = lttng_event_rule_jul_logging_hash;
28ab034a 550 tp_rule->parent.generate_lttng_event = lttng_event_rule_jul_logging_generate_lttng_event;
6a751b95 551 tp_rule->parent.mi_serialize = lttng_event_rule_jul_logging_mi_serialize;
b47b01d8 552
cd9adb8b 553 tp_rule->log_level_rule = nullptr;
b47b01d8
JR
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);
cd9adb8b 559 rule = nullptr;
b47b01d8
JR
560 }
561
562end:
563 return rule;
564}
565
28ab034a
JG
566ssize_t lttng_event_rule_jul_logging_create_from_payload(struct lttng_payload_view *view,
567 struct lttng_event_rule **_event_rule)
b47b01d8
JR
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;
cd9adb8b 573 const char *filter_expression = nullptr;
b47b01d8 574 struct lttng_buffer_view current_buffer_view;
cd9adb8b
JG
575 struct lttng_event_rule *rule = nullptr;
576 struct lttng_log_level_rule *log_level_rule = nullptr;
b47b01d8
JR
577
578 if (!_event_rule) {
579 ret = -1;
580 goto end;
581 }
582
28ab034a
JG
583 current_buffer_view =
584 lttng_buffer_view_from_view(&view->buffer, offset, sizeof(*jul_logging_comm));
b47b01d8
JR
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. */
28ab034a
JG
604 current_buffer_view =
605 lttng_buffer_view_from_view(&view->buffer, offset, jul_logging_comm->pattern_len);
b47b01d8
JR
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;
28ab034a
JG
613 if (!lttng_buffer_view_contains_string(
614 &current_buffer_view, pattern, jul_logging_comm->pattern_len)) {
b47b01d8
JR
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. */
28ab034a
JG
627 current_buffer_view = lttng_buffer_view_from_view(
628 &view->buffer, offset, jul_logging_comm->filter_expression_len);
b47b01d8
JR
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,
28ab034a
JG
636 filter_expression,
637 jul_logging_comm->filter_expression_len)) {
b47b01d8
JR
638 ret = -1;
639 goto end;
640 }
641
642 /* Skip after the pattern. */
643 offset += jul_logging_comm->filter_expression_len;
644
645skip_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. */
28ab034a
JG
652 struct lttng_payload_view current_payload_view = lttng_payload_view_from_view(
653 view, offset, jul_logging_comm->log_level_rule_len);
b47b01d8 654
28ab034a
JG
655 ret = lttng_log_level_rule_create_from_payload(&current_payload_view,
656 &log_level_rule);
b47b01d8
JR
657 if (ret < 0) {
658 ret = -1;
659 goto end;
660 }
661
a0377dfe 662 LTTNG_ASSERT(ret == jul_logging_comm->log_level_rule_len);
b47b01d8
JR
663 }
664
665 /* Skip after the log level rule. */
666 offset += jul_logging_comm->log_level_rule_len;
667
668skip_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) {
28ab034a 678 status = lttng_event_rule_jul_logging_set_filter(rule, filter_expression);
b47b01d8
JR
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) {
28ab034a 687 status = lttng_event_rule_jul_logging_set_log_level_rule(rule, log_level_rule);
b47b01d8
JR
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;
cd9adb8b 696 rule = nullptr;
b47b01d8
JR
697 ret = offset;
698end:
699 lttng_log_level_rule_destroy(log_level_rule);
700 lttng_event_rule_destroy(rule);
701 return ret;
702}
703
28ab034a
JG
704enum lttng_event_rule_status
705lttng_event_rule_jul_logging_set_name_pattern(struct lttng_event_rule *rule, const char *pattern)
b47b01d8 706{
cd9adb8b 707 char *pattern_copy = nullptr;
b47b01d8
JR
708 struct lttng_event_rule_jul_logging *jul_logging;
709 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
710
28ab034a 711 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !pattern || strlen(pattern) == 0) {
b47b01d8
JR
712 status = LTTNG_EVENT_RULE_STATUS_INVALID;
713 goto end;
714 }
715
28ab034a 716 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
JR
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;
cd9adb8b 729 pattern_copy = nullptr;
b47b01d8
JR
730end:
731 return status;
732}
733
28ab034a
JG
734enum lttng_event_rule_status
735lttng_event_rule_jul_logging_get_name_pattern(const struct lttng_event_rule *rule,
736 const char **pattern)
b47b01d8
JR
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
28ab034a 746 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
JR
747 if (!jul_logging->pattern) {
748 status = LTTNG_EVENT_RULE_STATUS_UNSET;
749 goto end;
750 }
751
752 *pattern = jul_logging->pattern;
753end:
754 return status;
755}
756
28ab034a
JG
757enum lttng_event_rule_status lttng_event_rule_jul_logging_set_filter(struct lttng_event_rule *rule,
758 const char *expression)
b47b01d8 759{
cd9adb8b 760 char *expression_copy = nullptr;
b47b01d8
JR
761 struct lttng_event_rule_jul_logging *jul_logging;
762 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
763
28ab034a 764 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule) || !expression || strlen(expression) == 0) {
b47b01d8
JR
765 status = LTTNG_EVENT_RULE_STATUS_INVALID;
766 goto end;
767 }
768
28ab034a 769 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
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 (jul_logging->filter_expression) {
778 free(jul_logging->filter_expression);
779 }
780
781 jul_logging->filter_expression = expression_copy;
cd9adb8b 782 expression_copy = nullptr;
b47b01d8
JR
783end:
784 return status;
785}
786
28ab034a
JG
787enum lttng_event_rule_status
788lttng_event_rule_jul_logging_get_filter(const struct lttng_event_rule *rule,
789 const char **expression)
b47b01d8
JR
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
28ab034a 799 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
JR
800 if (!jul_logging->filter_expression) {
801 status = LTTNG_EVENT_RULE_STATUS_UNSET;
802 goto end;
803 }
804
805 *expression = jul_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)))
b47b01d8
JR
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
28ab034a
JG
819enum lttng_event_rule_status
820lttng_event_rule_jul_logging_set_log_level_rule(struct lttng_event_rule *rule,
821 const struct lttng_log_level_rule *log_level_rule)
b47b01d8
JR
822{
823 struct lttng_event_rule_jul_logging *jul_logging;
824 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
cd9adb8b 825 struct lttng_log_level_rule *copy = nullptr;
b47b01d8
JR
826
827 if (!rule || !IS_JUL_LOGGING_EVENT_RULE(rule)) {
828 status = LTTNG_EVENT_RULE_STATUS_INVALID;
829 goto end;
830 }
831
28ab034a 832 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
b47b01d8
JR
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);
cd9adb8b 840 if (copy == nullptr) {
b47b01d8
JR
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
851end:
852 return status;
853}
854
28ab034a
JG
855enum lttng_event_rule_status
856lttng_event_rule_jul_logging_get_log_level_rule(const struct lttng_event_rule *rule,
857 const struct lttng_log_level_rule **log_level_rule)
b47b01d8
JR
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
28ab034a 867 jul_logging = lttng::utils::container_of(rule, &lttng_event_rule_jul_logging::parent);
cd9adb8b 868 if (jul_logging->log_level_rule == nullptr) {
b47b01d8
JR
869 status = LTTNG_EVENT_RULE_STATUS_UNSET;
870 goto end;
871 }
872
873 *log_level_rule = jul_logging->log_level_rule;
874end:
875 return status;
876}
This page took 0.077432 seconds and 4 git commands to generate.