clang-tidy: add Chrome-inspired checks
[lttng-tools.git] / src / common / event-rule / log4j-logging.cpp
CommitLineData
138d6838
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/log4j-logging-internal.hpp>
138d6838 22#include <lttng/event.h>
6a751b95 23#include <lttng/log-level-rule.h>
138d6838
JR
24
25#define IS_LOG4J_LOGGING_EVENT_RULE(rule) \
26 (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING)
27
28static void lttng_event_rule_log4j_logging_destroy(struct lttng_event_rule *rule)
29{
30 struct lttng_event_rule_log4j_logging *log4j_logging;
31
cd9adb8b 32 if (rule == nullptr) {
138d6838
JR
33 return;
34 }
35
28ab034a 36 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
JR
37
38 lttng_log_level_rule_destroy(log4j_logging->log_level_rule);
39 free(log4j_logging->pattern);
40 free(log4j_logging->filter_expression);
41 free(log4j_logging->internal_filter.filter);
42 free(log4j_logging->internal_filter.bytecode);
43 free(log4j_logging);
44}
45
28ab034a 46static bool lttng_event_rule_log4j_logging_validate(const struct lttng_event_rule *rule)
138d6838
JR
47{
48 bool valid = false;
49 struct lttng_event_rule_log4j_logging *log4j_logging;
50
51 if (!rule) {
52 goto end;
53 }
54
28ab034a 55 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
JR
56
57 /* Required field. */
58 if (!log4j_logging->pattern) {
59 ERR("Invalid log4j_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_log4j_logging_serialize(const struct lttng_event_rule *rule,
69 struct lttng_payload *payload)
138d6838
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_log4j_logging *log4j_logging;
75 struct lttng_event_rule_log4j_logging_comm log4j_logging_comm;
76 struct lttng_event_rule_log4j_logging_comm *header;
77
78 if (!rule || !IS_LOG4J_LOGGING_EVENT_RULE(rule)) {
79 ret = -1;
80 goto end;
81 }
82
83 header_offset = payload->buffer.size;
84
85 DBG("Serializing log4j_logging event rule.");
28ab034a 86 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
JR
87
88 pattern_len = strlen(log4j_logging->pattern) + 1;
89
cd9adb8b 90 if (log4j_logging->filter_expression != nullptr) {
28ab034a 91 filter_expression_len = strlen(log4j_logging->filter_expression) + 1;
138d6838
JR
92 } else {
93 filter_expression_len = 0;
94 }
95
96 log4j_logging_comm.pattern_len = pattern_len;
97 log4j_logging_comm.filter_expression_len = filter_expression_len;
98
28ab034a
JG
99 ret = lttng_dynamic_buffer_append(
100 &payload->buffer, &log4j_logging_comm, sizeof(log4j_logging_comm));
138d6838
JR
101 if (ret) {
102 goto end;
103 }
104
28ab034a 105 ret = lttng_dynamic_buffer_append(&payload->buffer, log4j_logging->pattern, pattern_len);
138d6838
JR
106 if (ret) {
107 goto end;
108 }
109
28ab034a
JG
110 ret = lttng_dynamic_buffer_append(
111 &payload->buffer, log4j_logging->filter_expression, filter_expression_len);
138d6838
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(log4j_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;
138d6838
JR
125
126end:
127 return ret;
128}
129
28ab034a
JG
130static bool lttng_event_rule_log4j_logging_is_equal(const struct lttng_event_rule *_a,
131 const struct lttng_event_rule *_b)
138d6838
JR
132{
133 bool is_equal = false;
134 struct lttng_event_rule_log4j_logging *a, *b;
135
0114db0e
JG
136 a = lttng::utils::container_of(_a, &lttng_event_rule_log4j_logging::parent);
137 b = lttng::utils::container_of(_b, &lttng_event_rule_log4j_logging::parent);
138d6838
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);
138d6838
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)) {
138d6838
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)
138d6838
JR
178{
179 int err;
180 int ret = 0;
cd9adb8b 181 char *agent_filter = nullptr;
138d6838
JR
182 const char *pattern;
183 const char *filter;
cd9adb8b 184 const struct lttng_log_level_rule *log_level_rule = nullptr;
138d6838
JR
185 enum lttng_event_rule_status status;
186
a0377dfe
FD
187 LTTNG_ASSERT(rule);
188 LTTNG_ASSERT(_agent_filter);
138d6838
JR
189
190 status = lttng_event_rule_log4j_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_log4j_logging_get_filter(rule, &filter);
197 if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
cd9adb8b 198 filter = nullptr;
138d6838
JR
199 } else if (status != LTTNG_EVENT_RULE_STATUS_OK) {
200 ret = -1;
201 goto end;
202 }
203
138d6838
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);
138d6838 209 } else {
28ab034a 210 err = asprintf(&agent_filter, "logger_name == \"%s\"", pattern);
138d6838
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_log4j_logging_get_log_level_rule(rule, &log_level_rule);
138d6838
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)) {
138d6838 227 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
28ab034a 228 llr_status = lttng_log_level_rule_exactly_get_level(log_level_rule, &level);
138d6838
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);
138d6838
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);
138d6838
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);
138d6838
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;
138d6838
JR
270
271end:
272 free(agent_filter);
273 return ret;
274}
275
276static enum lttng_error_code
28ab034a
JG
277lttng_event_rule_log4j_logging_generate_filter_bytecode(struct lttng_event_rule *rule,
278 const struct lttng_credentials *creds)
138d6838
JR
279{
280 int ret;
281 enum lttng_error_code ret_code;
282 struct lttng_event_rule_log4j_logging *log4j_logging;
283 enum lttng_event_rule_status status;
284 const char *filter;
cd9adb8b 285 struct lttng_bytecode *bytecode = nullptr;
138d6838
JR
286 char *agent_filter;
287
a0377dfe 288 LTTNG_ASSERT(rule);
138d6838 289
28ab034a 290 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
JR
291
292 status = lttng_event_rule_log4j_logging_get_filter(rule, &filter);
293 if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
cd9adb8b 294 filter = nullptr;
138d6838
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 log4j_logging->internal_filter.filter = agent_filter;
312
cd9adb8b 313 if (log4j_logging->internal_filter.filter == nullptr) {
138d6838
JR
314 ret_code = LTTNG_OK;
315 goto end;
316 }
317
318 ret = run_as_generate_filter_bytecode(
28ab034a 319 log4j_logging->internal_filter.filter, creds, &bytecode);
138d6838
JR
320 if (ret) {
321 ret_code = LTTNG_ERR_FILTER_INVAL;
322 goto end;
323 }
324
325 log4j_logging->internal_filter.bytecode = bytecode;
cd9adb8b 326 bytecode = nullptr;
138d6838
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_log4j_logging_get_internal_filter(const struct lttng_event_rule *rule)
138d6838
JR
337{
338 struct lttng_event_rule_log4j_logging *log4j_logging;
339
a0377dfe 340 LTTNG_ASSERT(rule);
28ab034a 341 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
JR
342 return log4j_logging->internal_filter.filter;
343}
344
345static const struct lttng_bytecode *
28ab034a 346lttng_event_rule_log4j_logging_get_internal_filter_bytecode(const struct lttng_event_rule *rule)
138d6838
JR
347{
348 struct lttng_event_rule_log4j_logging *log4j_logging;
349
a0377dfe 350 LTTNG_ASSERT(rule);
28ab034a 351 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
JR
352 return log4j_logging->internal_filter.bytecode;
353}
354
355static enum lttng_event_rule_generate_exclusions_status
28ab034a
JG
356lttng_event_rule_log4j_logging_generate_exclusions(const struct lttng_event_rule *rule
357 __attribute__((unused)),
358 struct lttng_event_exclusion **_exclusions)
138d6838
JR
359{
360 /* Unsupported. */
cd9adb8b 361 *_exclusions = nullptr;
138d6838
JR
362 return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE;
363}
364
28ab034a 365static unsigned long lttng_event_rule_log4j_logging_hash(const struct lttng_event_rule *rule)
138d6838
JR
366{
367 unsigned long hash;
368 struct lttng_event_rule_log4j_logging *tp_rule =
28ab034a 369 lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838 370
28ab034a 371 hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING, lttng_ht_seed);
138d6838
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_log4j_logging_generate_lttng_event(const struct lttng_event_rule *rule)
138d6838
JR
387{
388 int ret;
389 const struct lttng_event_rule_log4j_logging *log4j_logging;
cd9adb8b
JG
390 struct lttng_event *local_event = nullptr;
391 struct lttng_event *event = nullptr;
138d6838
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 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838 398
64803277 399 local_event = zmalloc<lttng_event>();
138d6838
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, log4j_logging->pattern, sizeof(local_event->name));
138d6838
JR
406 if (ret) {
407 ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'",
28ab034a 408 log4j_logging->pattern);
138d6838
JR
409 goto error;
410 }
411
138d6838 412 /* Map the log level rule to an equivalent lttng_loglevel. */
28ab034a 413 status = lttng_event_rule_log4j_logging_get_log_level_rule(rule, &log_level_rule);
138d6838
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);
138d6838
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);
138d6838
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;
138d6838
JR
448error:
449 free(local_event);
450 return event;
451}
452
28ab034a
JG
453static enum lttng_error_code
454lttng_event_rule_log4j_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;
cd9adb8b
JG
460 const char *filter = nullptr;
461 const char *name_pattern = nullptr;
462 const struct lttng_log_level_rule *log_level_rule = nullptr;
6a751b95 463
a0377dfe
FD
464 LTTNG_ASSERT(rule);
465 LTTNG_ASSERT(writer);
466 LTTNG_ASSERT(IS_LOG4J_LOGGING_EVENT_RULE(rule));
6a751b95 467
28ab034a 468 status = lttng_event_rule_log4j_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_log4j_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_log4j_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 log4j logging element. */
28ab034a 481 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_rule_log4j_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. */
cd9adb8b 494 if (filter != nullptr) {
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 log4j 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
138d6838
JR
525struct lttng_event_rule *lttng_event_rule_log4j_logging_create(void)
526{
cd9adb8b 527 struct lttng_event_rule *rule = nullptr;
138d6838
JR
528 struct lttng_event_rule_log4j_logging *tp_rule;
529 enum lttng_event_rule_status status;
530
64803277 531 tp_rule = zmalloc<lttng_event_rule_log4j_logging>();
138d6838
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_LOG4J_LOGGING);
538 tp_rule->parent.validate = lttng_event_rule_log4j_logging_validate;
539 tp_rule->parent.serialize = lttng_event_rule_log4j_logging_serialize;
540 tp_rule->parent.equal = lttng_event_rule_log4j_logging_is_equal;
541 tp_rule->parent.destroy = lttng_event_rule_log4j_logging_destroy;
542 tp_rule->parent.generate_filter_bytecode =
28ab034a
JG
543 lttng_event_rule_log4j_logging_generate_filter_bytecode;
544 tp_rule->parent.get_filter = lttng_event_rule_log4j_logging_get_internal_filter;
138d6838 545 tp_rule->parent.get_filter_bytecode =
28ab034a
JG
546 lttng_event_rule_log4j_logging_get_internal_filter_bytecode;
547 tp_rule->parent.generate_exclusions = lttng_event_rule_log4j_logging_generate_exclusions;
138d6838 548 tp_rule->parent.hash = lttng_event_rule_log4j_logging_hash;
28ab034a 549 tp_rule->parent.generate_lttng_event = lttng_event_rule_log4j_logging_generate_lttng_event;
6a751b95 550 tp_rule->parent.mi_serialize = lttng_event_rule_log4j_logging_mi_serialize;
138d6838 551
cd9adb8b 552 tp_rule->log_level_rule = nullptr;
138d6838
JR
553
554 /* Default pattern is '*'. */
555 status = lttng_event_rule_log4j_logging_set_name_pattern(rule, "*");
556 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
557 lttng_event_rule_destroy(rule);
cd9adb8b 558 rule = nullptr;
138d6838
JR
559 }
560
561end:
562 return rule;
563}
564
28ab034a
JG
565ssize_t lttng_event_rule_log4j_logging_create_from_payload(struct lttng_payload_view *view,
566 struct lttng_event_rule **_event_rule)
138d6838
JR
567{
568 ssize_t ret, offset = 0;
569 enum lttng_event_rule_status status;
570 const struct lttng_event_rule_log4j_logging_comm *log4j_logging_comm;
571 const char *pattern;
cd9adb8b 572 const char *filter_expression = nullptr;
138d6838 573 struct lttng_buffer_view current_buffer_view;
cd9adb8b
JG
574 struct lttng_event_rule *rule = nullptr;
575 struct lttng_log_level_rule *log_level_rule = nullptr;
138d6838
JR
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(*log4j_logging_comm));
138d6838
JR
584 if (!lttng_buffer_view_is_valid(&current_buffer_view)) {
585 ERR("Failed to initialize from malformed event rule log4j_logging: buffer too short to contain header.");
586 ret = -1;
587 goto end;
588 }
589
590 log4j_logging_comm = (typeof(log4j_logging_comm)) current_buffer_view.data;
591
592 rule = lttng_event_rule_log4j_logging_create();
593 if (!rule) {
594 ERR("Failed to create event rule log4j_logging.");
595 ret = -1;
596 goto end;
597 }
598
599 /* Skip to payload. */
600 offset += current_buffer_view.size;
601
602 /* Map the pattern. */
28ab034a
JG
603 current_buffer_view =
604 lttng_buffer_view_from_view(&view->buffer, offset, log4j_logging_comm->pattern_len);
138d6838
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, log4j_logging_comm->pattern_len)) {
138d6838
JR
614 ret = -1;
615 goto end;
616 }
617
618 /* Skip after the pattern. */
619 offset += log4j_logging_comm->pattern_len;
620
621 if (!log4j_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, log4j_logging_comm->filter_expression_len);
138d6838
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 log4j_logging_comm->filter_expression_len)) {
138d6838
JR
637 ret = -1;
638 goto end;
639 }
640
641 /* Skip after the pattern. */
642 offset += log4j_logging_comm->filter_expression_len;
643
644skip_filter_expression:
645 if (!log4j_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, log4j_logging_comm->log_level_rule_len);
138d6838 653
28ab034a
JG
654 ret = lttng_log_level_rule_create_from_payload(&current_payload_view,
655 &log_level_rule);
138d6838
JR
656 if (ret < 0) {
657 ret = -1;
658 goto end;
659 }
660
a0377dfe 661 LTTNG_ASSERT(ret == log4j_logging_comm->log_level_rule_len);
138d6838
JR
662 }
663
664 /* Skip after the log level rule. */
665 offset += log4j_logging_comm->log_level_rule_len;
666
667skip_log_level_rule:
668
669 status = lttng_event_rule_log4j_logging_set_name_pattern(rule, pattern);
670 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
671 ERR("Failed to set event rule log4j_logging pattern.");
672 ret = -1;
673 goto end;
674 }
675
676 if (filter_expression) {
28ab034a 677 status = lttng_event_rule_log4j_logging_set_filter(rule, filter_expression);
138d6838
JR
678 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
679 ERR("Failed to set event rule log4j_logging pattern.");
680 ret = -1;
681 goto end;
682 }
683 }
684
685 if (log_level_rule) {
28ab034a 686 status = lttng_event_rule_log4j_logging_set_log_level_rule(rule, log_level_rule);
138d6838
JR
687 if (status != LTTNG_EVENT_RULE_STATUS_OK) {
688 ERR("Failed to set event rule log4j_logging log level rule.");
689 ret = -1;
690 goto end;
691 }
692 }
693
694 *_event_rule = rule;
cd9adb8b 695 rule = nullptr;
138d6838
JR
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_log4j_logging_set_name_pattern(struct lttng_event_rule *rule, const char *pattern)
138d6838 705{
cd9adb8b 706 char *pattern_copy = nullptr;
138d6838
JR
707 struct lttng_event_rule_log4j_logging *log4j_logging;
708 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
709
28ab034a 710 if (!rule || !IS_LOG4J_LOGGING_EVENT_RULE(rule) || !pattern || strlen(pattern) == 0) {
138d6838
JR
711 status = LTTNG_EVENT_RULE_STATUS_INVALID;
712 goto end;
713 }
714
28ab034a 715 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
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(log4j_logging->pattern);
726
727 log4j_logging->pattern = pattern_copy;
cd9adb8b 728 pattern_copy = nullptr;
138d6838
JR
729end:
730 return status;
731}
732
28ab034a
JG
733enum lttng_event_rule_status
734lttng_event_rule_log4j_logging_get_name_pattern(const struct lttng_event_rule *rule,
735 const char **pattern)
138d6838
JR
736{
737 struct lttng_event_rule_log4j_logging *log4j_logging;
738 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
739
740 if (!rule || !IS_LOG4J_LOGGING_EVENT_RULE(rule) || !pattern) {
741 status = LTTNG_EVENT_RULE_STATUS_INVALID;
742 goto end;
743 }
744
28ab034a 745 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
JR
746 if (!log4j_logging->pattern) {
747 status = LTTNG_EVENT_RULE_STATUS_UNSET;
748 goto end;
749 }
750
751 *pattern = log4j_logging->pattern;
752end:
753 return status;
754}
755
28ab034a
JG
756enum lttng_event_rule_status
757lttng_event_rule_log4j_logging_set_filter(struct lttng_event_rule *rule, const char *expression)
138d6838 758{
cd9adb8b 759 char *expression_copy = nullptr;
138d6838
JR
760 struct lttng_event_rule_log4j_logging *log4j_logging;
761 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
762
28ab034a 763 if (!rule || !IS_LOG4J_LOGGING_EVENT_RULE(rule) || !expression || strlen(expression) == 0) {
138d6838
JR
764 status = LTTNG_EVENT_RULE_STATUS_INVALID;
765 goto end;
766 }
767
28ab034a 768 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
JR
769 expression_copy = strdup(expression);
770 if (!expression_copy) {
771 PERROR("Failed to copy filter expression");
772 status = LTTNG_EVENT_RULE_STATUS_ERROR;
773 goto end;
774 }
775
776 if (log4j_logging->filter_expression) {
777 free(log4j_logging->filter_expression);
778 }
779
780 log4j_logging->filter_expression = expression_copy;
cd9adb8b 781 expression_copy = nullptr;
138d6838
JR
782end:
783 return status;
784}
785
28ab034a
JG
786enum lttng_event_rule_status
787lttng_event_rule_log4j_logging_get_filter(const struct lttng_event_rule *rule,
788 const char **expression)
138d6838
JR
789{
790 struct lttng_event_rule_log4j_logging *log4j_logging;
791 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
792
793 if (!rule || !IS_LOG4J_LOGGING_EVENT_RULE(rule) || !expression) {
794 status = LTTNG_EVENT_RULE_STATUS_INVALID;
795 goto end;
796 }
797
28ab034a 798 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
JR
799 if (!log4j_logging->filter_expression) {
800 status = LTTNG_EVENT_RULE_STATUS_UNSET;
801 goto end;
802 }
803
804 *expression = log4j_logging->filter_expression;
805end:
806 return status;
807}
808
28ab034a 809static bool log_level_rule_valid(const struct lttng_log_level_rule *rule __attribute__((unused)))
138d6838
JR
810{
811 /*
812 * For both LOG4J custom log level are possible and can
813 * span the entire int32 range.
814 */
815 return true;
816}
817
28ab034a
JG
818enum lttng_event_rule_status
819lttng_event_rule_log4j_logging_set_log_level_rule(struct lttng_event_rule *rule,
820 const struct lttng_log_level_rule *log_level_rule)
138d6838
JR
821{
822 struct lttng_event_rule_log4j_logging *log4j_logging;
823 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
cd9adb8b 824 struct lttng_log_level_rule *copy = nullptr;
138d6838
JR
825
826 if (!rule || !IS_LOG4J_LOGGING_EVENT_RULE(rule)) {
827 status = LTTNG_EVENT_RULE_STATUS_INVALID;
828 goto end;
829 }
830
28ab034a 831 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
138d6838
JR
832
833 if (!log_level_rule_valid(log_level_rule)) {
834 status = LTTNG_EVENT_RULE_STATUS_INVALID;
835 goto end;
836 }
837
838 copy = lttng_log_level_rule_copy(log_level_rule);
cd9adb8b 839 if (copy == nullptr) {
138d6838
JR
840 status = LTTNG_EVENT_RULE_STATUS_ERROR;
841 goto end;
842 }
843
844 if (log4j_logging->log_level_rule) {
845 lttng_log_level_rule_destroy(log4j_logging->log_level_rule);
846 }
847
848 log4j_logging->log_level_rule = copy;
849
850end:
851 return status;
852}
853
854enum lttng_event_rule_status lttng_event_rule_log4j_logging_get_log_level_rule(
28ab034a 855 const struct lttng_event_rule *rule, const struct lttng_log_level_rule **log_level_rule)
138d6838
JR
856{
857 struct lttng_event_rule_log4j_logging *log4j_logging;
858 enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
859
860 if (!rule || !IS_LOG4J_LOGGING_EVENT_RULE(rule) || !log_level_rule) {
861 status = LTTNG_EVENT_RULE_STATUS_INVALID;
862 goto end;
863 }
864
28ab034a 865 log4j_logging = lttng::utils::container_of(rule, &lttng_event_rule_log4j_logging::parent);
cd9adb8b 866 if (log4j_logging->log_level_rule == nullptr) {
138d6838
JR
867 status = LTTNG_EVENT_RULE_STATUS_UNSET;
868 goto end;
869 }
870
871 *log_level_rule = log4j_logging->log_level_rule;
872end:
873 return status;
874}
This page took 0.076642 seconds and 4 git commands to generate.