2 * Copyright (C) 2014 - Jonathan Rajotte <jonathan.r.julien@gmail.com>
3 * - Olivier Cotte <olivier.cotte@polymtl.ca>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License, version 2 only, as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <include/config.h>
21 #include <common/config/config.h>
26 /* Strings related to command */
27 const char * const mi_lttng_element_command
= "command";
28 const char * const mi_lttng_element_command_version
= "version";
29 const char * const mi_lttng_element_command_list
= "list";
30 const char * const mi_lttng_element_command_save
= "save";
31 const char * const mi_lttng_element_command_load
= "load";
32 const char * const mi_lttng_element_command_name
= "name";
33 const char * const mi_lttng_element_command_start
= "start";
34 const char * const mi_lttng_element_command_stop
= "stop";
35 const char * const mi_lttng_element_command_output
= "output";
36 const char * const mi_lttng_element_command_success
= "success";
38 /* Strings related to version command */
39 const char * const mi_lttng_element_version
= "version";
40 const char * const mi_lttng_element_version_str
= "string";
41 const char * const mi_lttng_element_version_web
= "url";
42 const char * const mi_lttng_element_version_major
= "major";
43 const char * const mi_lttng_element_version_minor
= "minor";
44 const char * const mi_lttng_element_version_commit
= "commit";
45 const char * const mi_lttng_element_version_license
= "license";
46 const char * const mi_lttng_element_version_patch_level
= "patchLevel";
47 const char * const mi_lttng_element_version_description
= "description";
49 /* Strings related to pid */
50 const char * const mi_lttng_element_pids
= "pids";
51 const char * const mi_lttng_element_pid
= "pid";
52 const char * const mi_lttng_element_pid_id
= "id";
54 /* Strings related to save command */
55 const char * const mi_lttng_element_save
= "save";
57 /* Strings related to load command */
58 const char * const mi_lttng_element_load
= "load";
60 /* String related to a lttng_event_field */
61 const char * const mi_lttng_element_event_field
= "event_field";
62 const char * const mi_lttng_element_event_fields
= "event_fields";
64 /* General elements of mi_lttng */
65 const char * const mi_lttng_element_type_other
= "OTHER";
66 const char * const mi_lttng_element_type_integer
= "INTEGER";
67 const char * const mi_lttng_element_type_enum
= "ENUM";
68 const char * const mi_lttng_element_type_float
= "FLOAT";
69 const char * const mi_lttng_element_type_string
= "STRING";
70 const char * const mi_lttng_element_nowrite
= "nowrite";
72 /* String related to loglevel */
73 const char * const mi_lttng_loglevel_str_alert
= "TRACE_ALERT";
74 const char * const mi_lttng_loglevel_str_crit
= "TRACE_CRIT";
75 const char * const mi_lttng_loglevel_str_debug
= "TRACE_DEBUG";
76 const char * const mi_lttng_loglevel_str_debug_function
= "TRACE_DEBUG_FUNCTION";
77 const char * const mi_lttng_loglevel_str_debug_line
= "TRACE_DEBUG_LINE";
78 const char * const mi_lttng_loglevel_str_debug_module
= "TRACE_DEBUG_MODULE";
79 const char * const mi_lttng_loglevel_str_debug_process
= "TRACE_DEBUG_PROCESS";
80 const char * const mi_lttng_loglevel_str_debug_program
= "TRACE_DEBUG_PROGRAM";
81 const char * const mi_lttng_loglevel_str_debug_system
= "TRACE_DEBUG_SYSTEM";
82 const char * const mi_lttng_loglevel_str_debug_unit
= "TRACE_DEBUG_UNIT";
83 const char * const mi_lttng_loglevel_str_emerg
= "TRACE_EMERG";
84 const char * const mi_lttng_loglevel_str_err
= "TRACE_ERR";
85 const char * const mi_lttng_loglevel_str_info
= "TRACE_INFO";
86 const char * const mi_lttng_loglevel_str_notice
= "TRACE_NOTICE";
87 const char * const mi_lttng_loglevel_str_unknown
= "UNKNOWN";
88 const char * const mi_lttng_loglevel_str_warning
= "TRACE_WARNING";
90 /* String related to loglevel type */
91 const char * const mi_lttng_loglevel_type_all
= "ALL";
92 const char * const mi_lttng_loglevel_type_range
= "RANGE";
93 const char * const mi_lttng_loglevel_type_single
= "SINGLE";
94 const char * const mi_lttng_loglevel_type_unknown
= "UNKNOWN";
96 const char * const mi_lttng_element_empty
= "";
98 const char *mi_lttng_loglevel_string(int value
)
102 return mi_lttng_element_empty
;
103 case LTTNG_LOGLEVEL_EMERG
:
104 return mi_lttng_loglevel_str_emerg
;
105 case LTTNG_LOGLEVEL_ALERT
:
106 return mi_lttng_loglevel_str_alert
;
107 case LTTNG_LOGLEVEL_CRIT
:
108 return mi_lttng_loglevel_str_crit
;
109 case LTTNG_LOGLEVEL_ERR
:
110 return mi_lttng_loglevel_str_err
;
111 case LTTNG_LOGLEVEL_WARNING
:
112 return mi_lttng_loglevel_str_warning
;
113 case LTTNG_LOGLEVEL_NOTICE
:
114 return mi_lttng_loglevel_str_notice
;
115 case LTTNG_LOGLEVEL_INFO
:
116 return mi_lttng_loglevel_str_info
;
117 case LTTNG_LOGLEVEL_DEBUG_SYSTEM
:
118 return mi_lttng_loglevel_str_debug_system
;
119 case LTTNG_LOGLEVEL_DEBUG_PROGRAM
:
120 return mi_lttng_loglevel_str_debug_program
;
121 case LTTNG_LOGLEVEL_DEBUG_PROCESS
:
122 return mi_lttng_loglevel_str_debug_process
;
123 case LTTNG_LOGLEVEL_DEBUG_MODULE
:
124 return mi_lttng_loglevel_str_debug_module
;
125 case LTTNG_LOGLEVEL_DEBUG_UNIT
:
126 return mi_lttng_loglevel_str_debug_unit
;
127 case LTTNG_LOGLEVEL_DEBUG_FUNCTION
:
128 return mi_lttng_loglevel_str_debug_function
;
129 case LTTNG_LOGLEVEL_DEBUG_LINE
:
130 return mi_lttng_loglevel_str_debug_line
;
131 case LTTNG_LOGLEVEL_DEBUG
:
132 return mi_lttng_loglevel_str_debug
;
134 return mi_lttng_loglevel_str_unknown
;
138 const char *mi_lttng_logleveltype_string(enum lttng_loglevel_type value
)
141 case LTTNG_EVENT_LOGLEVEL_ALL
:
142 return mi_lttng_loglevel_type_all
;
143 case LTTNG_EVENT_LOGLEVEL_RANGE
:
144 return mi_lttng_loglevel_type_range
;
145 case LTTNG_EVENT_LOGLEVEL_SINGLE
:
146 return mi_lttng_loglevel_type_single
;
148 return mi_lttng_loglevel_type_unknown
;
152 const char *mi_lttng_eventtype_string(enum lttng_event_type value
)
155 case LTTNG_EVENT_ALL
:
156 return config_event_type_all
;
157 case LTTNG_EVENT_TRACEPOINT
:
158 return config_event_type_tracepoint
;
159 case LTTNG_EVENT_PROBE
:
160 return config_event_type_probe
;
161 case LTTNG_EVENT_FUNCTION
:
162 return config_event_type_function
;
163 case LTTNG_EVENT_FUNCTION_ENTRY
:
164 return config_event_type_function_entry
;
165 case LTTNG_EVENT_SYSCALL
:
166 return config_event_type_syscall
;
167 case LTTNG_EVENT_NOOP
:
168 return config_event_type_noop
;
170 return mi_lttng_element_empty
;
174 const char *mi_lttng_eventfieldtype_string(enum lttng_event_field_type val
)
177 case(LTTNG_EVENT_FIELD_INTEGER
):
178 return mi_lttng_element_type_integer
;
179 case(LTTNG_EVENT_FIELD_ENUM
):
180 return mi_lttng_element_type_enum
;
181 case(LTTNG_EVENT_FIELD_FLOAT
):
182 return mi_lttng_element_type_float
;
183 case(LTTNG_EVENT_FIELD_STRING
):
184 return mi_lttng_element_type_string
;
186 return mi_lttng_element_type_other
;
190 const char *mi_lttng_domaintype_string(enum lttng_domain_type value
)
192 /* Note: This is a *duplicate* of get_domain_str from bin/lttng/utils.c */
194 case LTTNG_DOMAIN_KERNEL
:
195 return config_domain_type_kernel
;
196 case LTTNG_DOMAIN_UST
:
197 return config_domain_type_ust
;
198 case LTTNG_DOMAIN_JUL
:
199 return config_domain_type_jul
;
201 /* Should not have an unknown domain */
206 const char *mi_lttng_buffertype_string(enum lttng_buffer_type value
)
209 case LTTNG_BUFFER_PER_PID
:
210 return config_buffer_type_per_pid
;
211 case LTTNG_BUFFER_PER_UID
:
212 return config_buffer_type_per_uid
;
213 case LTTNG_BUFFER_GLOBAL
:
214 return config_buffer_type_global
;
216 /* Should not have an unknow buffer type */
222 struct mi_writer
*mi_lttng_writer_create(int fd_output
, int mi_output_type
)
224 struct mi_writer
*mi_writer
;
226 mi_writer
= zmalloc(sizeof(struct mi_writer
));
228 PERROR("zmalloc mi_writer_create");
231 if (mi_output_type
== LTTNG_MI_XML
) {
232 mi_writer
->writer
= config_writer_create(fd_output
);
233 if (!mi_writer
->writer
) {
236 mi_writer
->type
= LTTNG_MI_XML
;
250 int mi_lttng_writer_destroy(struct mi_writer
*writer
)
259 ret
= config_writer_destroy(writer
->writer
);
270 int mi_lttng_writer_command_open(struct mi_writer
*writer
, const char *command
)
274 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_command
);
278 ret
= mi_lttng_writer_write_element_string(writer
,
279 mi_lttng_element_command_name
, command
);
285 int mi_lttng_writer_command_close(struct mi_writer
*writer
)
287 return mi_lttng_writer_close_element(writer
);
291 int mi_lttng_writer_open_element(struct mi_writer
*writer
,
292 const char *element_name
)
294 return config_writer_open_element(writer
->writer
, element_name
);
298 int mi_lttng_writer_close_element(struct mi_writer
*writer
)
300 return config_writer_close_element(writer
->writer
);
304 int mi_lttng_close_multi_element(struct mi_writer
*writer
,
305 unsigned int nb_element
)
309 if (nb_element
< 1) {
313 for (i
= 0; i
< nb_element
; i
++) {
314 ret
= mi_lttng_writer_close_element(writer
);
324 int mi_lttng_writer_write_element_unsigned_int(struct mi_writer
*writer
,
325 const char *element_name
, uint64_t value
)
327 return config_writer_write_element_unsigned_int(writer
->writer
,
328 element_name
, value
);
332 int mi_lttng_writer_write_element_signed_int(struct mi_writer
*writer
,
333 const char *element_name
, int64_t value
)
335 return config_writer_write_element_signed_int(writer
->writer
,
336 element_name
, value
);
340 int mi_lttng_writer_write_element_bool(struct mi_writer
*writer
,
341 const char *element_name
, int value
)
343 return config_writer_write_element_bool(writer
->writer
,
344 element_name
, value
);
348 int mi_lttng_writer_write_element_string(struct mi_writer
*writer
,
349 const char *element_name
, const char *value
)
351 return config_writer_write_element_string(writer
->writer
,
352 element_name
, value
);
356 int mi_lttng_version(struct mi_writer
*writer
, struct mi_lttng_version
*version
,
357 const char *lttng_description
, const char *lttng_license
)
362 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_version
);
367 /* Version string (contain info like rc etc.) */
368 ret
= mi_lttng_writer_write_element_string(writer
,
369 mi_lttng_element_version_str
, VERSION
);
374 /* Major version number */
375 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
376 mi_lttng_element_version_major
, version
->version_major
);
381 /* Minor version number */
382 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
383 mi_lttng_element_version_minor
, version
->version_minor
);
388 /* Commit version number */
389 ret
= mi_lttng_writer_write_element_string(writer
,
390 mi_lttng_element_version_commit
, version
->version_commit
);
396 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
397 mi_lttng_element_version_patch_level
, version
->version_patchlevel
);
402 /* Name of the version */
403 ret
= mi_lttng_writer_write_element_string(writer
,
404 config_element_name
, version
->version_name
);
409 /* Description mostly related to beer... */
410 ret
= mi_lttng_writer_write_element_string(writer
,
411 mi_lttng_element_version_description
, lttng_description
);
417 ret
= mi_lttng_writer_write_element_string(writer
,
418 mi_lttng_element_version_web
, version
->package_url
);
423 /* License: free as in free beer...no...*speech* */
424 ret
= mi_lttng_writer_write_element_string(writer
,
425 mi_lttng_element_version_license
, lttng_license
);
430 /* Close version element */
431 ret
= mi_lttng_writer_close_element(writer
);
438 int mi_lttng_sessions_open(struct mi_writer
*writer
)
440 return mi_lttng_writer_open_element(writer
, config_element_sessions
);
444 int mi_lttng_session(struct mi_writer
*writer
,
445 struct lttng_session
*session
, int is_open
)
451 /* Open sessions element */
452 ret
= mi_lttng_writer_open_element(writer
,
453 config_element_session
);
458 /* Name of the session */
459 ret
= mi_lttng_writer_write_element_string(writer
,
460 config_element_name
, session
->name
);
466 ret
= mi_lttng_writer_write_element_string(writer
,
467 config_element_path
, session
->path
);
473 ret
= mi_lttng_writer_write_element_bool(writer
,
474 config_element_enabled
, session
->enabled
);
480 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
481 config_element_snapshot_mode
, session
->snapshot_mode
);
486 /* Live timer interval in usec */
487 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
488 config_element_live_timer_interval
,
489 session
->live_timer_interval
);
495 /* Closing session element */
496 ret
= mi_lttng_writer_close_element(writer
);
504 int mi_lttng_domains_open(struct mi_writer
*writer
)
506 return mi_lttng_writer_open_element(writer
, config_element_domains
);
510 int mi_lttng_domain(struct mi_writer
*writer
,
511 struct lttng_domain
*domain
, int is_open
)
514 const char *str_domain
;
515 const char *str_buffer
;
519 /* Open domain element */
520 ret
= mi_lttng_writer_open_element(writer
, config_element_domain
);
526 str_domain
= mi_lttng_domaintype_string(domain
->type
);
527 ret
= mi_lttng_writer_write_element_string(writer
, config_element_type
,
534 str_buffer
= mi_lttng_buffertype_string(domain
->buf_type
);
535 ret
= mi_lttng_writer_write_element_string(writer
,
536 config_element_buffer_type
, str_buffer
);
541 /* TODO: attr... not sure how to use the union.... */
544 /* Closing domain element */
545 ret
= mi_lttng_writer_close_element(writer
);
554 int mi_lttng_channels_open(struct mi_writer
*writer
)
556 return mi_lttng_writer_open_element(writer
, config_element_channels
);
560 int mi_lttng_channel(struct mi_writer
*writer
,
561 struct lttng_channel
*channel
, int is_open
)
567 /* Opening channel element */
568 ret
= mi_lttng_writer_open_element(writer
, config_element_channel
);
574 ret
= mi_lttng_writer_write_element_string(writer
, config_element_name
,
581 ret
= mi_lttng_writer_write_element_bool(writer
,
582 config_element_enabled
, channel
->enabled
);
588 ret
= mi_lttng_channel_attr(writer
, &channel
->attr
);
594 /* Closing channel element */
595 ret
= mi_lttng_writer_close_element(writer
);
605 int mi_lttng_channel_attr(struct mi_writer
*writer
,
606 struct lttng_channel_attr
*attr
)
612 /* Opening Attributes */
613 ret
= mi_lttng_writer_open_element(writer
, config_element_attributes
);
619 ret
= mi_lttng_writer_write_element_string(writer
,
620 config_element_overwrite_mode
,
621 attr
->overwrite
? config_overwrite_mode_overwrite
:
622 config_overwrite_mode_discard
);
627 /* Sub buffer size in byte */
628 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
629 config_element_subbuf_size
, attr
->subbuf_size
);
634 /* Number of subbuffer (power of two) */
635 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
636 config_element_num_subbuf
,
642 /* Switch timer interval in usec */
643 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
644 config_element_switch_timer_interval
,
645 attr
->switch_timer_interval
);
650 /* Read timer interval in usec */
651 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
652 config_element_read_timer_interval
,
653 attr
->read_timer_interval
);
659 ret
= mi_lttng_writer_write_element_string(writer
,
660 config_element_output_type
,
661 attr
->output
== LTTNG_EVENT_SPLICE
?
662 config_output_type_splice
: config_output_type_mmap
);
667 /* Tracefile size in bytes */
668 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
669 config_element_tracefile_size
, attr
->tracefile_size
);
674 /* Count of tracefiles */
675 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
676 config_element_tracefile_count
,
677 attr
->tracefile_count
);
682 /* Live timer interval in usec*/
683 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
684 config_element_live_timer_interval
,
685 attr
->live_timer_interval
);
690 /* Closing attributes */
691 ret
= mi_lttng_writer_close_element(writer
);
701 int mi_lttng_event_common_attributes(struct mi_writer
*writer
,
702 struct lttng_event
*event
)
706 /* Open event element */
707 ret
= mi_lttng_writer_open_element(writer
, config_element_event
);
713 ret
= mi_lttng_writer_write_element_string(writer
,
714 config_element_name
, event
->name
);
720 ret
= mi_lttng_writer_write_element_string(writer
,
721 config_element_type
, mi_lttng_eventtype_string(event
->type
));
726 /* is event enabled */
727 ret
= mi_lttng_writer_write_element_bool(writer
,
728 config_element_enabled
, event
->enabled
);
733 /* event filter enabled? */
734 ret
= mi_lttng_writer_write_element_bool(writer
,
735 config_element_filter
, event
->filter
);
742 int mi_lttng_event_tracepoint_loglevel(struct mi_writer
*writer
,
743 struct lttng_event
*event
)
748 ret
= mi_lttng_writer_write_element_string(writer
,
749 config_element_loglevel
, mi_lttng_loglevel_string(event
->loglevel
));
754 ret
= mi_lttng_writer_write_element_string(writer
,
755 config_element_loglevel_type
,
756 mi_lttng_logleveltype_string(event
->loglevel_type
));
761 /* event exclusion filter */
762 ret
= mi_lttng_writer_write_element_bool(writer
,
763 config_element_exclusion
, event
->exclusion
);
773 int mi_lttng_event_tracepoint_no_loglevel(struct mi_writer
*writer
,
774 struct lttng_event
*event
)
776 /* event exclusion filter */
777 return mi_lttng_writer_write_element_bool(writer
,
778 config_element_exclusion
, event
->exclusion
);
782 int mi_lttng_event_function_probe(struct mi_writer
*writer
,
783 struct lttng_event
*event
)
787 if (event
->attr
.probe
.addr
!= 0) {
788 /* event probe address */
789 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
790 config_element_address
, event
->attr
.probe
.addr
);
795 /* event probe offset */
796 ret
= mi_lttng_writer_write_element_unsigned_int(writer
,
797 config_element_offset
, event
->attr
.probe
.offset
);
802 /* event probe symbol_name */
803 ret
= mi_lttng_writer_write_element_string(writer
,
804 config_element_symbol_name
, event
->attr
.probe
.symbol_name
);
814 int mi_lttng_event_function_entry(struct mi_writer
*writer
,
815 struct lttng_event
*event
)
817 /* event probe symbol_name */
818 return mi_lttng_writer_write_element_string(writer
,
819 config_element_symbol_name
, event
->attr
.ftrace
.symbol_name
);
823 int mi_lttng_events_open(struct mi_writer
*writer
)
825 return mi_lttng_writer_open_element(writer
, config_element_events
);
829 int mi_lttng_event(struct mi_writer
*writer
,
830 struct lttng_event
*event
, int is_open
)
834 ret
= mi_lttng_event_common_attributes(writer
, event
);
839 switch (event
->type
) {
840 case LTTNG_EVENT_ALL
:
841 /* We should never have "all" events in list. */
844 case LTTNG_EVENT_TRACEPOINT
:
846 if (event
->loglevel
!= -1) {
847 ret
= mi_lttng_event_tracepoint_loglevel(writer
, event
);
849 ret
= mi_lttng_event_tracepoint_no_loglevel(writer
, event
);
853 case LTTNG_EVENT_PROBE
:
854 ret
= mi_lttng_event_function_probe(writer
, event
);
856 case LTTNG_EVENT_FUNCTION_ENTRY
:
857 ret
= mi_lttng_event_function_entry(writer
, event
);
864 ret
= mi_lttng_writer_close_element(writer
);
872 int mi_lttng_pids_open(struct mi_writer
*writer
)
874 return mi_lttng_writer_open_element(writer
, mi_lttng_element_pids
);
878 int mi_lttng_pid(struct mi_writer
*writer
, pid_t pid
, const char *cmdline
,
883 /* Open element pid */
884 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_pid
);
889 /* Writing pid number */
890 ret
= mi_lttng_writer_write_element_signed_int(writer
,
891 mi_lttng_element_pid_id
, (int)pid
);
896 /* Writing name of the process */
897 ret
= mi_lttng_writer_write_element_string(writer
, config_element_name
,
905 ret
= mi_lttng_writer_close_element(writer
);
913 int mi_lttng_event_fields_open(struct mi_writer
*writer
)
915 return mi_lttng_writer_open_element(writer
, mi_lttng_element_event_fields
);
919 int mi_lttng_event_field(struct mi_writer
*writer
,
920 struct lttng_event_field
*field
)
924 if (!field
->field_name
[0]) {
925 /* To Review: not sure if legal david ?
926 * how should this be handle ?
933 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_event_field
);
938 if (!field
->field_name
[0]) {
943 ret
= mi_lttng_writer_write_element_string(writer
, config_element_name
,
950 ret
= mi_lttng_writer_write_element_string(writer
, config_element_type
,
951 mi_lttng_eventfieldtype_string(field
->type
));
957 ret
= mi_lttng_writer_write_element_signed_int(writer
,
958 mi_lttng_element_nowrite
, field
->nowrite
);
964 /* Close field element */
965 ret
= mi_lttng_writer_close_element(writer
);