X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fmi-lttng.c;h=1073c84ec54582185177a6bcf51d38db2db57093;hp=a250546d75bfe45d1c974725187ffef258d19eef;hb=eecb9438e176fe991bacb70c923bb247bd62e465;hpb=3b4a6e401ee2df275299aa0460f0ae5b693f8aba diff --git a/src/common/mi-lttng.c b/src/common/mi-lttng.c index a250546d7..1073c84ec 100644 --- a/src/common/mi-lttng.c +++ b/src/common/mi-lttng.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2014 - Jonathan Rajotte * - Olivier Cotte + * Copyright (C) 2016 - Jérémie Galarneau * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License, version 2 only, as @@ -16,14 +17,31 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - -#include -#include +#define _LGPL_SOURCE +#include +#include #include #include "mi-lttng.h" #include +#define MI_SCHEMA_MAJOR_VERSION 3 +#define MI_SCHEMA_MINOR_VERSION 0 + +/* Machine interface namespace URI */ +const char * const mi_lttng_xmlns = "xmlns"; +const char * const mi_lttng_xmlns_xsi = "xmlns:xsi"; +const char * const mi_lttng_w3_schema_uri = "http://www.w3.org/2001/XMLSchema-instance"; +const char * const mi_lttng_schema_location = "xsi:schemaLocation"; +const char * const mi_lttng_schema_location_uri = + DEFAULT_LTTNG_MI_NAMESPACE " " + "http://lttng.org/xml/schemas/lttng-mi/" XSTR(MI_SCHEMA_MAJOR_VERSION) + "/lttng-mi-" XSTR(MI_SCHEMA_MAJOR_VERSION) "." + XSTR(MI_SCHEMA_MINOR_VERSION) ".xsd"; +const char * const mi_lttng_schema_version = "schemaVersion"; +const char * const mi_lttng_schema_version_value = XSTR(MI_SCHEMA_MAJOR_VERSION) + "." XSTR(MI_SCHEMA_MINOR_VERSION); + /* Strings related to command */ const char * const mi_lttng_element_command = "command"; const char * const mi_lttng_element_command_action = "snapshot_action"; @@ -49,6 +67,8 @@ const char * const mi_lttng_element_command_snapshot_record = "record_snapshot"; const char * const mi_lttng_element_command_start = "start"; const char * const mi_lttng_element_command_stop = "stop"; const char * const mi_lttng_element_command_success = "success"; +const char * const mi_lttng_element_command_track = "track"; +const char * const mi_lttng_element_command_untrack = "untrack"; const char * const mi_lttng_element_command_version = "version"; /* Strings related to version command */ @@ -66,17 +86,10 @@ const char * const mi_lttng_element_version_web = "url"; const char * const mi_lttng_element_event_field = "event_field"; const char * const mi_lttng_element_event_fields = "event_fields"; -/* String related to lttng_event_context */ -const char * const mi_lttng_context_type_perf_counter = "PERF_COUNTER"; -const char * const mi_lttng_context_type_perf_cpu_counter = "PERF_CPU_COUNTER"; -const char * const mi_lttng_context_type_perf_thread_counter = "PERF_THREAD_COUNTER"; - /* String related to lttng_event_perf_counter_ctx */ -const char * const mi_lttng_element_perf_counter_context = "perf_counter_context"; +const char * const mi_lttng_element_perf_counter_context = "perf"; /* Strings related to pid */ -const char * const mi_lttng_element_pids = "pids"; -const char * const mi_lttng_element_pid = "pid"; const char * const mi_lttng_element_pid_id = "id"; /* Strings related to save command */ @@ -125,6 +138,24 @@ const char * const mi_lttng_loglevel_str_jul_off = "JUL_OFF"; const char * const mi_lttng_loglevel_str_jul_severe = "JUL_SEVERE"; const char * const mi_lttng_loglevel_str_jul_warning = "JUL_WARNING"; +/* String related to loglevel LOG4J */ +const char * const mi_lttng_loglevel_str_log4j_off = "LOG4J_OFF"; +const char * const mi_lttng_loglevel_str_log4j_fatal = "LOG4J_FATAL"; +const char * const mi_lttng_loglevel_str_log4j_error = "LOG4J_ERROR"; +const char * const mi_lttng_loglevel_str_log4j_warn = "LOG4J_WARN"; +const char * const mi_lttng_loglevel_str_log4j_info = "LOG4J_INFO"; +const char * const mi_lttng_loglevel_str_log4j_debug = "LOG4J_DEBUG"; +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 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_loglevel_str_python_warning = "PYTHON_WARNING"; +const char * const mi_lttng_loglevel_str_python_info = "PYTHON_INFO"; +const char * const mi_lttng_loglevel_str_python_debug = "PYTHON_DEBUG"; +const char * const mi_lttng_loglevel_str_python_notset = "PYTHON_NOTSET"; + /* String related to loglevel type */ const char * const mi_lttng_loglevel_type_all = "ALL"; const char * const mi_lttng_loglevel_type_range = "RANGE"; @@ -143,68 +174,132 @@ const char * const mi_lttng_element_snapshot_n_ptr = "n_ptr"; const char * const mi_lttng_element_snapshot_session_name = "session_name"; const char * const mi_lttng_element_snapshots = "snapshots"; +/* String related to track/untrack command */ +const char * const mi_lttng_element_track_untrack_all_wildcard = "*"; + + /* This is a merge of jul loglevel and regular loglevel * Those should never overlap by definition * (see struct lttng_event loglevel) */ -const char *mi_lttng_loglevel_string(int value) +LTTNG_HIDDEN +const char *mi_lttng_loglevel_string(int value, enum lttng_domain_type domain) { - switch (value) { - case -1: - return mi_lttng_element_empty; - case LTTNG_LOGLEVEL_EMERG: - return mi_lttng_loglevel_str_emerg; - case LTTNG_LOGLEVEL_ALERT: - return mi_lttng_loglevel_str_alert; - case LTTNG_LOGLEVEL_CRIT: - return mi_lttng_loglevel_str_crit; - case LTTNG_LOGLEVEL_ERR: - return mi_lttng_loglevel_str_err; - case LTTNG_LOGLEVEL_WARNING: - return mi_lttng_loglevel_str_warning; - case LTTNG_LOGLEVEL_NOTICE: - return mi_lttng_loglevel_str_notice; - case LTTNG_LOGLEVEL_INFO: - return mi_lttng_loglevel_str_info; - case LTTNG_LOGLEVEL_DEBUG_SYSTEM: - return mi_lttng_loglevel_str_debug_system; - case LTTNG_LOGLEVEL_DEBUG_PROGRAM: - return mi_lttng_loglevel_str_debug_program; - case LTTNG_LOGLEVEL_DEBUG_PROCESS: - return mi_lttng_loglevel_str_debug_process; - case LTTNG_LOGLEVEL_DEBUG_MODULE: - return mi_lttng_loglevel_str_debug_module; - case LTTNG_LOGLEVEL_DEBUG_UNIT: - return mi_lttng_loglevel_str_debug_unit; - case LTTNG_LOGLEVEL_DEBUG_FUNCTION: - return mi_lttng_loglevel_str_debug_function; - case LTTNG_LOGLEVEL_DEBUG_LINE: - return mi_lttng_loglevel_str_debug_line; - case LTTNG_LOGLEVEL_DEBUG: - return mi_lttng_loglevel_str_debug; - case LTTNG_LOGLEVEL_JUL_OFF: - return mi_lttng_loglevel_str_jul_off; - case LTTNG_LOGLEVEL_JUL_SEVERE: - return mi_lttng_loglevel_str_jul_severe; - case LTTNG_LOGLEVEL_JUL_WARNING: - return mi_lttng_loglevel_str_jul_warning; - case LTTNG_LOGLEVEL_JUL_INFO: - return mi_lttng_loglevel_str_jul_info; - case LTTNG_LOGLEVEL_JUL_CONFIG: - return mi_lttng_loglevel_str_jul_config; - case LTTNG_LOGLEVEL_JUL_FINE: - return mi_lttng_loglevel_str_jul_fine; - case LTTNG_LOGLEVEL_JUL_FINER: - return mi_lttng_loglevel_str_jul_finer; - case LTTNG_LOGLEVEL_JUL_FINEST: - return mi_lttng_loglevel_str_jul_finest; - case LTTNG_LOGLEVEL_JUL_ALL: - return mi_lttng_loglevel_str_jul_all; - default: - return mi_lttng_loglevel_str_unknown; + switch (domain) { + case LTTNG_DOMAIN_KERNEL: + case LTTNG_DOMAIN_UST: + switch (value) { + case -1: + return mi_lttng_element_empty; + case LTTNG_LOGLEVEL_EMERG: + return mi_lttng_loglevel_str_emerg; + case LTTNG_LOGLEVEL_ALERT: + return mi_lttng_loglevel_str_alert; + case LTTNG_LOGLEVEL_CRIT: + return mi_lttng_loglevel_str_crit; + case LTTNG_LOGLEVEL_ERR: + return mi_lttng_loglevel_str_err; + case LTTNG_LOGLEVEL_WARNING: + return mi_lttng_loglevel_str_warning; + case LTTNG_LOGLEVEL_NOTICE: + return mi_lttng_loglevel_str_notice; + case LTTNG_LOGLEVEL_INFO: + return mi_lttng_loglevel_str_info; + case LTTNG_LOGLEVEL_DEBUG_SYSTEM: + return mi_lttng_loglevel_str_debug_system; + case LTTNG_LOGLEVEL_DEBUG_PROGRAM: + return mi_lttng_loglevel_str_debug_program; + case LTTNG_LOGLEVEL_DEBUG_PROCESS: + return mi_lttng_loglevel_str_debug_process; + case LTTNG_LOGLEVEL_DEBUG_MODULE: + return mi_lttng_loglevel_str_debug_module; + case LTTNG_LOGLEVEL_DEBUG_UNIT: + return mi_lttng_loglevel_str_debug_unit; + case LTTNG_LOGLEVEL_DEBUG_FUNCTION: + return mi_lttng_loglevel_str_debug_function; + case LTTNG_LOGLEVEL_DEBUG_LINE: + return mi_lttng_loglevel_str_debug_line; + case LTTNG_LOGLEVEL_DEBUG: + return mi_lttng_loglevel_str_debug; + default: + return mi_lttng_loglevel_str_unknown; + } + break; + case LTTNG_DOMAIN_LOG4J: + switch (value) { + case -1: + return mi_lttng_element_empty; + case LTTNG_LOGLEVEL_LOG4J_OFF: + return mi_lttng_loglevel_str_log4j_off; + case LTTNG_LOGLEVEL_LOG4J_FATAL: + return mi_lttng_loglevel_str_log4j_fatal; + case LTTNG_LOGLEVEL_LOG4J_ERROR: + return mi_lttng_loglevel_str_log4j_error; + case LTTNG_LOGLEVEL_LOG4J_WARN: + return mi_lttng_loglevel_str_log4j_warn; + case LTTNG_LOGLEVEL_LOG4J_INFO: + return mi_lttng_loglevel_str_log4j_info; + case LTTNG_LOGLEVEL_LOG4J_DEBUG: + return mi_lttng_loglevel_str_log4j_debug; + case LTTNG_LOGLEVEL_LOG4J_TRACE: + return mi_lttng_loglevel_str_log4j_trace; + case LTTNG_LOGLEVEL_LOG4J_ALL: + return mi_lttng_loglevel_str_log4j_all; + default: + return mi_lttng_loglevel_str_unknown; + } + break; + case LTTNG_DOMAIN_JUL: + switch (value) { + case -1: + return mi_lttng_element_empty; + case LTTNG_LOGLEVEL_JUL_OFF: + return mi_lttng_loglevel_str_jul_off; + case LTTNG_LOGLEVEL_JUL_SEVERE: + return mi_lttng_loglevel_str_jul_severe; + case LTTNG_LOGLEVEL_JUL_WARNING: + return mi_lttng_loglevel_str_jul_warning; + case LTTNG_LOGLEVEL_JUL_INFO: + return mi_lttng_loglevel_str_jul_info; + case LTTNG_LOGLEVEL_JUL_CONFIG: + return mi_lttng_loglevel_str_jul_config; + case LTTNG_LOGLEVEL_JUL_FINE: + return mi_lttng_loglevel_str_jul_fine; + case LTTNG_LOGLEVEL_JUL_FINER: + return mi_lttng_loglevel_str_jul_finer; + case LTTNG_LOGLEVEL_JUL_FINEST: + return mi_lttng_loglevel_str_jul_finest; + case LTTNG_LOGLEVEL_JUL_ALL: + return mi_lttng_loglevel_str_jul_all; + default: + return mi_lttng_loglevel_str_unknown; + } + break; + case LTTNG_DOMAIN_PYTHON: + switch (value) { + case LTTNG_LOGLEVEL_PYTHON_CRITICAL: + return mi_lttng_loglevel_str_python_critical; + case LTTNG_LOGLEVEL_PYTHON_ERROR: + return mi_lttng_loglevel_str_python_error; + case LTTNG_LOGLEVEL_PYTHON_WARNING: + return mi_lttng_loglevel_str_python_warning; + case LTTNG_LOGLEVEL_PYTHON_INFO: + return mi_lttng_loglevel_str_python_info; + case LTTNG_LOGLEVEL_PYTHON_DEBUG: + return mi_lttng_loglevel_str_python_debug; + case LTTNG_LOGLEVEL_PYTHON_NOTSET: + return mi_lttng_loglevel_str_python_notset; + default: + return mi_lttng_loglevel_str_unknown; + } + break; } + + /* Reaching this means the domain is unknown. */ + return mi_lttng_loglevel_str_unknown; } +LTTNG_HIDDEN const char *mi_lttng_logleveltype_string(enum lttng_loglevel_type value) { switch (value) { @@ -219,6 +314,7 @@ const char *mi_lttng_logleveltype_string(enum lttng_loglevel_type value) } } +LTTNG_HIDDEN const char *mi_lttng_eventtype_string(enum lttng_event_type value) { switch (value) { @@ -241,17 +337,12 @@ const char *mi_lttng_eventtype_string(enum lttng_event_type value) } } +static const char *mi_lttng_event_contexttype_string(enum lttng_event_context_type val) { switch (val) { case LTTNG_EVENT_CONTEXT_PID: return config_event_context_pid; - case LTTNG_EVENT_CONTEXT_PERF_COUNTER: - return mi_lttng_context_type_perf_counter; - case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER: - return mi_lttng_context_type_perf_thread_counter; - case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER: - return mi_lttng_context_type_perf_cpu_counter; case LTTNG_EVENT_CONTEXT_PROCNAME: return config_event_context_procname; case LTTNG_EVENT_CONTEXT_PRIO: @@ -279,6 +370,7 @@ const char *mi_lttng_event_contexttype_string(enum lttng_event_context_type val) } } +LTTNG_HIDDEN const char *mi_lttng_eventfieldtype_string(enum lttng_event_field_type val) { switch (val) { @@ -295,6 +387,7 @@ const char *mi_lttng_eventfieldtype_string(enum lttng_event_field_type val) } } +LTTNG_HIDDEN const char *mi_lttng_domaintype_string(enum lttng_domain_type value) { /* Note: This is a *duplicate* of get_domain_str from bin/lttng/utils.c */ @@ -307,12 +400,16 @@ const char *mi_lttng_domaintype_string(enum lttng_domain_type value) return config_domain_type_jul; case LTTNG_DOMAIN_LOG4J: return config_domain_type_log4j; + case LTTNG_DOMAIN_PYTHON: + return config_domain_type_python; default: /* Should not have an unknown domain */ assert(0); + return NULL; } } +LTTNG_HIDDEN const char *mi_lttng_buffertype_string(enum lttng_buffer_type value) { switch (value) { @@ -325,9 +422,11 @@ const char *mi_lttng_buffertype_string(enum lttng_buffer_type value) default: /* Should not have an unknow buffer type */ assert(0); + return NULL; } } +LTTNG_HIDDEN const char *mi_lttng_calibratetype_string(enum lttng_calibrate_type val) { const char *ret; @@ -396,10 +495,42 @@ int mi_lttng_writer_command_open(struct mi_writer *writer, const char *command) { int ret; - ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command); + /* + * A command is always the MI's root node, it must declare the current + * namespace and schema URIs and the schema's version. + */ + ret = config_writer_open_element(writer->writer, + mi_lttng_element_command); + if (ret) { + goto end; + } + + ret = config_writer_write_attribute(writer->writer, + mi_lttng_xmlns, DEFAULT_LTTNG_MI_NAMESPACE); + if (ret) { + goto end; + } + + ret = config_writer_write_attribute(writer->writer, + mi_lttng_xmlns_xsi, mi_lttng_w3_schema_uri); + if (ret) { + goto end; + } + + ret = config_writer_write_attribute(writer->writer, + mi_lttng_schema_location, + mi_lttng_schema_location_uri); + if (ret) { + goto end; + } + + ret = config_writer_write_attribute(writer->writer, + mi_lttng_schema_version, + mi_lttng_schema_version_value); if (ret) { goto end; } + ret = mi_lttng_writer_write_element_string(writer, mi_lttng_element_command_name, command); end: @@ -831,6 +962,7 @@ int mi_lttng_event_common_attributes(struct mi_writer *writer, struct lttng_event *event) { int ret; + const char *filter_expression; /* Open event element */ ret = mi_lttng_writer_open_element(writer, config_element_event); @@ -859,9 +991,72 @@ int mi_lttng_event_common_attributes(struct mi_writer *writer, goto end; } - /* Event filter enabled? */ + /* Event filter expression */ + ret = lttng_event_get_filter_string(event, &filter_expression); + if (ret) { + goto end; + } + + if (filter_expression) { + ret = mi_lttng_writer_write_element_string(writer, + config_element_filter_expression, + filter_expression); + if (ret) { + goto end; + } + } + +end: + return ret; +} + +static int write_event_exclusions(struct mi_writer *writer, + struct lttng_event *event) +{ + int i; + int ret; + int exclusion_count; + + /* event exclusion filter */ ret = mi_lttng_writer_write_element_bool(writer, - config_element_filter, event->filter); + config_element_exclusion, event->exclusion); + if (ret) { + goto end; + } + + /* Open event exclusions */ + ret = mi_lttng_writer_open_element(writer, config_element_exclusions); + if (ret) { + goto end; + } + + exclusion_count = lttng_event_get_exclusion_name_count(event); + if (exclusion_count < 0) { + ret = exclusion_count; + goto end; + } + + for (i = 0; i < exclusion_count; i++) { + const char *name; + + ret = lttng_event_get_exclusion_name(event, i, &name); + if (ret) { + /* Close exclusions */ + mi_lttng_writer_close_element(writer); + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + config_element_exclusion, name); + if (ret) { + /* Close exclusions */ + mi_lttng_writer_close_element(writer); + goto end; + } + } + + /* Close exclusions */ + ret = mi_lttng_writer_close_element(writer); end: return ret; @@ -869,13 +1064,14 @@ end: LTTNG_HIDDEN int mi_lttng_event_tracepoint_loglevel(struct mi_writer *writer, - struct lttng_event *event) + struct lttng_event *event, enum lttng_domain_type domain) { int ret; /* Event loglevel */ ret = mi_lttng_writer_write_element_string(writer, - config_element_loglevel, mi_lttng_loglevel_string(event->loglevel)); + config_element_loglevel, + mi_lttng_loglevel_string(event->loglevel, domain)); if (ret) { goto end; } @@ -888,12 +1084,8 @@ int mi_lttng_event_tracepoint_loglevel(struct mi_writer *writer, goto end; } - /* event exclusion filter */ - ret = mi_lttng_writer_write_element_bool(writer, - config_element_exclusion, event->exclusion); - if (ret) { - goto end; - } + /* Event exclusions */ + ret = write_event_exclusions(writer, event); end: return ret; @@ -904,8 +1096,7 @@ int mi_lttng_event_tracepoint_no_loglevel(struct mi_writer *writer, struct lttng_event *event) { /* event exclusion filter */ - return mi_lttng_writer_write_element_bool(writer, - config_element_exclusion, event->exclusion); + return write_event_exclusions(writer, event); } LTTNG_HIDDEN @@ -990,7 +1181,7 @@ int mi_lttng_events_open(struct mi_writer *writer) LTTNG_HIDDEN int mi_lttng_event(struct mi_writer *writer, - struct lttng_event *event, int is_open) + struct lttng_event *event, int is_open, enum lttng_domain_type domain) { int ret; @@ -1003,7 +1194,7 @@ int mi_lttng_event(struct mi_writer *writer, case LTTNG_EVENT_TRACEPOINT: { if (event->loglevel != -1) { - ret = mi_lttng_event_tracepoint_loglevel(writer, event); + ret = mi_lttng_event_tracepoint_loglevel(writer, event, domain); } else { ret = mi_lttng_event_tracepoint_no_loglevel(writer, event); } @@ -1031,20 +1222,47 @@ end: return ret; } +LTTNG_HIDDEN +int mi_lttng_trackers_open(struct mi_writer *writer) +{ + return mi_lttng_writer_open_element(writer, config_element_trackers); +} + +LTTNG_HIDDEN +int mi_lttng_pid_tracker_open(struct mi_writer *writer) +{ + int ret; + + /* Open element pid_tracker */ + ret = mi_lttng_writer_open_element(writer, config_element_pid_tracker); + if (ret) { + goto end; + } + + /* Open targets element */ + ret = mi_lttng_targets_open(writer); +end: + return ret; +} + LTTNG_HIDDEN int mi_lttng_pids_open(struct mi_writer *writer) { - return mi_lttng_writer_open_element(writer, mi_lttng_element_pids); + return mi_lttng_writer_open_element(writer, config_element_pids); } +/* + * TODO: move the listing of pid for user agent to process semantic on + * mi api bump. The use of process element break the mi api. + */ LTTNG_HIDDEN -int mi_lttng_pid(struct mi_writer *writer, pid_t pid , const char *cmdline, +int mi_lttng_pid(struct mi_writer *writer, pid_t pid , const char *name, int is_open) { int ret; - /* Open element pid */ - ret = mi_lttng_writer_open_element(writer, mi_lttng_element_pid); + /* Open pid process */ + ret = mi_lttng_writer_open_element(writer, config_element_pid); if (ret) { goto end; } @@ -1057,15 +1275,62 @@ int mi_lttng_pid(struct mi_writer *writer, pid_t pid , const char *cmdline, } /* Writing name of the process */ - ret = mi_lttng_writer_write_element_string(writer, config_element_name, - cmdline); + if (name) { + ret = mi_lttng_writer_write_element_string(writer, config_element_name, + name); + if (ret) { + goto end; + } + } + + if (!is_open) { + /* Closing Pid */ + ret = mi_lttng_writer_close_element(writer); + } + +end: + return ret; +} + +LTTNG_HIDDEN +int mi_lttng_targets_open(struct mi_writer *writer) +{ + return mi_lttng_writer_open_element(writer, + config_element_targets); +} + +LTTNG_HIDDEN +int mi_lttng_pid_target(struct mi_writer *writer, pid_t pid, int is_open) +{ + int ret; + + ret = mi_lttng_writer_open_element(writer, + config_element_target_pid); + if (ret) { + goto end; + } + + /* Writing pid number + * Special case for element all on track untrack command + * All pid is represented as wildcard * + */ + if ((int) pid == -1) { + ret = mi_lttng_writer_write_element_string(writer, + config_element_pid, + mi_lttng_element_track_untrack_all_wildcard); + } else { + ret = mi_lttng_writer_write_element_signed_int(writer, + config_element_pid, (int) pid); + } if (ret) { goto end; } if (!is_open) { - /* Closing Pid */ ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } } end: @@ -1152,90 +1417,139 @@ int mi_lttng_calibrate(struct mi_writer *writer, end: return ret; } + LTTNG_HIDDEN -int mi_lttng_context(struct mi_writer *writer, - struct lttng_event_context *context, int is_open) +int mi_lttng_perf_counter_context(struct mi_writer *writer, + struct lttng_event_perf_counter_ctx *perf_context) { int ret; - const char *type_string; - struct lttng_event_perf_counter_ctx *perf_context; - /* Open context */ - ret = mi_lttng_writer_open_element(writer , config_element_context); + + /* Open perf_counter_context */ + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_perf_counter_context); if (ret) { goto end; } - type_string = mi_lttng_event_contexttype_string(context->ctx); - if (!type_string) { - ret = -LTTNG_ERR_INVALID; + /* Type */ + ret = mi_lttng_writer_write_element_unsigned_int(writer, + config_element_type, perf_context->type); + if (ret) { goto end; } - /* Print context type */ - ret = mi_lttng_writer_write_element_string(writer, config_element_type, - type_string); - - /* Special case for PERF_*_COUNTER - * print the lttng_event_perf_counter_ctx*/ - switch (context->ctx) { - case LTTNG_EVENT_CONTEXT_PERF_COUNTER: - case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER: - case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER: - perf_context = &context->u.perf_counter; - ret = mi_lttng_perf_counter_context(writer, perf_context); - if (ret) { - goto end; - } - break; - default: - break; + /* Config */ + ret = mi_lttng_writer_write_element_unsigned_int(writer, + config_element_config, perf_context->config); + if (ret) { + goto end; } - /* Close context */ - if (!is_open) { - ret = mi_lttng_writer_close_element(writer); + /* Name of the perf counter */ + ret = mi_lttng_writer_write_element_string(writer, + config_element_name, perf_context->name); + if (ret) { + goto end; } + /* Close perf_counter_context */ + ret = mi_lttng_writer_close_element(writer); end: return ret; } -LTTNG_HIDDEN -int mi_lttng_perf_counter_context(struct mi_writer *writer, - struct lttng_event_perf_counter_ctx *perf_context) +static +int mi_lttng_app_context(struct mi_writer *writer, + const char *provider_name, const char *ctx_name) { int ret; - /* Open perf_counter_context */ + /* Open app */ ret = mi_lttng_writer_open_element(writer, - mi_lttng_element_perf_counter_context); + config_element_context_app); if (ret) { goto end; } - /* Type */ - ret = mi_lttng_writer_write_element_unsigned_int(writer, - config_element_type, perf_context->type); + /* provider_name */ + ret = mi_lttng_writer_write_element_string(writer, + config_element_context_app_provider_name, + provider_name); if (ret) { goto end; } - /* Config */ - ret = mi_lttng_writer_write_element_unsigned_int(writer, - config_element_config, perf_context->config); + /* ctx_name */ + ret = mi_lttng_writer_write_element_string(writer, + config_element_context_app_ctx_name, ctx_name); if (ret) { goto end; } - /* Name of the perf counter */ - ret = mi_lttng_writer_write_element_string(writer, - config_element_name, perf_context->name); + /* Close app */ + ret = mi_lttng_writer_close_element(writer); +end: + return ret; +} + +LTTNG_HIDDEN +int mi_lttng_context(struct mi_writer *writer, + struct lttng_event_context *context, int is_open) +{ + int ret; + + /* Open context */ + ret = mi_lttng_writer_open_element(writer , config_element_context); if (ret) { goto end; } - /* Close perf_counter_context */ - ret = mi_lttng_writer_close_element(writer); + /* Special case for PERF_*_COUNTER + * print the lttng_event_perf_counter_ctx*/ + switch (context->ctx) { + case LTTNG_EVENT_CONTEXT_PERF_COUNTER: + case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER: + case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER: + { + struct lttng_event_perf_counter_ctx *perf_context = + &context->u.perf_counter; + ret = mi_lttng_perf_counter_context(writer, perf_context); + if (ret) { + goto end; + } + break; + } + case LTTNG_EVENT_CONTEXT_APP_CONTEXT: + { + ret = mi_lttng_app_context(writer, + context->u.app_ctx.provider_name, + context->u.app_ctx.ctx_name); + if (ret) { + goto end; + } + break; + } + default: + { + const char *type_string = mi_lttng_event_contexttype_string( + context->ctx); + if (!type_string) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + /* Print context type */ + ret = mi_lttng_writer_write_element_string(writer, + config_element_type, type_string); + break; + } + } + + /* Close context */ + if (!is_open) { + ret = mi_lttng_writer_close_element(writer); + } + end: return ret; } @@ -1255,6 +1569,9 @@ int mi_lttng_snapshot_output_session_name(struct mi_writer *writer, /* Snapshot output list for current session name */ ret = mi_lttng_writer_write_element_string(writer, config_element_name, session_name); + if (ret) { + goto end; + } /* Open element snapshots (sequence one snapshot) */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_snapshots);