filter_expression, 0, NULL);
}
+/*
+ * Depending on the event, return a newly allocated JUL filter expression or
+ * NULL if not applicable.
+ *
+ * An event with NO loglevel and the name is * will return NULL.
+ */
+static char *set_jul_filter(const char *filter, struct lttng_event *ev)
+{
+ int err;
+ char *jul_filter = NULL;
+
+ assert(ev);
+
+ /* Don't add filter for the '*' event. */
+ if (ev->name[0] != '*') {
+ if (filter) {
+ err = asprintf(&jul_filter, "(%s) && (logger_name == \"%s\")", filter,
+ ev->name);
+ } else {
+ err = asprintf(&jul_filter, "logger_name == \"%s\"", ev->name);
+ }
+ if (err < 0) {
+ PERROR("asprintf");
+ goto error;
+ }
+ }
+
+ /* Add loglevel filtering if any for the JUL domain. */
+ if (ev->loglevel_type != LTTNG_EVENT_LOGLEVEL_ALL) {
+ char *op;
+
+ if (ev->loglevel_type == LTTNG_EVENT_LOGLEVEL_RANGE) {
+ op = ">=";
+ } else {
+ op = "==";
+ }
+
+ if (filter || jul_filter) {
+ char *new_filter;
+
+ err = asprintf(&new_filter, "(%s) && (int_loglevel %s %d)",
+ jul_filter ? jul_filter : filter, op,
+ ev->loglevel);
+ if (jul_filter) {
+ free(jul_filter);
+ }
+ jul_filter = new_filter;
+ } else {
+ err = asprintf(&jul_filter, "int_loglevel %s %d", op,
+ ev->loglevel);
+ }
+ if (err < 0) {
+ PERROR("asprintf");
+ goto error;
+ }
+ }
+
+ return jul_filter;
+error:
+ free(jul_filter);
+ return NULL;
+}
+
/*
* Enable event(s) for a channel, possibly with exclusions and a filter.
* If no event name is specified, all events are enabled.
*/
int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
struct lttng_event *ev, const char *channel_name,
- const char *filter_expression,
+ const char *original_filter_expression,
int exclusion_count, char **exclusion_list)
{
struct lttcomm_session_msg lsm;
- char *varlen_data, *jul_filter = NULL;
+ char *varlen_data;
int ret = 0;
struct filter_parser_ctx *ctx = NULL;
FILE *fmem = NULL;
+ /*
+ * Cast as non-const since we may replace the filter expression
+ * by a dynamically allocated string. Otherwise, the original
+ * string is not modified.
+ */
+ char *filter_expression = (char *) original_filter_expression;
+ int free_filter_expression = 0;
if (handle == NULL || ev == NULL) {
return -LTTNG_ERR_INVALID;
* filtering by logger name.
*/
if (exclusion_count == 0 && filter_expression == NULL &&
- (handle->domain.type != LTTNG_DOMAIN_JUL || ev->name[0] == '*')) {
- ret = lttng_ctl_ask_sessiond(&lsm, NULL);
- return ret;
+ handle->domain.type != LTTNG_DOMAIN_JUL) {
+ goto ask_sessiond;
}
/*
*/
/* Parse filter expression */
- if (filter_expression != NULL ||
- (handle->domain.type == LTTNG_DOMAIN_JUL && ev->name[0] != '*')) {
+ if (filter_expression != NULL || handle->domain.type == LTTNG_DOMAIN_JUL) {
if (handle->domain.type == LTTNG_DOMAIN_JUL) {
- int err;
+ char *jul_filter;
- if (filter_expression) {
- err = asprintf(&jul_filter, "%s && logger_name == \"%s\"",
- filter_expression, ev->name);
+ /* Setup JUL filter if needed. */
+ jul_filter = set_jul_filter(filter_expression, ev);
+ if (!jul_filter && !filter_expression) {
+ /* No JUL and no filter, just skip everything below. */
+ goto ask_sessiond;
} else {
- err = asprintf(&jul_filter, "logger_name == \"%s\"", ev->name);
- }
- if (err < 0) {
- PERROR("asprintf");
- return -LTTNG_ERR_NOMEM;
+ /*
+ * With a JUL filter, the original filter has been added to it
+ * thus replace the filter expression.
+ */
+ filter_expression = jul_filter;
+ free_filter_expression = 1;
}
- filter_expression = jul_filter;
}
/*
strlen(filter_expression), "r");
if (!fmem) {
fprintf(stderr, "Error opening memory as stream\n");
- free(jul_filter);
return -LTTNG_ERR_FILTER_NOMEM;
}
ctx = filter_parser_ctx_alloc(fmem);
if (fclose(fmem) != 0) {
perror("fclose");
}
+ if (free_filter_expression) {
+ /*
+ * The filter expression has been replaced and must be
+ * freed as it is not the original filter expression
+ * received as a parameter.
+ */
+ free(filter_expression);
+ }
}
- free(jul_filter);
return ret;
parse_error:
if (fclose(fmem) != 0) {
perror("fclose");
}
- free(jul_filter);
+ return ret;
+
+ask_sessiond:
+ ret = lttng_ctl_ask_sessiond(&lsm, NULL);
return ret;
}