lttng/event-rule/kernel-tracepoint.h \
lttng/event-rule/kernel-uprobe.h \
lttng/event-rule/log4j-logging.h \
+ lttng/event-rule/log4j2-logging.h \
lttng/event-rule/python-logging.h \
lttng/event-rule/user-tracepoint.h
lttng/event-rule/kernel-tracepoint-internal.hpp \
lttng/event-rule/kernel-uprobe-internal.hpp \
lttng/event-rule/log4j-logging-internal.hpp \
+ lttng/event-rule/log4j2-logging-internal.hpp \
lttng/event-rule/python-logging-internal.hpp \
lttng/event-rule/user-tracepoint-internal.hpp \
lttng/health-internal.hpp \
/// <code>java.util.logging</code> (JUL).
LTTNG_DOMAIN_JUL = 3,
- /// Apache log4j.
+ /// Apache Log4j 1.x.
LTTNG_DOMAIN_LOG4J = 4,
/// Python logging.
LTTNG_DOMAIN_PYTHON = 5,
+
+ /// Apache Log4j 2.
+ LTTNG_DOMAIN_LOG4J2 = 6,
};
/*!
LTTNG_EVENT_RULE_TYPE_JUL_LOGGING = 5,
LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING = 6,
LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING = 7,
+ LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING = 8,
};
enum lttng_event_rule_status {
#include <lttng/event.h>
#include <lttng/log-level-rule-internal.hpp>
+#define LTTNG_JUL_EVENT_RULE_AT_LEAST_AS_SEVERE_AS_OP ">="
+
struct lttng_event_rule_jul_logging {
struct lttng_event_rule parent;
#include <lttng/event.h>
#include <lttng/log-level-rule-internal.hpp>
+#define LTTNG_LOG4J_EVENT_RULE_AT_LEAST_AS_SEVERE_AS_OP ">="
+
struct lttng_event_rule_log4j_logging {
struct lttng_event_rule parent;
--- /dev/null
+/*
+ * Copyright (C) 2024 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_EVENT_RULE_LOG4J2_LOGGING_INTERNAL_H
+#define LTTNG_EVENT_RULE_LOG4J2_LOGGING_INTERNAL_H
+
+#include <common/macros.hpp>
+#include <common/optional.hpp>
+#include <common/payload-view.hpp>
+
+#include <lttng/event-rule/event-rule-internal.hpp>
+#include <lttng/event-rule/log4j2-logging.h>
+#include <lttng/event.h>
+#include <lttng/log-level-rule-internal.hpp>
+
+#define LTTNG_LOG4J2_EVENT_RULE_AT_LEAST_AS_SEVERE_AS_OP "<="
+
+struct lttng_event_rule_log4j2_logging {
+ struct lttng_event_rule parent;
+
+ /* Name pattern. */
+ char *pattern;
+
+ /* Filter. */
+ char *filter_expression;
+
+ /* Log level. */
+ struct lttng_log_level_rule *log_level_rule;
+
+ /* internal use only. */
+ struct {
+ char *filter;
+ struct lttng_bytecode *bytecode;
+ } internal_filter;
+};
+
+struct lttng_event_rule_log4j2_logging_comm {
+ /* Includes terminator `\0`. */
+ uint32_t pattern_len;
+ /* Includes terminator `\0`. */
+ uint32_t filter_expression_len;
+ /* enum lttng_log_level_rule_comm + payload if any */
+ uint32_t log_level_rule_len;
+ /*
+ * Payload is composed of, in that order:
+ * - pattern (null terminated),
+ * - filter expression (null terminated),
+ * - log level rule serialized object,
+ */
+ char payload[];
+} LTTNG_PACKED;
+
+ssize_t lttng_event_rule_log4j2_logging_create_from_payload(struct lttng_payload_view *view,
+ struct lttng_event_rule **rule);
+
+#endif /* LTTNG_EVENT_RULE_LOG4J2_LOGGING_INTERNAL_H */
--- /dev/null
+/*
+ * Copyright (C) 2024 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_EVENT_RULE_LOG4J2_LOGGING_H
+#define LTTNG_EVENT_RULE_LOG4J2_LOGGING_H
+
+#include <lttng/event-rule/event-rule.h>
+#include <lttng/event.h>
+#include <lttng/log-level-rule.h>
+#include <lttng/lttng-export.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Create a newly allocated log4j2 logging event rule.
+ *
+ * The default name pattern is '*'.
+ *
+ * Returns a new event rule on success, NULL on failure. This event rule must be
+ * destroyed using lttng_event_rule_destroy().
+ */
+LTTNG_EXPORT extern struct lttng_event_rule *lttng_event_rule_log4j2_logging_create(void);
+
+/*
+ * Set the name pattern of a log4j2 logging event rule.
+ *
+ * Pattern can contain wildcard '*'. See man lttng-enable-event.
+ *
+ * Return LTTNG_EVENT_RULE_STATUS_OK on success, LTTNG_EVENT_RULE_STATUS_INVALID
+ * if invalid parameters are passed.
+ */
+LTTNG_EXPORT extern enum lttng_event_rule_status
+lttng_event_rule_log4j2_logging_set_name_pattern(struct lttng_event_rule *rule,
+ const char *pattern);
+
+/*
+ * Get the name pattern of a log4j2 logging event rule.
+ *
+ * The caller does not assume the ownership of the returned pattern. The
+ * pattern shall only only be used for the duration of the event rule's
+ * lifetime, or before a different pattern is set.
+ *
+ * Returns LTTNG_EVENT_RULE_STATUS_OK and a pointer to the event rule's pattern
+ * on success, LTTNG_EVENT_RULE_STATUS_INVALID if an invalid
+ * parameter is passed, or LTTNG_EVENT_RULE_STATUS_UNSET if a pattern
+ * was not set prior to this call.
+ */
+LTTNG_EXPORT extern enum lttng_event_rule_status
+lttng_event_rule_log4j2_logging_get_name_pattern(const struct lttng_event_rule *rule,
+ const char **pattern);
+
+/*
+ * Set the filter expression of a log4j2 logging event rule.
+ *
+ * The expression is copied internally.
+ *
+ * Return LTTNG_EVENT_RULE_STATUS_OK on success, LTTNG_EVENT_RULE_STATUS_INVALID
+ * if invalid parameters are passed.
+ */
+LTTNG_EXPORT extern enum lttng_event_rule_status
+lttng_event_rule_log4j2_logging_set_filter(struct lttng_event_rule *rule, const char *expression);
+
+/*
+ * Get the filter expression of a log4j2 logging event rule.
+ *
+ * The caller does not assume the ownership of the returned filter expression.
+ * The filter expression shall only only be used for the duration of the event
+ * rule's lifetime, or before a different filter expression is set.
+ *
+ * Returns LTTNG_EVENT_RULE_STATUS_OK and a pointer to the event rule's filter
+ * expression on success, LTTNG_EVENT_RULE_STATUS_INVALID if an invalid
+ * parameter is passed, or LTTNG_EVENT_RULE_STATUS_UNSET if a filter expression
+ * was not set prior to this call.
+ */
+LTTNG_EXPORT extern enum lttng_event_rule_status
+lttng_event_rule_log4j2_logging_get_filter(const struct lttng_event_rule *rule,
+ const char **expression);
+
+/*
+ * Set the log level rule of a log4j2 logging event rule.
+ *
+ * The log level rule is copied internally.
+ *
+ * Return LTTNG_EVENT_RULE_STATUS_OK on success, LTTNG_EVENT_RULE_STATUS_INVALID
+ * if invalid parameters are passed.
+ */
+LTTNG_EXPORT extern enum lttng_event_rule_status lttng_event_rule_log4j2_logging_set_log_level_rule(
+ struct lttng_event_rule *rule, const struct lttng_log_level_rule *log_level_rule);
+
+/*
+ * Get the log level rule of a log4j2 logging event rule.
+ *
+ * The caller does not assume the ownership of the returned log level rule. The
+ * log level rule shall only only be used for the duration of the event rule's
+ * lifetime, or before a different log level rule is set.
+ *
+ * Returns LTTNG_EVENT_RULE_STATUS_OK and sets the log level rule output
+ * parameter on success, LTTNG_EVENT_RULE_STATUS_INVALID if an invalid parameter
+ * is passed, or LTTNG_EVENT_RULE_STATUS_UNSET if a log level rule was not set prior
+ * to this call.
+ */
+LTTNG_EXPORT extern enum lttng_event_rule_status lttng_event_rule_log4j2_logging_get_log_level_rule(
+ const struct lttng_event_rule *rule, const struct lttng_log_level_rule **log_level_rule);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LTTNG_EVENT_RULE_LOG4J2_LOGGING_H */
Value of the
\ref api-rer-conds-ll "instrumentation point log level condition"
of an
- \link #LTTNG_DOMAIN_LOG4J Apache log4j\endlink
+ \link #LTTNG_DOMAIN_LOG4J Apache Log4j 1.x\endlink
recording event rule.
@ingroup api_rer
LTTNG_LOGLEVEL_LOG4J_ALL = INT32_MIN,
};
+/*!
+@brief
+ Value of the
+ \ref api-rer-conds-ll "instrumentation point log level condition"
+ of a
+ \link #LTTNG_DOMAIN_LOG4J2 Apache Log4j 2\endlink
+ recording event rule.
+
+@ingroup api_rer
+
+@sa #lttng_loglevel_type --
+ Operand of the log level condition of a recording event rule.
+*/
+enum lttng_loglevel_log4j2 {
+ /// Logging turned off.
+ LTTNG_LOGLEVEL_LOG4J2_OFF = 0,
+
+ /*!
+ Very severe error events that will presumably lead the
+ application to abort.
+ */
+ LTTNG_LOGLEVEL_LOG4J2_FATAL = 100,
+
+ /*!
+ Error events that might still allow the application to continue
+ running.
+ */
+ LTTNG_LOGLEVEL_LOG4J2_ERROR = 200,
+
+ /// Potentially harmful situations.
+ LTTNG_LOGLEVEL_LOG4J2_WARN = 300,
+
+ /*!
+ Informational messages that highlight the progress of the
+ application at coarse-grained level.
+ */
+ LTTNG_LOGLEVEL_LOG4J2_INFO = 400,
+
+ /*!
+ Fine-grained informational events that are most useful to debug
+ an application.
+ */
+ LTTNG_LOGLEVEL_LOG4J2_DEBUG = 500,
+
+ /*!
+ Finer-grained informational events than the
+ #LTTNG_LOGLEVEL_LOG4J2_DEBUG level.
+ */
+ LTTNG_LOGLEVEL_LOG4J2_TRACE = 600,
+
+ /// All levels, including custom levels.
+ LTTNG_LOGLEVEL_LOG4J2_ALL = INT32_MAX,
+};
+
/*!
@brief
Value of the
#include <lttng/event-rule/kernel-tracepoint.h>
#include <lttng/event-rule/kernel-uprobe.h>
#include <lttng/event-rule/log4j-logging.h>
+#include <lttng/event-rule/log4j2-logging.h>
#include <lttng/event-rule/python-logging.h>
#include <lttng/event-rule/user-tracepoint.h>
#include <lttng/event.h>
return "jul";
case LTTNG_DOMAIN_LOG4J:
return "log4j";
+ case LTTNG_DOMAIN_LOG4J2:
+ return "log4j2";
case LTTNG_DOMAIN_PYTHON:
return "python";
default:
#include <lttng/event-rule/event-rule.h>
#include <lttng/event-rule/jul-logging.h>
#include <lttng/event-rule/log4j-logging.h>
+#include <lttng/event-rule/log4j2-logging.h>
#include <lttng/event-rule/python-logging.h>
#include <lttng/log-level-rule-internal.hpp>
logging_get_name_pattern = lttng_event_rule_log4j_logging_get_name_pattern;
logging_get_log_level_rule = lttng_event_rule_log4j_logging_get_log_level_rule;
break;
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
+ logging_get_name_pattern = lttng_event_rule_log4j2_logging_get_name_pattern;
+ logging_get_log_level_rule = lttng_event_rule_log4j2_logging_get_log_level_rule;
+ break;
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
logging_get_name_pattern = lttng_event_rule_python_logging_get_name_pattern;
logging_get_log_level_rule = lttng_event_rule_python_logging_get_log_level_rule;
domain = lttng_event_rule_get_domain_type(rule);
LTTNG_ASSERT(domain == LTTNG_DOMAIN_JUL || domain == LTTNG_DOMAIN_LOG4J ||
- domain == LTTNG_DOMAIN_PYTHON);
+ domain == LTTNG_DOMAIN_LOG4J2 || domain == LTTNG_DOMAIN_PYTHON);
/* Get the event's pattern name ('name' in the legacy terminology). */
er_status = logging_get_name_pattern(rule, &name);
case LTTNG_DOMAIN_LOG4J:
channel_name = DEFAULT_LOG4J_CHANNEL_NAME;
goto common_ust;
+ case LTTNG_DOMAIN_LOG4J2:
+ channel_name = DEFAULT_LOG4J2_CHANNEL_NAME;
+ goto common_ust;
case LTTNG_DOMAIN_PYTHON:
channel_name = DEFAULT_PYTHON_CHANNEL_NAME;
goto common_ust;
domain = LTTNG_DOMAIN_JUL;
} else if (!strcmp(attr->name, DEFAULT_LOG4J_CHANNEL_NAME)) {
domain = LTTNG_DOMAIN_LOG4J;
+ } else if (!strcmp(attr->name, DEFAULT_LOG4J2_CHANNEL_NAME)) {
+ domain = LTTNG_DOMAIN_LOG4J2;
} else if (!strcmp(attr->name, DEFAULT_PYTHON_CHANNEL_NAME)) {
domain = LTTNG_DOMAIN_PYTHON;
}
break;
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
case LTTNG_DOMAIN_UST:
DBG3("Copying tracing session consumer output in UST session");
switch (domain->type) {
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
case LTTNG_DOMAIN_UST:
break;
break;
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
case LTTNG_DOMAIN_UST:
if (!(*target_session)->ust_session) {
break;
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
if (!agent_tracing_is_enabled()) {
ret = LTTNG_ERR_AGENT_TRACING_DISABLED;
break;
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
case LTTNG_DOMAIN_UST:
if (uatomic_read(&the_ust_consumerd_state) != CONSUMER_STARTED) {
break;
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
if (!agent_tracing_is_enabled()) {
DBG("Attempted to enable a channel in an agent domain but the agent thread is not running");
case LTTNG_DOMAIN_UST:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
{
struct ltt_ust_channel *uchan;
ret_code = LTTNG_ERR_INVALID_CHANNEL_NAME;
goto error;
}
+ } else if (domain->type == LTTNG_DOMAIN_LOG4J2) {
+ if (strncmp(attr->name,
+ DEFAULT_LOG4J2_CHANNEL_NAME,
+ LTTNG_SYMBOL_NAME_LEN - 1) != 0) {
+ ret_code = LTTNG_ERR_INVALID_CHANNEL_NAME;
+ goto error;
+ }
} else if (domain->type == LTTNG_DOMAIN_PYTHON) {
if (strncmp(attr->name,
DEFAULT_PYTHON_CHANNEL_NAME,
break;
}
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_PYTHON:
{
break;
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
{
/*
* Validate channel name.
strcmp(channel_name, DEFAULT_LOG4J_CHANNEL_NAME) != 0) {
ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
goto error;
+ } else if (domain == LTTNG_DOMAIN_LOG4J2 && *channel_name &&
+ strcmp(channel_name, DEFAULT_LOG4J2_CHANNEL_NAME) != 0) {
+ ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
+ goto error;
}
}
/* fall through */
*/
if (name_starts_with(name, DEFAULT_JUL_EVENT_COMPONENT) ||
name_starts_with(name, DEFAULT_LOG4J_EVENT_COMPONENT) ||
+ name_starts_with(name, DEFAULT_LOG4J2_EVENT_COMPONENT) ||
name_starts_with(name, DEFAULT_PYTHON_EVENT_COMPONENT)) {
ret = -1;
}
break;
}
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_PYTHON:
{
case LTTNG_DOMAIN_LOG4J:
default_chan_name = DEFAULT_LOG4J_CHANNEL_NAME;
break;
+ case LTTNG_DOMAIN_LOG4J2:
+ default_chan_name = DEFAULT_LOG4J2_CHANNEL_NAME;
+ break;
case LTTNG_DOMAIN_JUL:
default_chan_name = DEFAULT_JUL_CHANNEL_NAME;
break;
}
break;
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_PYTHON:
nb_events = agent_list_events(&events, domain);
break;
}
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_PYTHON:
if (session->ust_session) {
break;
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
{
/* Agent domains. */
break;
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
{
/* Agent domains. */
switch (domain) {
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
{
struct agent *agt;
case LTTNG_DOMAIN_PYTHON:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
state = &ust_state;
break;
default:
case LTTNG_DOMAIN_PYTHON:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
pthread_mutex_lock(&the_event_notifier_counter.lock);
the_event_notifier_counter.count++;
if (the_event_notifier_counter.count == 1) {
case LTTNG_DOMAIN_PYTHON:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
#ifdef HAVE_LIBLTTNG_UST_CTL
return event_notifier_error_accounting_ust_get_count(trigger, count);
#else
case LTTNG_DOMAIN_PYTHON:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
#ifdef HAVE_LIBLTTNG_UST_CTL
return event_notifier_error_accounting_ust_clear(trigger);
#else
case LTTNG_DOMAIN_PYTHON:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
state = &ust_state;
pthread_mutex_lock(&the_event_notifier_counter.lock);
switch (lttng_event_rule_get_type(rule)) {
case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
break;
default:
case LTTNG_DOMAIN_LOG4J:
default_event_name = DEFAULT_LOG4J_EVENT_NAME;
break;
+ case LTTNG_DOMAIN_LOG4J2:
+ default_event_name = DEFAULT_LOG4J2_EVENT_NAME;
+ break;
case LTTNG_DOMAIN_JUL:
default_event_name = DEFAULT_JUL_EVENT_NAME;
break;
ust_channel_name = DEFAULT_JUL_CHANNEL_NAME;
} else if (agt->domain == LTTNG_DOMAIN_LOG4J) {
ust_channel_name = DEFAULT_LOG4J_CHANNEL_NAME;
+ } else if (agt->domain == LTTNG_DOMAIN_LOG4J2) {
+ ust_channel_name = DEFAULT_LOG4J2_CHANNEL_NAME;
} else if (agt->domain == LTTNG_DOMAIN_PYTHON) {
ust_channel_name = DEFAULT_PYTHON_CHANNEL_NAME;
} else {
case LTTNG_DOMAIN_LOG4J:
str_dom = config_domain_type_log4j;
break;
+ case LTTNG_DOMAIN_LOG4J2:
+ str_dom = config_domain_type_log4j2;
+ break;
case LTTNG_DOMAIN_PYTHON:
str_dom = config_domain_type_python;
break;
}
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
default:
ret = LTTNG_ERR_UNSUPPORTED_DOMAIN;
goto end;
}
+ ret = save_ust_domain(writer, session, LTTNG_DOMAIN_LOG4J2);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+
ret = save_ust_domain(writer, session, LTTNG_DOMAIN_PYTHON);
if (ret != LTTNG_OK) {
goto end;
bool enabled;
/*
* A UST channel can be part of a userspace sub-domain such as JUL,
- * Log4j, Python.
+ * Log4j, Log4j2, Python.
*/
enum lttng_domain_type domain;
char name[LTTNG_UST_ABI_SYM_NAME_LEN];
LTTNG_ASSERT(event_rule_type == LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT ||
event_rule_type == LTTNG_EVENT_RULE_TYPE_JUL_LOGGING ||
event_rule_type == LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING ||
+ event_rule_type == LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING ||
event_rule_type == LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING);
init_ust_event_notifier_from_event_rule(event_rule, &event_notifier);
static int opt_userspace;
static int opt_jul;
static int opt_log4j;
+static int opt_log4j2;
static char *opt_type;
#ifdef LTTNG_EMBED_HELP
OPT_USERSPACE,
OPT_JUL,
OPT_LOG4J,
+ OPT_LOG4J2,
OPT_LIST_OPTIONS,
OPT_LIST,
};
{ "userspace", 'u', POPT_ARG_NONE, nullptr, OPT_USERSPACE, nullptr, nullptr },
{ "jul", 'j', POPT_ARG_NONE, nullptr, OPT_JUL, nullptr, nullptr },
{ "log4j", 'l', POPT_ARG_NONE, nullptr, OPT_LOG4J, nullptr, nullptr },
+ { "log4j2", 0, POPT_ARG_NONE, nullptr, OPT_LOG4J2, nullptr, nullptr },
{ "type", 't', POPT_ARG_STRING, &opt_type, OPT_TYPE, nullptr, nullptr },
{ "list", 0, POPT_ARG_NONE, nullptr, OPT_LIST, nullptr, nullptr },
{ "list-options", 0, POPT_ARG_NONE, nullptr, OPT_LIST_OPTIONS, nullptr, nullptr },
return LTTNG_DOMAIN_JUL;
} else if (opt_log4j) {
return LTTNG_DOMAIN_LOG4J;
+ } else if (opt_log4j2) {
+ return LTTNG_DOMAIN_LOG4J2;
} else {
abort();
}
case OPT_LOG4J:
opt_log4j = 1;
break;
+ case OPT_LOG4J2:
+ opt_log4j2 = 1;
+ break;
case OPT_LIST_OPTIONS:
list_cmd_options(stdout, long_options);
goto end;
goto end;
}
- ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace + opt_jul + opt_log4j,
- true);
+ ret = print_missing_or_multiple_domains(
+ opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_log4j2, true);
if (ret) {
ret = CMD_ERROR;
goto end;
*dest = LTTNG_EVENT_RULE_TYPE_JUL_LOGGING;
} else if (strcmp(arg, "log4j") == 0 || strcmp(arg, "log4j:logging") == 0) {
*dest = LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING;
+ } else if (strcmp(arg, "log4j2") == 0 || strcmp(arg, "log4j2:logging") == 0) {
+ *dest = LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING;
} else if (strcmp(arg, "python") == 0 || strcmp(arg, "python:logging") == 0) {
*dest = LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING;
} else if (strcmp(arg, "kprobe") == 0 || strcmp(arg, "kernel:kprobe") == 0) {
*log_level_only = log_level_min == log_level_max;
break;
}
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
+ {
+ enum lttng_loglevel_log4j2 log_level_min, log_level_max;
+ if (!loglevel_log4j2_parse_range_string(str, &log_level_min, &log_level_max)) {
+ goto error;
+ }
+
+ /* Only support VAL and VAL.. for now. */
+ if (log_level_min != log_level_max &&
+ log_level_max != LTTNG_LOGLEVEL_LOG4J2_FATAL) {
+ goto error;
+ }
+
+ *log_level = (int) log_level_min;
+ *log_level_only = log_level_min == log_level_max;
+ break;
+ }
case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
{
enum lttng_loglevel_jul log_level_min, log_level_max;
/*
* Option --name is applicable to event rules of type kernel, user, jul,
- * log4j,python and syscall. If --name is omitted, it is implicitly
- * "*".
+ * log4j, log4j2, python and syscall. If --name is omitted, it is
+ * implicitly "*".
*/
switch (event_rule_type) {
case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
if (!name) {
case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
break;
case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
{
int log_level;
}
break;
}
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
+ {
+ enum lttng_event_rule_status event_rule_status;
+
+ res.er = lttng_event_rule_log4j2_logging_create();
+ if (!res.er) {
+ ERR("Failed to create log4j2_logging event rule.");
+ goto error;
+ }
+
+ /* Set pattern. */
+ event_rule_status = lttng_event_rule_log4j2_logging_set_name_pattern(res.er, name);
+ if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
+ ERR("Failed to set log4j2_logging event rule's pattern to '%s'.", name);
+ goto error;
+ }
+
+ /* Set filter. */
+ if (filter) {
+ event_rule_status =
+ lttng_event_rule_log4j2_logging_set_filter(res.er, filter);
+ if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
+ ERR("Failed to set log4j2_logging event rule's filter to '%s'.",
+ filter);
+ goto error;
+ }
+ }
+
+ if (log_level_rule) {
+ event_rule_status = lttng_event_rule_log4j2_logging_set_log_level_rule(
+ res.er, log_level_rule);
+
+ if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
+ ERR("Failed to set log level on event fule.");
+ goto error;
+ }
+ }
+ break;
+ }
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
{
enum lttng_event_rule_status event_rule_status;
static int opt_disable_all;
static int opt_jul;
static int opt_log4j;
+static int opt_log4j2;
static int opt_python;
static int opt_event_type;
{ "channel", 'c', POPT_ARG_STRING, &opt_channel_name, 0, nullptr, nullptr },
{ "jul", 'j', POPT_ARG_VAL, &opt_jul, 1, nullptr, nullptr },
{ "log4j", 'l', POPT_ARG_VAL, &opt_log4j, 1, nullptr, nullptr },
+ { "log4j2", 0, POPT_ARG_VAL, &opt_log4j2, 1, nullptr, nullptr },
{ "python", 'p', POPT_ARG_VAL, &opt_python, 1, nullptr, nullptr },
{ "kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, nullptr, nullptr },
{ "userspace", 'u', POPT_ARG_VAL, &opt_userspace, 1, nullptr, nullptr },
dom.type = LTTNG_DOMAIN_JUL;
} else if (opt_log4j) {
dom.type = LTTNG_DOMAIN_LOG4J;
+ } else if (opt_log4j2) {
+ dom.type = LTTNG_DOMAIN_LOG4J2;
} else if (opt_python) {
dom.type = LTTNG_DOMAIN_PYTHON;
} else {
}
ret = print_missing_or_multiple_domains(
- opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python, true);
+ opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_log4j2 + opt_python, true);
if (ret) {
ret = CMD_ERROR;
goto end;
}
/* Ust and agent only support ALL event type */
- if ((opt_userspace || opt_jul || opt_log4j || opt_python) &&
+ if ((opt_userspace || opt_jul || opt_log4j || opt_log4j2 || opt_python) &&
opt_event_type != LTTNG_EVENT_ALL) {
- ERR("Disabling userspace and agent (-j | -l | -p) event(s) based on instrumentation type is not supported.\n");
+ ERR("Disabling userspace and agent event(s) based on instrumentation type is not supported.\n");
ret = CMD_ERROR;
goto end;
}
int opt_userspace;
int opt_jul;
int opt_log4j;
+int opt_log4j2;
int opt_python;
int opt_enable_all;
char *opt_probe;
{ "userspace", 'u', POPT_ARG_NONE, nullptr, OPT_USERSPACE, nullptr, nullptr },
{ "jul", 'j', POPT_ARG_VAL, &opt_jul, 1, nullptr, nullptr },
{ "log4j", 'l', POPT_ARG_VAL, &opt_log4j, 1, nullptr, nullptr },
+ { "log4j2", 0, POPT_ARG_VAL, &opt_log4j2, 1, nullptr, nullptr },
{ "python", 'p', POPT_ARG_VAL, &opt_python, 1, nullptr, nullptr },
{ "tracepoint", 0, POPT_ARG_NONE, nullptr, OPT_TRACEPOINT, nullptr, nullptr },
{ "probe", 0, POPT_ARG_STRING, &opt_probe, OPT_PROBE, nullptr, nullptr },
dom.type = LTTNG_DOMAIN_LOG4J;
/* Default. */
dom.buf_type = LTTNG_BUFFER_PER_UID;
+ } else if (opt_log4j2) {
+ dom.type = LTTNG_DOMAIN_LOG4J2;
+ /* Default. */
+ dom.buf_type = LTTNG_BUFFER_PER_UID;
} else if (opt_python) {
dom.type = LTTNG_DOMAIN_PYTHON;
/* Default. */
case LTTNG_DOMAIN_KERNEL:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
ERR("Event name exclusions are not supported for %s event rules",
lttng_domain_type_str(dom.type));
} else {
ev->loglevel = -1;
}
- } else if (opt_jul || opt_log4j || opt_python) {
+ } else if (opt_jul || opt_log4j || opt_log4j2 || opt_python) {
if (opt_event_type != LTTNG_EVENT_ALL &&
opt_event_type != LTTNG_EVENT_TRACEPOINT) {
ERR("Instrumentation point type not supported for the %s domain",
name_search_ret = loglevel_log4j_name_to_value(opt_loglevel,
&loglevel);
ev->loglevel = (int) loglevel;
+ } else if (opt_log4j2) {
+ enum lttng_loglevel_log4j2 loglevel;
+
+ name_search_ret = loglevel_log4j2_name_to_value(
+ opt_loglevel, &loglevel);
+ ev->loglevel = (int) loglevel;
} else {
/* python domain. */
enum lttng_loglevel_python loglevel;
ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL;
} else if (opt_log4j) {
ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
+ } else if (opt_log4j2) {
+ ev->loglevel = LTTNG_LOGLEVEL_LOG4J2_ALL;
} else if (opt_python) {
ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
}
}
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
/*
* Don't print the default channel
}
ret = print_missing_or_multiple_domains(
- opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python, true);
+ opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_log4j2 + opt_python, true);
if (ret) {
return CMD_ERROR;
}
static int opt_kernel;
static int opt_jul;
static int opt_log4j;
+static int opt_log4j2;
static int opt_python;
static char *opt_channel;
static int opt_domain;
{ "kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, nullptr, nullptr },
{ "jul", 'j', POPT_ARG_VAL, &opt_jul, 1, nullptr, nullptr },
{ "log4j", 'l', POPT_ARG_VAL, &opt_log4j, 1, nullptr, nullptr },
+ { "log4j2", 0, POPT_ARG_VAL, &opt_log4j2, 1, nullptr, nullptr },
{ "python", 'p', POPT_ARG_VAL, &opt_python, 1, nullptr, nullptr },
{ "userspace", 'u', POPT_ARG_NONE, nullptr, OPT_USERSPACE, nullptr, nullptr },
{ "channel", 'c', POPT_ARG_STRING, &opt_channel, 0, nullptr, nullptr },
domain.type = LTTNG_DOMAIN_JUL;
} else if (opt_log4j) {
domain.type = LTTNG_DOMAIN_LOG4J;
+ } else if (opt_log4j2) {
+ domain.type = LTTNG_DOMAIN_LOG4J2;
} else if (opt_python) {
domain.type = LTTNG_DOMAIN_PYTHON;
} else {
MSG(" - UST global");
break;
case LTTNG_DOMAIN_JUL:
- MSG(" - JUL (Java Util Logging)");
+ MSG(" - JUL (java.util.logging)");
break;
case LTTNG_DOMAIN_LOG4J:
- MSG(" - LOG4j (Logging for Java)");
+ MSG(" - Log4j");
+ break;
+ case LTTNG_DOMAIN_LOG4J2:
+ MSG(" - Log4j2");
break;
case LTTNG_DOMAIN_PYTHON:
MSG(" - Python (logging)");
domain.type = LTTNG_DOMAIN_JUL;
} else if (opt_log4j) {
domain.type = LTTNG_DOMAIN_LOG4J;
+ } else if (opt_log4j2) {
+ domain.type = LTTNG_DOMAIN_LOG4J2;
} else if (opt_python) {
domain.type = LTTNG_DOMAIN_PYTHON;
}
goto end;
}
- if (opt_kernel || opt_userspace || opt_jul || opt_log4j || opt_python) {
+ if (opt_kernel || opt_userspace || opt_jul || opt_log4j || opt_log4j2 || opt_python) {
the_handle = lttng_create_handle(arg_session_name, &domain);
if (the_handle == nullptr) {
ret = CMD_FATAL;
}
if (arg_session_name == nullptr) {
- if (!opt_kernel && !opt_userspace && !opt_jul && !opt_log4j && !opt_python) {
+ if (!opt_kernel && !opt_userspace && !opt_jul && !opt_log4j && !opt_log4j2 &&
+ !opt_python) {
ret = list_sessions(nullptr);
if (ret) {
goto end;
goto end;
}
}
- if (opt_jul || opt_log4j || opt_python) {
+ if (opt_jul || opt_log4j || opt_log4j2 || opt_python) {
ret = list_agent_events();
if (ret) {
goto end;
"per-user");
break;
case LTTNG_DOMAIN_JUL:
- MSG("=== Domain: java.util.logging (JUL) ===\n");
+ MSG("=== Domain: JUL (java.util.logging) ===\n");
break;
case LTTNG_DOMAIN_LOG4J:
- MSG("=== Domain: log4j ===\n");
+ MSG("=== Domain: Log4j ===\n");
+ break;
+ case LTTNG_DOMAIN_LOG4J2:
+ MSG("=== Domain: Log4j2 ===\n");
break;
case LTTNG_DOMAIN_PYTHON:
MSG("=== Domain: Python logging ===\n");
if (domains[i].type == LTTNG_DOMAIN_JUL ||
domains[i].type == LTTNG_DOMAIN_LOG4J ||
+ domains[i].type == LTTNG_DOMAIN_LOG4J2 ||
domains[i].type == LTTNG_DOMAIN_PYTHON) {
ret = list_session_agent_events();
if (ret) {
case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
name = loglevel_log4j_value_to_name(loglevel);
break;
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
+ name = loglevel_log4j2_value_to_name(loglevel);
+ break;
case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
name = loglevel_jul_value_to_name(loglevel);
break;
logging_get_log_level_rule = lttng_event_rule_log4j_logging_get_log_level_rule;
type_str = "log4j";
break;
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
+ logging_get_name_pattern = lttng_event_rule_log4j2_logging_get_name_pattern;
+ logging_get_filter = lttng_event_rule_log4j2_logging_get_filter;
+ logging_get_log_level_rule = lttng_event_rule_log4j2_logging_get_log_level_rule;
+ type_str = "log4j2";
+ break;
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
logging_get_name_pattern = lttng_event_rule_python_logging_get_name_pattern;
logging_get_filter = lttng_event_rule_python_logging_get_filter;
break;
case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
print_event_rule_logging(event_rule);
break;
{ .name = "LOG4J_ALL", .value = LTTNG_LOGLEVEL_LOG4J_ALL },
};
+static const struct loglevel_name_value loglevel_log4j2_values[] = {
+ { .name = "OFF", .value = LTTNG_LOGLEVEL_LOG4J2_OFF },
+ { .name = "LOG4J2_OFF", .value = LTTNG_LOGLEVEL_LOG4J2_OFF },
+ { .name = "FATAL", .value = LTTNG_LOGLEVEL_LOG4J2_FATAL },
+ { .name = "LOG4J2_FATAL", .value = LTTNG_LOGLEVEL_LOG4J2_FATAL },
+ { .name = "ERROR", .value = LTTNG_LOGLEVEL_LOG4J2_ERROR },
+ { .name = "LOG4J2_ERROR", .value = LTTNG_LOGLEVEL_LOG4J2_ERROR },
+ { .name = "WARN", .value = LTTNG_LOGLEVEL_LOG4J2_WARN },
+ { .name = "LOG4J2_WARN", .value = LTTNG_LOGLEVEL_LOG4J2_WARN },
+ { .name = "INFO", .value = LTTNG_LOGLEVEL_LOG4J2_INFO },
+ { .name = "LOG4J2_INFO", .value = LTTNG_LOGLEVEL_LOG4J2_INFO },
+ { .name = "DEBUG", .value = LTTNG_LOGLEVEL_LOG4J2_DEBUG },
+ { .name = "LOG4J2_DEBUG", .value = LTTNG_LOGLEVEL_LOG4J2_DEBUG },
+ { .name = "TRACE", .value = LTTNG_LOGLEVEL_LOG4J2_TRACE },
+ { .name = "LOG4J2_TRACE", .value = LTTNG_LOGLEVEL_LOG4J2_TRACE },
+ { .name = "ALL", .value = LTTNG_LOGLEVEL_LOG4J2_ALL },
+ { .name = "LOG4J2_ALL", .value = LTTNG_LOGLEVEL_LOG4J2_ALL },
+};
+
static const struct loglevel_name_value loglevel_jul_values[] = {
{ .name = "OFF", .value = LTTNG_LOGLEVEL_JUL_OFF },
{ .name = "JUL_OFF", .value = LTTNG_LOGLEVEL_JUL_OFF },
return ret;
}
+int loglevel_log4j2_name_to_value(const char *name, enum lttng_loglevel_log4j2 *loglevel)
+{
+ int ret = lookup_value_from_name(
+ loglevel_log4j2_values, ARRAY_SIZE(loglevel_log4j2_values), name);
+
+ if (ret >= 0) {
+ *loglevel = (typeof(*loglevel)) ret;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+bool loglevel_log4j2_parse_range_string(const char *str,
+ enum lttng_loglevel_log4j2 *min,
+ enum lttng_loglevel_log4j2 *max)
+{
+ int min_int, max_int;
+ bool ret = loglevel_parse_range_string_common(str,
+ loglevel_log4j2_values,
+ ARRAY_SIZE(loglevel_log4j2_values),
+ &min_int,
+ &max_int);
+
+ *min = (lttng_loglevel_log4j2) min_int;
+ *max = (lttng_loglevel_log4j2) max_int;
+
+ return ret;
+}
+
int loglevel_jul_name_to_value(const char *name, enum lttng_loglevel_jul *loglevel)
{
int ret =
loglevel_log4j_values, ARRAY_SIZE(loglevel_log4j_values), loglevel);
}
+const char *loglevel_log4j2_value_to_name(int loglevel)
+{
+ return lookup_name_from_value(
+ loglevel_log4j2_values, ARRAY_SIZE(loglevel_log4j2_values), loglevel);
+}
+
const char *loglevel_jul_value_to_name(int loglevel)
{
return lookup_name_from_value(
enum lttng_loglevel_log4j *min,
enum lttng_loglevel_log4j *max);
+int loglevel_log4j2_name_to_value(const char *name, enum lttng_loglevel_log4j2 *loglevel);
+
+bool loglevel_log4j2_parse_range_string(const char *str,
+ enum lttng_loglevel_log4j2 *min,
+ enum lttng_loglevel_log4j2 *max);
+
int loglevel_jul_name_to_value(const char *name, enum lttng_loglevel_jul *loglevel);
bool loglevel_jul_parse_range_string(const char *str,
const char *loglevel_log4j_value_to_name(int loglevel);
+const char *loglevel_log4j2_value_to_name(int loglevel);
+
const char *loglevel_jul_value_to_name(int loglevel);
const char *loglevel_python_value_to_name(int loglevel);
if (domain_count == 0) {
ERR("Please specify a domain (--kernel/--userspace%s).",
- include_agent_domains ? "/--jul/--log4j/--python" : "");
+ include_agent_domains ? "/--jul/--log4j/--log4j2/--python" : "");
ret = -1;
} else if (domain_count > 1) {
ERR("Only one domain must be specified.");
event-rule/kernel-tracepoint.cpp \
event-rule/user-tracepoint.cpp \
event-rule/log4j-logging.cpp \
+ event-rule/log4j2-logging.cpp \
event-rule/jul-logging.cpp \
event-rule/python-logging.cpp \
exception.cpp exception.hpp \
case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
/* Supported. */
LTTNG_EXPORT extern const char *const config_domain_type_ust;
LTTNG_EXPORT extern const char *const config_domain_type_jul;
LTTNG_EXPORT extern const char *const config_domain_type_log4j;
+LTTNG_EXPORT extern const char *const config_domain_type_log4j2;
LTTNG_EXPORT extern const char *const config_domain_type_python;
LTTNG_EXPORT extern const char *const config_buffer_type_per_pid;
const char *const config_domain_type_ust = "UST";
const char *const config_domain_type_jul = "JUL";
const char *const config_domain_type_log4j = "LOG4J";
+const char *const config_domain_type_log4j2 = "LOG4J2";
const char *const config_domain_type_python = "PYTHON";
const char *const config_buffer_type_per_pid = "PER_PID";
ret = LTTNG_DOMAIN_JUL;
} else if (!strcmp((char *) domain, config_domain_type_log4j)) {
ret = LTTNG_DOMAIN_LOG4J;
+ } else if (!strcmp((char *) domain, config_domain_type_log4j2)) {
+ ret = LTTNG_DOMAIN_LOG4J2;
} else if (!strcmp((char *) domain, config_domain_type_python)) {
ret = LTTNG_DOMAIN_PYTHON;
} else {
case LTTNG_DOMAIN_LOG4J:
event->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL;
break;
+ case LTTNG_DOMAIN_LOG4J2:
+ event->loglevel = LTTNG_LOGLEVEL_LOG4J2_ALL;
+ break;
case LTTNG_DOMAIN_PYTHON:
event->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG;
break;
switch (domain.type) {
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
domain.type = LTTNG_DOMAIN_UST;
default:
struct lttng_domain *ust_domain = nullptr;
struct lttng_domain *jul_domain = nullptr;
struct lttng_domain *log4j_domain = nullptr;
+ struct lttng_domain *log4j2_domain = nullptr;
struct lttng_domain *python_domain = nullptr;
for (node = xmlFirstElementChild(session_node); node; node = xmlNextElementSibling(node)) {
}
log4j_domain = domain;
break;
+ case LTTNG_DOMAIN_LOG4J2:
+ if (log4j2_domain) {
+ /* Same domain seen twice, invalid! */
+ goto domain_init_error;
+ }
+ log4j2_domain = domain;
+ break;
case LTTNG_DOMAIN_PYTHON:
if (python_domain) {
/* Same domain seen twice, invalid! */
free(ust_domain);
free(jul_domain);
free(log4j_domain);
+ free(log4j2_domain);
free(python_domain);
xmlFree(name);
xmlFree(shm_path);
#define DEFAULT_LOG4J_EVENT_COMPONENT "lttng_log4j"
#define DEFAULT_LOG4J_EVENT_NAME DEFAULT_LOG4J_EVENT_COMPONENT ":*"
+/* Default log4j2 domain channel name. */
+#define DEFAULT_LOG4J2_CHANNEL_NAME "lttng_log4j2_channel"
+/* Default log4j tracepoint name. This is a wildcard for the log4j2 domain. */
+#define DEFAULT_LOG4J2_EVENT_COMPONENT "lttng_log4j2"
+#define DEFAULT_LOG4J2_EVENT_NAME DEFAULT_LOG4J2_EVENT_COMPONENT ":*"
+
/* Default Python domain channel name. */
#define DEFAULT_PYTHON_CHANNEL_NAME "lttng_python_channel"
/* Default Python tracepoint name. This is a wildcard for the python domain. */
return "java.util.logging (JUL)";
case LTTNG_DOMAIN_LOG4J:
return "log4j";
+ case LTTNG_DOMAIN_LOG4J2:
+ return "log4j2";
case LTTNG_DOMAIN_PYTHON:
return "Python logging";
default:
#include <lttng/event-rule/kernel-tracepoint-internal.hpp>
#include <lttng/event-rule/kernel-uprobe-internal.hpp>
#include <lttng/event-rule/log4j-logging-internal.hpp>
+#include <lttng/event-rule/log4j2-logging-internal.hpp>
#include <lttng/event-rule/python-logging-internal.hpp>
#include <lttng/event-rule/user-tracepoint-internal.hpp>
case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
domain_type = LTTNG_DOMAIN_LOG4J;
break;
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
+ domain_type = LTTNG_DOMAIN_LOG4J2;
+ break;
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
domain_type = LTTNG_DOMAIN_PYTHON;
break;
case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
create_from_payload = lttng_event_rule_log4j_logging_create_from_payload;
break;
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
+ create_from_payload = lttng_event_rule_log4j2_logging_create_from_payload;
+ break;
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
create_from_payload = lttng_event_rule_python_logging_create_from_payload;
break;
switch (type) {
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
targets_agent_domain = true;
break;
return "jul logging";
case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
return "log4j logging";
+ case LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING:
+ return "log4j2 logging";
case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
return "python logging";
case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
log_level_rule, &level);
- op = ">=";
+ op = LTTNG_JUL_EVENT_RULE_AT_LEAST_AS_SEVERE_AS_OP;
break;
default:
abort();
static bool log_level_rule_valid(const struct lttng_log_level_rule *rule __attribute__((unused)))
{
/*
- * For both JUL and LOG4J custom log level are possible and can
- * span the entire int32 range.
+ * JUL custom log levels are possible and can span the entire int32
+ * range.
*/
return true;
}
case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
log_level_rule, &level);
- op = ">=";
+ op = LTTNG_LOG4J_EVENT_RULE_AT_LEAST_AS_SEVERE_AS_OP;
break;
default:
abort();
static bool log_level_rule_valid(const struct lttng_log_level_rule *rule __attribute__((unused)))
{
/*
- * For both LOG4J custom log level are possible and can
- * span the entire int32 range.
+ * LOG4J custom log levels are possible and can span the entire int32
+ * range.
*/
return true;
}
--- /dev/null
+/*
+ * Copyright (C) 2024 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#include <common/credentials.hpp>
+#include <common/error.hpp>
+#include <common/hashtable/hashtable.hpp>
+#include <common/hashtable/utils.hpp>
+#include <common/macros.hpp>
+#include <common/mi-lttng.hpp>
+#include <common/optional.hpp>
+#include <common/payload-view.hpp>
+#include <common/payload.hpp>
+#include <common/runas.hpp>
+#include <common/string-utils/string-utils.hpp>
+
+#include <lttng/event-rule/event-rule-internal.hpp>
+#include <lttng/event-rule/log4j2-logging-internal.hpp>
+#include <lttng/event.h>
+#include <lttng/log-level-rule.h>
+
+#define IS_LOG4J2_LOGGING_EVENT_RULE(rule) \
+ (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING)
+
+static void lttng_event_rule_log4j2_logging_destroy(struct lttng_event_rule *rule)
+{
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+
+ if (rule == nullptr) {
+ return;
+ }
+
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+
+ lttng_log_level_rule_destroy(log4j2_logging->log_level_rule);
+ free(log4j2_logging->pattern);
+ free(log4j2_logging->filter_expression);
+ free(log4j2_logging->internal_filter.filter);
+ free(log4j2_logging->internal_filter.bytecode);
+ free(log4j2_logging);
+}
+
+static bool lttng_event_rule_log4j2_logging_validate(const struct lttng_event_rule *rule)
+{
+ bool valid = false;
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+
+ if (!rule) {
+ goto end;
+ }
+
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+
+ /* Required field. */
+ if (!log4j2_logging->pattern) {
+ ERR("Invalid log4j2_logging event rule: a pattern must be set.");
+ goto end;
+ }
+
+ valid = true;
+end:
+ return valid;
+}
+
+static int lttng_event_rule_log4j2_logging_serialize(const struct lttng_event_rule *rule,
+ struct lttng_payload *payload)
+{
+ int ret;
+ size_t pattern_len, filter_expression_len, header_offset;
+ size_t size_before_log_level_rule;
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+ struct lttng_event_rule_log4j2_logging_comm log4j2_logging_comm;
+ struct lttng_event_rule_log4j2_logging_comm *header;
+
+ if (!rule || !IS_LOG4J2_LOGGING_EVENT_RULE(rule)) {
+ ret = -1;
+ goto end;
+ }
+
+ header_offset = payload->buffer.size;
+
+ DBG("Serializing log4j2_logging event rule.");
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+
+ pattern_len = strlen(log4j2_logging->pattern) + 1;
+
+ if (log4j2_logging->filter_expression != nullptr) {
+ filter_expression_len = strlen(log4j2_logging->filter_expression) + 1;
+ } else {
+ filter_expression_len = 0;
+ }
+
+ log4j2_logging_comm.pattern_len = pattern_len;
+ log4j2_logging_comm.filter_expression_len = filter_expression_len;
+
+ ret = lttng_dynamic_buffer_append(
+ &payload->buffer, &log4j2_logging_comm, sizeof(log4j2_logging_comm));
+ if (ret) {
+ goto end;
+ }
+
+ ret = lttng_dynamic_buffer_append(&payload->buffer, log4j2_logging->pattern, pattern_len);
+ if (ret) {
+ goto end;
+ }
+
+ ret = lttng_dynamic_buffer_append(
+ &payload->buffer, log4j2_logging->filter_expression, filter_expression_len);
+ if (ret) {
+ goto end;
+ }
+
+ size_before_log_level_rule = payload->buffer.size;
+
+ ret = lttng_log_level_rule_serialize(log4j2_logging->log_level_rule, payload);
+ if (ret < 0) {
+ goto end;
+ }
+
+ header = (typeof(header)) ((char *) payload->buffer.data + header_offset);
+ header->log_level_rule_len = payload->buffer.size - size_before_log_level_rule;
+
+end:
+ return ret;
+}
+
+static bool lttng_event_rule_log4j2_logging_is_equal(const struct lttng_event_rule *_a,
+ const struct lttng_event_rule *_b)
+{
+ bool is_equal = false;
+ struct lttng_event_rule_log4j2_logging *a, *b;
+
+ a = lttng::utils::container_of(_a, <tng_event_rule_log4j2_logging::parent);
+ b = lttng::utils::container_of(_b, <tng_event_rule_log4j2_logging::parent);
+
+ /* Quick checks. */
+
+ if (!!a->filter_expression != !!b->filter_expression) {
+ goto end;
+ }
+
+ /* Long check. */
+ LTTNG_ASSERT(a->pattern);
+ LTTNG_ASSERT(b->pattern);
+ if (strcmp(a->pattern, b->pattern) != 0) {
+ goto end;
+ }
+
+ if (a->filter_expression && b->filter_expression) {
+ if (strcmp(a->filter_expression, b->filter_expression) != 0) {
+ goto end;
+ }
+ } else if (!!a->filter_expression != !!b->filter_expression) {
+ /* One is set; not the other. */
+ goto end;
+ }
+
+ if (!lttng_log_level_rule_is_equal(a->log_level_rule, b->log_level_rule)) {
+ goto end;
+ }
+
+ is_equal = true;
+end:
+ return is_equal;
+}
+
+/*
+ * On success ret is 0;
+ *
+ * On error ret is negative.
+ *
+ * An event with NO loglevel and the name is * will return NULL.
+ */
+static int generate_agent_filter(const struct lttng_event_rule *rule, char **_agent_filter)
+{
+ int err;
+ int ret = 0;
+ char *agent_filter = nullptr;
+ const char *pattern;
+ const char *filter;
+ const struct lttng_log_level_rule *log_level_rule = nullptr;
+ enum lttng_event_rule_status status;
+
+ LTTNG_ASSERT(rule);
+ LTTNG_ASSERT(_agent_filter);
+
+ status = lttng_event_rule_log4j2_logging_get_name_pattern(rule, &pattern);
+ if (status != LTTNG_EVENT_RULE_STATUS_OK) {
+ ret = -1;
+ goto end;
+ }
+
+ status = lttng_event_rule_log4j2_logging_get_filter(rule, &filter);
+ if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
+ filter = nullptr;
+ } else if (status != LTTNG_EVENT_RULE_STATUS_OK) {
+ ret = -1;
+ goto end;
+ }
+
+ /* Don't add filter for the '*' event. */
+ if (strcmp(pattern, "*") != 0) {
+ if (filter) {
+ err = asprintf(
+ &agent_filter, "(%s) && (logger_name == \"%s\")", filter, pattern);
+ } else {
+ err = asprintf(&agent_filter, "logger_name == \"%s\"", pattern);
+ }
+
+ if (err < 0) {
+ PERROR("Failed to format agent filter string");
+ ret = -1;
+ goto end;
+ }
+ }
+
+ status = lttng_event_rule_log4j2_logging_get_log_level_rule(rule, &log_level_rule);
+ if (status == LTTNG_EVENT_RULE_STATUS_OK) {
+ enum lttng_log_level_rule_status llr_status;
+ const char *op;
+ int level;
+
+ switch (lttng_log_level_rule_get_type(log_level_rule)) {
+ case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
+ llr_status = lttng_log_level_rule_exactly_get_level(log_level_rule, &level);
+ op = "==";
+ break;
+ case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
+ llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
+ log_level_rule, &level);
+ op = LTTNG_LOG4J2_EVENT_RULE_AT_LEAST_AS_SEVERE_AS_OP;
+ break;
+ default:
+ abort();
+ }
+
+ if (llr_status != LTTNG_LOG_LEVEL_RULE_STATUS_OK) {
+ ret = -1;
+ goto end;
+ }
+
+ if (filter || agent_filter) {
+ char *new_filter;
+
+ err = asprintf(&new_filter,
+ "(%s) && (int_loglevel %s %d)",
+ agent_filter ? agent_filter : filter,
+ op,
+ level);
+ if (agent_filter) {
+ free(agent_filter);
+ }
+ agent_filter = new_filter;
+ } else {
+ err = asprintf(&agent_filter, "int_loglevel %s %d", op, level);
+ }
+
+ if (err < 0) {
+ PERROR("Failed to format agent filter string");
+ ret = -1;
+ goto end;
+ }
+ }
+
+ *_agent_filter = agent_filter;
+ agent_filter = nullptr;
+
+end:
+ free(agent_filter);
+ return ret;
+}
+
+static enum lttng_error_code
+lttng_event_rule_log4j2_logging_generate_filter_bytecode(struct lttng_event_rule *rule,
+ const struct lttng_credentials *creds)
+{
+ int ret;
+ enum lttng_error_code ret_code;
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+ enum lttng_event_rule_status status;
+ const char *filter;
+ struct lttng_bytecode *bytecode = nullptr;
+ char *agent_filter;
+
+ LTTNG_ASSERT(rule);
+
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+
+ status = lttng_event_rule_log4j2_logging_get_filter(rule, &filter);
+ if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
+ filter = nullptr;
+ } else if (status != LTTNG_EVENT_RULE_STATUS_OK) {
+ ret_code = LTTNG_ERR_FILTER_INVAL;
+ goto end;
+ }
+
+ if (filter && filter[0] == '\0') {
+ ret_code = LTTNG_ERR_FILTER_INVAL;
+ goto error;
+ }
+
+ ret = generate_agent_filter(rule, &agent_filter);
+ if (ret) {
+ ret_code = LTTNG_ERR_FILTER_INVAL;
+ goto error;
+ }
+
+ log4j2_logging->internal_filter.filter = agent_filter;
+
+ if (log4j2_logging->internal_filter.filter == nullptr) {
+ ret_code = LTTNG_OK;
+ goto end;
+ }
+
+ ret = run_as_generate_filter_bytecode(
+ log4j2_logging->internal_filter.filter, creds, &bytecode);
+ if (ret) {
+ ret_code = LTTNG_ERR_FILTER_INVAL;
+ goto end;
+ }
+
+ log4j2_logging->internal_filter.bytecode = bytecode;
+ bytecode = nullptr;
+ ret_code = LTTNG_OK;
+
+error:
+end:
+ free(bytecode);
+ return ret_code;
+}
+
+static const char *
+lttng_event_rule_log4j2_logging_get_internal_filter(const struct lttng_event_rule *rule)
+{
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+
+ LTTNG_ASSERT(rule);
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+ return log4j2_logging->internal_filter.filter;
+}
+
+static const struct lttng_bytecode *
+lttng_event_rule_log4j2_logging_get_internal_filter_bytecode(const struct lttng_event_rule *rule)
+{
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+
+ LTTNG_ASSERT(rule);
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+ return log4j2_logging->internal_filter.bytecode;
+}
+
+static enum lttng_event_rule_generate_exclusions_status
+lttng_event_rule_log4j2_logging_generate_exclusions(const struct lttng_event_rule *rule
+ __attribute__((unused)),
+ struct lttng_event_exclusion **_exclusions)
+{
+ /* Unsupported. */
+ *_exclusions = nullptr;
+ return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE;
+}
+
+static unsigned long lttng_event_rule_log4j2_logging_hash(const struct lttng_event_rule *rule)
+{
+ unsigned long hash;
+ struct lttng_event_rule_log4j2_logging *tp_rule =
+ lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+
+ hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING, lttng_ht_seed);
+ hash ^= hash_key_str(tp_rule->pattern, lttng_ht_seed);
+
+ if (tp_rule->filter_expression) {
+ hash ^= hash_key_str(tp_rule->filter_expression, lttng_ht_seed);
+ }
+
+ if (tp_rule->log_level_rule) {
+ hash ^= lttng_log_level_rule_hash(tp_rule->log_level_rule);
+ }
+
+ return hash;
+}
+
+static struct lttng_event *
+lttng_event_rule_log4j2_logging_generate_lttng_event(const struct lttng_event_rule *rule)
+{
+ int ret;
+ const struct lttng_event_rule_log4j2_logging *log4j2_logging;
+ struct lttng_event *local_event = nullptr;
+ struct lttng_event *event = nullptr;
+ enum lttng_loglevel_type loglevel_type;
+ int loglevel_value = 0;
+ enum lttng_event_rule_status status;
+ const struct lttng_log_level_rule *log_level_rule;
+
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+
+ local_event = zmalloc<lttng_event>();
+ if (!local_event) {
+ goto error;
+ }
+
+ local_event->type = LTTNG_EVENT_TRACEPOINT;
+ ret = lttng_strncpy(local_event->name, log4j2_logging->pattern, sizeof(local_event->name));
+ if (ret) {
+ ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'",
+ log4j2_logging->pattern);
+ goto error;
+ }
+
+ /* Map the log level rule to an equivalent lttng_loglevel. */
+ status = lttng_event_rule_log4j2_logging_get_log_level_rule(rule, &log_level_rule);
+ if (status == LTTNG_EVENT_RULE_STATUS_UNSET) {
+ loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
+ loglevel_value = LTTNG_LOGLEVEL_LOG4J2_ALL;
+ } else if (status == LTTNG_EVENT_RULE_STATUS_OK) {
+ enum lttng_log_level_rule_status llr_status;
+
+ switch (lttng_log_level_rule_get_type(log_level_rule)) {
+ case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
+ llr_status = lttng_log_level_rule_exactly_get_level(log_level_rule,
+ &loglevel_value);
+ loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
+ break;
+ case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
+ llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
+ log_level_rule, &loglevel_value);
+ loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
+ break;
+ default:
+ abort();
+ break;
+ }
+
+ if (llr_status != LTTNG_LOG_LEVEL_RULE_STATUS_OK) {
+ goto error;
+ }
+ } else {
+ goto error;
+ }
+
+ local_event->loglevel_type = loglevel_type;
+ local_event->loglevel = loglevel_value;
+
+ event = local_event;
+ local_event = nullptr;
+error:
+ free(local_event);
+ return event;
+}
+
+static enum lttng_error_code
+lttng_event_rule_log4j2_logging_mi_serialize(const struct lttng_event_rule *rule,
+ struct mi_writer *writer)
+{
+ int ret;
+ enum lttng_error_code ret_code;
+ enum lttng_event_rule_status status;
+ const char *filter = nullptr;
+ const char *name_pattern = nullptr;
+ const struct lttng_log_level_rule *log_level_rule = nullptr;
+
+ LTTNG_ASSERT(rule);
+ LTTNG_ASSERT(writer);
+ LTTNG_ASSERT(IS_LOG4J2_LOGGING_EVENT_RULE(rule));
+
+ status = lttng_event_rule_log4j2_logging_get_name_pattern(rule, &name_pattern);
+ LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK);
+ LTTNG_ASSERT(name_pattern);
+
+ status = lttng_event_rule_log4j2_logging_get_filter(rule, &filter);
+ LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK ||
+ status == LTTNG_EVENT_RULE_STATUS_UNSET);
+
+ status = lttng_event_rule_log4j2_logging_get_log_level_rule(rule, &log_level_rule);
+ LTTNG_ASSERT(status == LTTNG_EVENT_RULE_STATUS_OK ||
+ status == LTTNG_EVENT_RULE_STATUS_UNSET);
+
+ /* Open event rule log4j2 logging element. */
+ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_rule_log4j2_logging);
+ if (ret) {
+ goto mi_error;
+ }
+
+ /* Name pattern. */
+ ret = mi_lttng_writer_write_element_string(
+ writer, mi_lttng_element_event_rule_name_pattern, name_pattern);
+ if (ret) {
+ goto mi_error;
+ }
+
+ /* Filter expression. */
+ if (filter != nullptr) {
+ ret = mi_lttng_writer_write_element_string(
+ writer, mi_lttng_element_event_rule_filter_expression, filter);
+ if (ret) {
+ goto mi_error;
+ }
+ }
+
+ /* Log level rule. */
+ if (log_level_rule) {
+ ret_code = lttng_log_level_rule_mi_serialize(log_level_rule, writer);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+ }
+
+ /* Close event rule log4j2 logging element. */
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ goto mi_error;
+ }
+
+ ret_code = LTTNG_OK;
+ goto end;
+
+mi_error:
+ ret_code = LTTNG_ERR_MI_IO_FAIL;
+end:
+ return ret_code;
+}
+
+struct lttng_event_rule *lttng_event_rule_log4j2_logging_create(void)
+{
+ struct lttng_event_rule *rule = nullptr;
+ struct lttng_event_rule_log4j2_logging *tp_rule;
+ enum lttng_event_rule_status status;
+
+ tp_rule = zmalloc<lttng_event_rule_log4j2_logging>();
+ if (!tp_rule) {
+ goto end;
+ }
+
+ rule = &tp_rule->parent;
+ lttng_event_rule_init(&tp_rule->parent, LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING);
+ tp_rule->parent.validate = lttng_event_rule_log4j2_logging_validate;
+ tp_rule->parent.serialize = lttng_event_rule_log4j2_logging_serialize;
+ tp_rule->parent.equal = lttng_event_rule_log4j2_logging_is_equal;
+ tp_rule->parent.destroy = lttng_event_rule_log4j2_logging_destroy;
+ tp_rule->parent.generate_filter_bytecode =
+ lttng_event_rule_log4j2_logging_generate_filter_bytecode;
+ tp_rule->parent.get_filter = lttng_event_rule_log4j2_logging_get_internal_filter;
+ tp_rule->parent.get_filter_bytecode =
+ lttng_event_rule_log4j2_logging_get_internal_filter_bytecode;
+ tp_rule->parent.generate_exclusions = lttng_event_rule_log4j2_logging_generate_exclusions;
+ tp_rule->parent.hash = lttng_event_rule_log4j2_logging_hash;
+ tp_rule->parent.generate_lttng_event = lttng_event_rule_log4j2_logging_generate_lttng_event;
+ tp_rule->parent.mi_serialize = lttng_event_rule_log4j2_logging_mi_serialize;
+
+ tp_rule->log_level_rule = nullptr;
+
+ /* Default pattern is '*'. */
+ status = lttng_event_rule_log4j2_logging_set_name_pattern(rule, "*");
+ if (status != LTTNG_EVENT_RULE_STATUS_OK) {
+ lttng_event_rule_destroy(rule);
+ rule = nullptr;
+ }
+
+end:
+ return rule;
+}
+
+ssize_t lttng_event_rule_log4j2_logging_create_from_payload(struct lttng_payload_view *view,
+ struct lttng_event_rule **_event_rule)
+{
+ ssize_t ret, offset = 0;
+ enum lttng_event_rule_status status;
+ const struct lttng_event_rule_log4j2_logging_comm *log4j2_logging_comm;
+ const char *pattern;
+ const char *filter_expression = nullptr;
+ struct lttng_buffer_view current_buffer_view;
+ struct lttng_event_rule *rule = nullptr;
+ struct lttng_log_level_rule *log_level_rule = nullptr;
+
+ if (!_event_rule) {
+ ret = -1;
+ goto end;
+ }
+
+ current_buffer_view =
+ lttng_buffer_view_from_view(&view->buffer, offset, sizeof(*log4j2_logging_comm));
+ if (!lttng_buffer_view_is_valid(¤t_buffer_view)) {
+ ERR("Failed to initialize from malformed event rule log4j2_logging: buffer too short to contain header.");
+ ret = -1;
+ goto end;
+ }
+
+ log4j2_logging_comm = (typeof(log4j2_logging_comm)) current_buffer_view.data;
+
+ rule = lttng_event_rule_log4j2_logging_create();
+ if (!rule) {
+ ERR("Failed to create event rule log4j2_logging.");
+ ret = -1;
+ goto end;
+ }
+
+ /* Skip to payload. */
+ offset += current_buffer_view.size;
+
+ /* Map the pattern. */
+ current_buffer_view = lttng_buffer_view_from_view(
+ &view->buffer, offset, log4j2_logging_comm->pattern_len);
+
+ if (!lttng_buffer_view_is_valid(¤t_buffer_view)) {
+ ret = -1;
+ goto end;
+ }
+
+ pattern = current_buffer_view.data;
+ if (!lttng_buffer_view_contains_string(
+ ¤t_buffer_view, pattern, log4j2_logging_comm->pattern_len)) {
+ ret = -1;
+ goto end;
+ }
+
+ /* Skip after the pattern. */
+ offset += log4j2_logging_comm->pattern_len;
+
+ if (!log4j2_logging_comm->filter_expression_len) {
+ goto skip_filter_expression;
+ }
+
+ /* Map the filter_expression. */
+ current_buffer_view = lttng_buffer_view_from_view(
+ &view->buffer, offset, log4j2_logging_comm->filter_expression_len);
+ if (!lttng_buffer_view_is_valid(¤t_buffer_view)) {
+ ret = -1;
+ goto end;
+ }
+
+ filter_expression = current_buffer_view.data;
+ if (!lttng_buffer_view_contains_string(¤t_buffer_view,
+ filter_expression,
+ log4j2_logging_comm->filter_expression_len)) {
+ ret = -1;
+ goto end;
+ }
+
+ /* Skip after the pattern. */
+ offset += log4j2_logging_comm->filter_expression_len;
+
+skip_filter_expression:
+ if (!log4j2_logging_comm->log_level_rule_len) {
+ goto skip_log_level_rule;
+ }
+
+ {
+ /* Map the log level rule. */
+ struct lttng_payload_view current_payload_view = lttng_payload_view_from_view(
+ view, offset, log4j2_logging_comm->log_level_rule_len);
+
+ ret = lttng_log_level_rule_create_from_payload(¤t_payload_view,
+ &log_level_rule);
+ if (ret < 0) {
+ ret = -1;
+ goto end;
+ }
+
+ LTTNG_ASSERT(ret == log4j2_logging_comm->log_level_rule_len);
+ }
+
+ /* Skip after the log level rule. */
+ offset += log4j2_logging_comm->log_level_rule_len;
+
+skip_log_level_rule:
+
+ status = lttng_event_rule_log4j2_logging_set_name_pattern(rule, pattern);
+ if (status != LTTNG_EVENT_RULE_STATUS_OK) {
+ ERR("Failed to set event rule log4j2_logging pattern.");
+ ret = -1;
+ goto end;
+ }
+
+ if (filter_expression) {
+ status = lttng_event_rule_log4j2_logging_set_filter(rule, filter_expression);
+ if (status != LTTNG_EVENT_RULE_STATUS_OK) {
+ ERR("Failed to set event rule log4j2_logging pattern.");
+ ret = -1;
+ goto end;
+ }
+ }
+
+ if (log_level_rule) {
+ status = lttng_event_rule_log4j2_logging_set_log_level_rule(rule, log_level_rule);
+ if (status != LTTNG_EVENT_RULE_STATUS_OK) {
+ ERR("Failed to set event rule log4j2_logging log level rule.");
+ ret = -1;
+ goto end;
+ }
+ }
+
+ *_event_rule = rule;
+ rule = nullptr;
+ ret = offset;
+end:
+ lttng_log_level_rule_destroy(log_level_rule);
+ lttng_event_rule_destroy(rule);
+ return ret;
+}
+
+enum lttng_event_rule_status
+lttng_event_rule_log4j2_logging_set_name_pattern(struct lttng_event_rule *rule, const char *pattern)
+{
+ char *pattern_copy = nullptr;
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+ enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
+
+ if (!rule || !IS_LOG4J2_LOGGING_EVENT_RULE(rule) || !pattern || strlen(pattern) == 0) {
+ status = LTTNG_EVENT_RULE_STATUS_INVALID;
+ goto end;
+ }
+
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+ pattern_copy = strdup(pattern);
+ if (!pattern_copy) {
+ status = LTTNG_EVENT_RULE_STATUS_ERROR;
+ goto end;
+ }
+
+ /* Normalize the pattern. */
+ strutils_normalize_star_glob_pattern(pattern_copy);
+
+ free(log4j2_logging->pattern);
+
+ log4j2_logging->pattern = pattern_copy;
+ pattern_copy = nullptr;
+end:
+ return status;
+}
+
+enum lttng_event_rule_status
+lttng_event_rule_log4j2_logging_get_name_pattern(const struct lttng_event_rule *rule,
+ const char **pattern)
+{
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+ enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
+
+ if (!rule || !IS_LOG4J2_LOGGING_EVENT_RULE(rule) || !pattern) {
+ status = LTTNG_EVENT_RULE_STATUS_INVALID;
+ goto end;
+ }
+
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+ if (!log4j2_logging->pattern) {
+ status = LTTNG_EVENT_RULE_STATUS_UNSET;
+ goto end;
+ }
+
+ *pattern = log4j2_logging->pattern;
+end:
+ return status;
+}
+
+enum lttng_event_rule_status
+lttng_event_rule_log4j2_logging_set_filter(struct lttng_event_rule *rule, const char *expression)
+{
+ char *expression_copy = nullptr;
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+ enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
+
+ if (!rule || !IS_LOG4J2_LOGGING_EVENT_RULE(rule) || !expression ||
+ strlen(expression) == 0) {
+ status = LTTNG_EVENT_RULE_STATUS_INVALID;
+ goto end;
+ }
+
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+ expression_copy = strdup(expression);
+ if (!expression_copy) {
+ PERROR("Failed to copy filter expression");
+ status = LTTNG_EVENT_RULE_STATUS_ERROR;
+ goto end;
+ }
+
+ if (log4j2_logging->filter_expression) {
+ free(log4j2_logging->filter_expression);
+ }
+
+ log4j2_logging->filter_expression = expression_copy;
+ expression_copy = nullptr;
+end:
+ return status;
+}
+
+enum lttng_event_rule_status
+lttng_event_rule_log4j2_logging_get_filter(const struct lttng_event_rule *rule,
+ const char **expression)
+{
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+ enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
+
+ if (!rule || !IS_LOG4J2_LOGGING_EVENT_RULE(rule) || !expression) {
+ status = LTTNG_EVENT_RULE_STATUS_INVALID;
+ goto end;
+ }
+
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+ if (!log4j2_logging->filter_expression) {
+ status = LTTNG_EVENT_RULE_STATUS_UNSET;
+ goto end;
+ }
+
+ *expression = log4j2_logging->filter_expression;
+end:
+ return status;
+}
+
+static bool log_level_rule_valid(const struct lttng_log_level_rule *rule)
+{
+ /*
+ * LOG4J2 custom log levels are possible and can range from 0 to
+ * int32_max.
+ */
+ return (rule->level >= 0);
+}
+
+enum lttng_event_rule_status lttng_event_rule_log4j2_logging_set_log_level_rule(
+ struct lttng_event_rule *rule, const struct lttng_log_level_rule *log_level_rule)
+{
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+ enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
+ struct lttng_log_level_rule *copy = nullptr;
+
+ if (!rule || !IS_LOG4J2_LOGGING_EVENT_RULE(rule)) {
+ status = LTTNG_EVENT_RULE_STATUS_INVALID;
+ goto end;
+ }
+
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+
+ if (!log_level_rule_valid(log_level_rule)) {
+ status = LTTNG_EVENT_RULE_STATUS_INVALID;
+ goto end;
+ }
+
+ copy = lttng_log_level_rule_copy(log_level_rule);
+ if (copy == nullptr) {
+ status = LTTNG_EVENT_RULE_STATUS_ERROR;
+ goto end;
+ }
+
+ if (log4j2_logging->log_level_rule) {
+ lttng_log_level_rule_destroy(log4j2_logging->log_level_rule);
+ }
+
+ log4j2_logging->log_level_rule = copy;
+
+end:
+ return status;
+}
+
+enum lttng_event_rule_status lttng_event_rule_log4j2_logging_get_log_level_rule(
+ const struct lttng_event_rule *rule, const struct lttng_log_level_rule **log_level_rule)
+{
+ struct lttng_event_rule_log4j2_logging *log4j2_logging;
+ enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK;
+
+ if (!rule || !IS_LOG4J2_LOGGING_EVENT_RULE(rule) || !log_level_rule) {
+ status = LTTNG_EVENT_RULE_STATUS_INVALID;
+ goto end;
+ }
+
+ log4j2_logging = lttng::utils::container_of(rule, <tng_event_rule_log4j2_logging::parent);
+ if (log4j2_logging->log_level_rule == nullptr) {
+ status = LTTNG_EVENT_RULE_STATUS_UNSET;
+ goto end;
+ }
+
+ *log_level_rule = log4j2_logging->log_level_rule;
+end:
+ return status;
+}
<xs:enumeration value="LOG4J_DEBUG" />
<xs:enumeration value="LOG4J_TRACE" />
<xs:enumeration value="LOG4J_ALL" />
+ <xs:enumeration value="LOG4J2_OFF" />
+ <xs:enumeration value="LOG4J2_FATAL" />
+ <xs:enumeration value="LOG4J2_ERROR" />
+ <xs:enumeration value="LOG4J2_WARN" />
+ <xs:enumeration value="LOG4J2_INFO" />
+ <xs:enumeration value="LOG4J2_DEBUG" />
+ <xs:enumeration value="LOG4J2_TRACE" />
+ <xs:enumeration value="LOG4J2_ALL" />
<xs:enumeration value="PYTHON_CRITICAL" />
<xs:enumeration value="PYTHON_ERROR" />
<xs:enumeration value="PYTHON_WARNING" />
<xs:enumeration value="UST"/>
<xs:enumeration value="JUL"/>
<xs:enumeration value="LOG4J"/>
+ <xs:enumeration value="LOG4J2"/>
<xs:enumeration value="PYTHON"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="event_rule_kernel_tracepoint" type="tns:event_rule_kernel_tracepoint_type" substitutionGroup="tns:event_rule_sub_type" />
<xs:element name="event_rule_kernel_uprobe" type="tns:event_rule_kernel_uprobe_type" substitutionGroup="tns:event_rule_sub_type" />
<xs:element name="event_rule_log4j_logging" type="tns:event_rule_logging_type" substitutionGroup="tns:event_rule_sub_type" />
+ <xs:element name="event_rule_log4j2_logging" type="tns:event_rule_logging_type" substitutionGroup="tns:event_rule_sub_type" />
<xs:element name="event_rule_python_logging" type="tns:event_rule_logging_type" substitutionGroup="tns:event_rule_sub_type" />
<xs:element name="event_rule_user_tracepoint" type="tns:event_rule_user_tracepoint_type" substitutionGroup="tns:event_rule_sub_type" />
const char *const mi_lttng_loglevel_str_log4j_trace = "LOG4J_TRACE";
const char *const mi_lttng_loglevel_str_log4j_all = "LOG4J_ALL";
+/* String related to loglevel LOG4J2 */
+const char *const mi_lttng_loglevel_str_log4j2_off = "LOG4J2_OFF";
+const char *const mi_lttng_loglevel_str_log4j2_fatal = "LOG4J2_FATAL";
+const char *const mi_lttng_loglevel_str_log4j2_error = "LOG4J2_ERROR";
+const char *const mi_lttng_loglevel_str_log4j2_warn = "LOG4J2_WARN";
+const char *const mi_lttng_loglevel_str_log4j2_info = "LOG4J2_INFO";
+const char *const mi_lttng_loglevel_str_log4j2_debug = "LOG4J2_DEBUG";
+const char *const mi_lttng_loglevel_str_log4j2_trace = "LOG4J2_TRACE";
+const char *const mi_lttng_loglevel_str_log4j2_all = "LOG4J2_ALL";
+
/* String related to loglevel Python */
const char *const mi_lttng_loglevel_str_python_critical = "PYTHON_CRITICAL";
const char *const mi_lttng_loglevel_str_python_error = "PYTHON_ERROR";
const char *const mi_lttng_element_event_rule_kernel_tracepoint = "event_rule_kernel_tracepoint";
const char *const mi_lttng_element_event_rule_kernel_uprobe = "event_rule_kernel_uprobe";
const char *const mi_lttng_element_event_rule_log4j_logging = "event_rule_log4j_logging";
+const char *const mi_lttng_element_event_rule_log4j2_logging = "event_rule_log4j2_logging";
const char *const mi_lttng_element_event_rule_python_logging = "event_rule_python_logging";
const char *const mi_lttng_element_event_rule_user_tracepoint = "event_rule_user_tracepoint";
return mi_lttng_loglevel_str_unknown;
}
break;
+ case LTTNG_DOMAIN_LOG4J2:
+ switch (value) {
+ case -1:
+ return mi_lttng_element_empty;
+ case LTTNG_LOGLEVEL_LOG4J2_OFF:
+ return mi_lttng_loglevel_str_log4j2_off;
+ case LTTNG_LOGLEVEL_LOG4J2_FATAL:
+ return mi_lttng_loglevel_str_log4j2_fatal;
+ case LTTNG_LOGLEVEL_LOG4J2_ERROR:
+ return mi_lttng_loglevel_str_log4j2_error;
+ case LTTNG_LOGLEVEL_LOG4J2_WARN:
+ return mi_lttng_loglevel_str_log4j2_warn;
+ case LTTNG_LOGLEVEL_LOG4J2_INFO:
+ return mi_lttng_loglevel_str_log4j2_info;
+ case LTTNG_LOGLEVEL_LOG4J2_DEBUG:
+ return mi_lttng_loglevel_str_log4j2_debug;
+ case LTTNG_LOGLEVEL_LOG4J2_TRACE:
+ return mi_lttng_loglevel_str_log4j2_trace;
+ case LTTNG_LOGLEVEL_LOG4J2_ALL:
+ return mi_lttng_loglevel_str_log4j2_all;
+ default:
+ return mi_lttng_loglevel_str_unknown;
+ }
+ break;
case LTTNG_DOMAIN_JUL:
switch (value) {
case -1:
return config_domain_type_jul;
case LTTNG_DOMAIN_LOG4J:
return config_domain_type_log4j;
+ case LTTNG_DOMAIN_LOG4J2:
+ return config_domain_type_log4j2;
case LTTNG_DOMAIN_PYTHON:
return config_domain_type_python;
default:
LTTNG_EXPORT extern const char *const mi_lttng_loglevel_str_log4j_trace;
LTTNG_EXPORT extern const char *const mi_lttng_loglevel_str_log4j_all;
+/* String related to loglevel Log4j2 */
+extern const char *const mi_lttng_loglevel_str_log4j2_off;
+extern const char *const mi_lttng_loglevel_str_log4j2_fatal;
+extern const char *const mi_lttng_loglevel_str_log4j2_error;
+extern const char *const mi_lttng_loglevel_str_log4j2_warn;
+extern const char *const mi_lttng_loglevel_str_log4j2_info;
+extern const char *const mi_lttng_loglevel_str_log4j2_debug;
+extern const char *const mi_lttng_loglevel_str_log4j2_trace;
+extern const char *const mi_lttng_loglevel_str_log4j2_all;
+
/* String related to loglevel Python */
LTTNG_EXPORT extern const char *const mi_lttng_loglevel_str_python_critical;
LTTNG_EXPORT extern const char *const mi_lttng_loglevel_str_python_error;
extern const char *const mi_lttng_element_event_rule_kernel_tracepoint;
extern const char *const mi_lttng_element_event_rule_kernel_uprobe;
extern const char *const mi_lttng_element_event_rule_log4j_logging;
+extern const char *const mi_lttng_element_event_rule_log4j2_logging;
extern const char *const mi_lttng_element_event_rule_python_logging;
extern const char *const mi_lttng_element_event_rule_user_tracepoint;
<xs:enumeration value="UST"/>
<xs:enumeration value="JUL"/>
<xs:enumeration value="LOG4J"/>
+ <xs:enumeration value="LOG4J2"/>
<xs:enumeration value="PYTHON"/>
</xs:restriction>
</xs:simpleType>
config_domain_type_jul
config_domain_type_kernel
config_domain_type_log4j
+config_domain_type_log4j2
config_domain_type_python
config_domain_type_ust
config_element_address
lttng_event_rule_log4j_logging_set_filter
lttng_event_rule_log4j_logging_set_log_level_rule
lttng_event_rule_log4j_logging_set_name_pattern
+lttng_event_rule_log4j2_logging_create
+lttng_event_rule_log4j2_logging_get_filter
+lttng_event_rule_log4j2_logging_get_log_level_rule
+lttng_event_rule_log4j2_logging_get_name_pattern
+lttng_event_rule_log4j2_logging_set_filter
+lttng_event_rule_log4j2_logging_set_log_level_rule
+lttng_event_rule_log4j2_logging_set_name_pattern
lttng_event_rule_python_logging_create
lttng_event_rule_python_logging_get_filter
lttng_event_rule_python_logging_get_log_level_rule
case LTTNG_DOMAIN_UST:
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
+ case LTTNG_DOMAIN_LOG4J2:
case LTTNG_DOMAIN_PYTHON:
memcpy(dst, src, sizeof(struct lttng_domain));
break;
*
* An event with NO loglevel and the name is * will return NULL.
*/
-static char *set_agent_filter(const char *filter, struct lttng_event *ev)
+static char *
+set_agent_filter(const char *filter, struct lttng_event *ev, struct lttng_domain *domain)
{
int err;
char *agent_filter = nullptr;
LTTNG_ASSERT(ev);
+ LTTNG_ASSERT(domain);
/* Don't add filter for the '*' event. */
if (strcmp(ev->name, "*") != 0) {
}
}
- /* Add loglevel filtering if any for the JUL domain. */
+ /* Add loglevel filtering if any for the agent domains. */
if (ev->loglevel_type != LTTNG_EVENT_LOGLEVEL_ALL) {
const char *op;
if (ev->loglevel_type == LTTNG_EVENT_LOGLEVEL_RANGE) {
- op = ">=";
+ /*
+ * Log4j2 is the only agent domain for which more severe
+ * logging levels have a lower numerical value.
+ */
+ if (domain->type == LTTNG_DOMAIN_LOG4J2) {
+ op = "<=";
+ } else {
+ op = ">=";
+ }
} else {
op = "==";
}
/* Parse filter expression. */
if (filter_expression != nullptr || handle->domain.type == LTTNG_DOMAIN_JUL ||
handle->domain.type == LTTNG_DOMAIN_LOG4J ||
+ handle->domain.type == LTTNG_DOMAIN_LOG4J2 ||
handle->domain.type == LTTNG_DOMAIN_PYTHON) {
if (handle->domain.type == LTTNG_DOMAIN_JUL ||
handle->domain.type == LTTNG_DOMAIN_LOG4J ||
+ handle->domain.type == LTTNG_DOMAIN_LOG4J2 ||
handle->domain.type == LTTNG_DOMAIN_PYTHON) {
char *agent_filter;
/* Setup agent filter if needed. */
- agent_filter = set_agent_filter(filter_expression, ev);
+ agent_filter = set_agent_filter(filter_expression, ev, &handle->domain);
if (!agent_filter) {
if (!filter_expression) {
/*
- * No JUL and no filter, just skip
+ * No agent and no filter, just skip
* everything below.
*/
goto serialize;
/* Parse filter expression. */
if (filter_expression != nullptr || handle->domain.type == LTTNG_DOMAIN_JUL ||
handle->domain.type == LTTNG_DOMAIN_LOG4J ||
+ handle->domain.type == LTTNG_DOMAIN_LOG4J2 ||
handle->domain.type == LTTNG_DOMAIN_PYTHON) {
if (handle->domain.type == LTTNG_DOMAIN_JUL ||
handle->domain.type == LTTNG_DOMAIN_LOG4J ||
+ handle->domain.type == LTTNG_DOMAIN_LOG4J2 ||
handle->domain.type == LTTNG_DOMAIN_PYTHON) {
char *agent_filter;
/* Setup agent filter if needed. */
- agent_filter = set_agent_filter(filter_expression, ev);
+ agent_filter = set_agent_filter(filter_expression, ev, &handle->domain);
if (!agent_filter) {
if (!filter_expression) {
/*