4 * Babeltrace CTF Text Output Plugin Event Printing
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 * Copyright 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #include <babeltrace/babeltrace.h>
31 #include <babeltrace/bitfield-internal.h>
32 #include <babeltrace/common-internal.h>
33 #include <babeltrace/compat/time-internal.h>
34 #include <babeltrace/assert-internal.h>
39 #define NSEC_PER_SEC 1000000000LL
41 #define COLOR_NAME BT_COMMON_COLOR_BOLD
42 #define COLOR_FIELD_NAME BT_COMMON_COLOR_FG_CYAN
43 #define COLOR_RST BT_COMMON_COLOR_RESET
44 #define COLOR_STRING_VALUE BT_COMMON_COLOR_BOLD
45 #define COLOR_NUMBER_VALUE BT_COMMON_COLOR_BOLD
46 #define COLOR_ENUM_MAPPING_NAME BT_COMMON_COLOR_BOLD
47 #define COLOR_UNKNOWN BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_RED
48 #define COLOR_EVENT_NAME BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_MAGENTA
49 #define COLOR_TIMESTAMP BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_YELLOW
52 int64_t real_timestamp
; /* Relative to UNIX epoch. */
53 uint64_t clock_value
; /* In cycles. */
57 enum bt_component_status
print_field(struct pretty_component
*pretty
,
58 struct bt_field
*field
, bool print_names
,
59 GQuark
*filters_fields
, int filter_array_len
);
62 void print_name_equal(struct pretty_component
*pretty
, const char *name
)
64 if (pretty
->use_colors
) {
65 g_string_append_printf(pretty
->string
, "%s%s%s = ", COLOR_NAME
,
68 g_string_append_printf(pretty
->string
, "%s = ", name
);
73 void print_field_name_equal(struct pretty_component
*pretty
, const char *name
)
75 if (pretty
->use_colors
) {
76 g_string_append_printf(pretty
->string
, "%s%s%s = ",
77 COLOR_FIELD_NAME
, name
, COLOR_RST
);
79 g_string_append_printf(pretty
->string
, "%s = ", name
);
84 void print_timestamp_cycles(struct pretty_component
*pretty
,
85 struct bt_clock_class
*clock_class
,
86 struct bt_event
*event
)
89 struct bt_clock_value
*clock_value
;
92 clock_value
= bt_event_get_clock_value(event
, clock_class
);
94 g_string_append(pretty
->string
, "????????????????????");
98 ret
= bt_clock_value_get_value(clock_value
, &cycles
);
101 // TODO: log, this is unexpected
102 g_string_append(pretty
->string
, "Error");
106 g_string_append_printf(pretty
->string
, "%020" PRIu64
, cycles
);
108 if (pretty
->last_cycles_timestamp
!= -1ULL) {
109 pretty
->delta_cycles
= cycles
- pretty
->last_cycles_timestamp
;
111 pretty
->last_cycles_timestamp
= cycles
;
115 void print_timestamp_wall(struct pretty_component
*pretty
,
116 struct bt_clock_value
*clock_value
)
119 int64_t ts_nsec
= 0; /* add configurable offset */
120 int64_t ts_sec
= 0; /* add configurable offset */
121 uint64_t ts_sec_abs
, ts_nsec_abs
;
125 g_string_append(pretty
->string
, "??:??:??.?????????");
129 ret
= bt_clock_value_get_value_ns_from_epoch(clock_value
, &ts_nsec
);
131 // TODO: log, this is unexpected
132 g_string_append(pretty
->string
, "Error");
136 if (pretty
->last_real_timestamp
!= -1ULL) {
137 pretty
->delta_real_timestamp
= ts_nsec
- pretty
->last_real_timestamp
;
140 pretty
->last_real_timestamp
= ts_nsec
;
141 ts_sec
+= ts_nsec
/ NSEC_PER_SEC
;
142 ts_nsec
= ts_nsec
% NSEC_PER_SEC
;
144 if (ts_sec
>= 0 && ts_nsec
>= 0) {
147 ts_nsec_abs
= ts_nsec
;
148 } else if (ts_sec
> 0 && ts_nsec
< 0) {
150 ts_sec_abs
= ts_sec
- 1;
151 ts_nsec_abs
= NSEC_PER_SEC
+ ts_nsec
;
152 } else if (ts_sec
== 0 && ts_nsec
< 0) {
155 ts_nsec_abs
= -ts_nsec
;
156 } else if (ts_sec
< 0 && ts_nsec
> 0) {
158 ts_sec_abs
= -(ts_sec
+ 1);
159 ts_nsec_abs
= NSEC_PER_SEC
- ts_nsec
;
160 } else if (ts_sec
< 0 && ts_nsec
== 0) {
162 ts_sec_abs
= -ts_sec
;
163 ts_nsec_abs
= ts_nsec
;
164 } else { /* (ts_sec < 0 && ts_nsec < 0) */
166 ts_sec_abs
= -ts_sec
;
167 ts_nsec_abs
= -ts_nsec
;
170 if (!pretty
->options
.clock_seconds
) {
172 time_t time_s
= (time_t) ts_sec_abs
;
174 if (is_negative
&& !pretty
->negative_timestamp_warning_done
) {
176 fprintf(stderr
, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n");
177 pretty
->negative_timestamp_warning_done
= true;
181 if (!pretty
->options
.clock_gmt
) {
184 res
= bt_localtime_r(&time_s
, &tm
);
187 fprintf(stderr
, "[warning] Unable to get localtime.\n");
193 res
= bt_gmtime_r(&time_s
, &tm
);
196 fprintf(stderr
, "[warning] Unable to get gmtime.\n");
200 if (pretty
->options
.clock_date
) {
204 /* Print date and time */
205 res
= strftime(timestr
, sizeof(timestr
),
209 fprintf(stderr
, "[warning] Unable to print ascii time.\n");
213 g_string_append(pretty
->string
, timestr
);
216 /* Print time in HH:MM:SS.ns */
217 g_string_append_printf(pretty
->string
,
218 "%02d:%02d:%02d.%09" PRIu64
, tm
.tm_hour
, tm
.tm_min
,
219 tm
.tm_sec
, ts_nsec_abs
);
223 g_string_append_printf(pretty
->string
, "%s%" PRId64
".%09" PRIu64
,
224 is_negative
? "-" : "", ts_sec_abs
, ts_nsec_abs
);
230 enum bt_component_status
print_event_timestamp(struct pretty_component
*pretty
,
231 struct bt_event
*event
,
232 struct bt_clock_class_priority_map
*cc_prio_map
,
235 bool print_names
= pretty
->options
.print_header_field_names
;
236 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
237 struct bt_stream
*stream
= NULL
;
238 struct bt_stream_class
*stream_class
= NULL
;
239 struct bt_trace
*trace
= NULL
;
240 struct bt_clock_class
*clock_class
= NULL
;
242 stream
= bt_event_get_stream(event
);
244 ret
= BT_COMPONENT_STATUS_ERROR
;
248 stream_class
= bt_stream_get_class(stream
);
250 ret
= BT_COMPONENT_STATUS_ERROR
;
253 trace
= bt_stream_class_get_trace(stream_class
);
255 ret
= BT_COMPONENT_STATUS_ERROR
;
259 if (bt_clock_class_priority_map_get_clock_class_count(cc_prio_map
) == 0) {
260 /* No clock class: skip the timestamp without an error */
265 bt_clock_class_priority_map_get_highest_priority_clock_class(
268 ret
= BT_COMPONENT_STATUS_ERROR
;
273 print_name_equal(pretty
, "timestamp");
275 g_string_append(pretty
->string
, "[");
277 if (pretty
->use_colors
) {
278 g_string_append(pretty
->string
, COLOR_TIMESTAMP
);
280 if (pretty
->options
.print_timestamp_cycles
) {
281 print_timestamp_cycles(pretty
, clock_class
, event
);
283 struct bt_clock_value
*clock_value
=
284 bt_event_get_clock_value(event
, clock_class
);
286 print_timestamp_wall(pretty
, clock_value
);
289 if (pretty
->use_colors
) {
290 g_string_append(pretty
->string
, COLOR_RST
);
294 g_string_append(pretty
->string
, "] ");
296 if (pretty
->options
.print_delta_field
) {
298 g_string_append(pretty
->string
, ", ");
299 print_name_equal(pretty
, "delta");
301 g_string_append(pretty
->string
, "(");
303 if (pretty
->options
.print_timestamp_cycles
) {
304 if (pretty
->delta_cycles
== -1ULL) {
305 g_string_append(pretty
->string
,
306 "+??????????\?\?) "); /* Not a trigraph. */
308 g_string_append_printf(pretty
->string
,
309 "+%012" PRIu64
, pretty
->delta_cycles
);
312 if (pretty
->delta_real_timestamp
!= -1ULL) {
313 uint64_t delta_sec
, delta_nsec
, delta
;
315 delta
= pretty
->delta_real_timestamp
;
316 delta_sec
= delta
/ NSEC_PER_SEC
;
317 delta_nsec
= delta
% NSEC_PER_SEC
;
318 g_string_append_printf(pretty
->string
,
319 "+%" PRIu64
".%09" PRIu64
,
320 delta_sec
, delta_nsec
);
322 g_string_append(pretty
->string
, "+?.?????????");
326 g_string_append(pretty
->string
, ") ");
329 *start_line
= !print_names
;
334 bt_put(stream_class
);
340 enum bt_component_status
print_event_header(struct pretty_component
*pretty
,
341 struct bt_event
*event
,
342 struct bt_clock_class_priority_map
*cc_prio_map
)
344 bool print_names
= pretty
->options
.print_header_field_names
;
345 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
346 struct bt_event_class
*event_class
= NULL
;
347 struct bt_stream_class
*stream_class
= NULL
;
348 struct bt_trace
*trace_class
= NULL
;
351 event_class
= bt_event_get_class(event
);
353 ret
= BT_COMPONENT_STATUS_ERROR
;
356 stream_class
= bt_event_class_get_stream_class(event_class
);
358 ret
= BT_COMPONENT_STATUS_ERROR
;
361 trace_class
= bt_stream_class_get_trace(stream_class
);
363 ret
= BT_COMPONENT_STATUS_ERROR
;
366 ret
= print_event_timestamp(pretty
, event
, cc_prio_map
,
367 &pretty
->start_line
);
368 if (ret
!= BT_COMPONENT_STATUS_OK
) {
371 if (pretty
->options
.print_trace_field
) {
374 name
= bt_trace_get_name(trace_class
);
376 if (!pretty
->start_line
) {
377 g_string_append(pretty
->string
, ", ");
380 print_name_equal(pretty
, "trace");
383 g_string_append(pretty
->string
, name
);
386 g_string_append(pretty
->string
, " ");
390 if (pretty
->options
.print_trace_hostname_field
) {
391 struct bt_value
*hostname_str
;
393 hostname_str
= bt_trace_get_environment_field_value_by_name(trace_class
,
398 if (!pretty
->start_line
) {
399 g_string_append(pretty
->string
, ", ");
402 print_name_equal(pretty
, "trace:hostname");
404 if (bt_value_string_get(hostname_str
, &str
)
405 == BT_VALUE_STATUS_OK
) {
406 g_string_append(pretty
->string
, str
);
408 bt_put(hostname_str
);
412 if (pretty
->options
.print_trace_domain_field
) {
413 struct bt_value
*domain_str
;
415 domain_str
= bt_trace_get_environment_field_value_by_name(trace_class
,
420 if (!pretty
->start_line
) {
421 g_string_append(pretty
->string
, ", ");
424 print_name_equal(pretty
, "trace:domain");
425 } else if (dom_print
) {
426 g_string_append(pretty
->string
, ":");
428 if (bt_value_string_get(domain_str
, &str
)
429 == BT_VALUE_STATUS_OK
) {
430 g_string_append(pretty
->string
, str
);
436 if (pretty
->options
.print_trace_procname_field
) {
437 struct bt_value
*procname_str
;
439 procname_str
= bt_trace_get_environment_field_value_by_name(trace_class
,
444 if (!pretty
->start_line
) {
445 g_string_append(pretty
->string
, ", ");
448 print_name_equal(pretty
, "trace:procname");
449 } else if (dom_print
) {
450 g_string_append(pretty
->string
, ":");
452 if (bt_value_string_get(procname_str
, &str
)
453 == BT_VALUE_STATUS_OK
) {
454 g_string_append(pretty
->string
, str
);
456 bt_put(procname_str
);
460 if (pretty
->options
.print_trace_vpid_field
) {
461 struct bt_value
*vpid_value
;
463 vpid_value
= bt_trace_get_environment_field_value_by_name(trace_class
,
468 if (!pretty
->start_line
) {
469 g_string_append(pretty
->string
, ", ");
472 print_name_equal(pretty
, "trace:vpid");
473 } else if (dom_print
) {
474 g_string_append(pretty
->string
, ":");
476 if (bt_value_integer_get(vpid_value
, &value
)
477 == BT_VALUE_STATUS_OK
) {
478 g_string_append_printf(pretty
->string
, "(%" PRId64
")", value
);
484 if (pretty
->options
.print_loglevel_field
) {
485 static const char *log_level_names
[] = {
486 [ BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
] = "TRACE_EMERG",
487 [ BT_EVENT_CLASS_LOG_LEVEL_ALERT
] = "TRACE_ALERT",
488 [ BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
] = "TRACE_CRIT",
489 [ BT_EVENT_CLASS_LOG_LEVEL_ERROR
] = "TRACE_ERR",
490 [ BT_EVENT_CLASS_LOG_LEVEL_WARNING
] = "TRACE_WARNING",
491 [ BT_EVENT_CLASS_LOG_LEVEL_NOTICE
] = "TRACE_NOTICE",
492 [ BT_EVENT_CLASS_LOG_LEVEL_INFO
] = "TRACE_INFO",
493 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
] = "TRACE_DEBUG_SYSTEM",
494 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
] = "TRACE_DEBUG_PROGRAM",
495 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
] = "TRACE_DEBUG_PROCESS",
496 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
] = "TRACE_DEBUG_MODULE",
497 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
] = "TRACE_DEBUG_UNIT",
498 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
] = "TRACE_DEBUG_FUNCTION",
499 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
] = "TRACE_DEBUG_LINE",
500 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG
] = "TRACE_DEBUG",
502 enum bt_event_class_log_level log_level
;
503 const char *log_level_str
= NULL
;
505 log_level
= bt_event_class_get_log_level(event_class
);
506 BT_ASSERT(log_level
!= BT_EVENT_CLASS_LOG_LEVEL_UNKNOWN
);
507 if (log_level
!= BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
) {
508 log_level_str
= log_level_names
[log_level
];
512 if (!pretty
->start_line
) {
513 g_string_append(pretty
->string
, ", ");
516 print_name_equal(pretty
, "loglevel");
517 } else if (dom_print
) {
518 g_string_append(pretty
->string
, ":");
521 g_string_append(pretty
->string
, log_level_str
);
522 g_string_append_printf(
523 pretty
->string
, " (%d)", (int) log_level
);
527 if (pretty
->options
.print_emf_field
) {
530 uri_str
= bt_event_class_get_emf_uri(event_class
);
532 if (!pretty
->start_line
) {
533 g_string_append(pretty
->string
, ", ");
536 print_name_equal(pretty
, "model.emf.uri");
537 } else if (dom_print
) {
538 g_string_append(pretty
->string
, ":");
541 g_string_append(pretty
->string
, uri_str
);
545 if (dom_print
&& !print_names
) {
546 g_string_append(pretty
->string
, " ");
548 if (!pretty
->start_line
) {
549 g_string_append(pretty
->string
, ", ");
551 pretty
->start_line
= true;
553 print_name_equal(pretty
, "name");
555 if (pretty
->use_colors
) {
556 g_string_append(pretty
->string
, COLOR_EVENT_NAME
);
558 g_string_append(pretty
->string
, bt_event_class_get_name(event_class
));
559 if (pretty
->use_colors
) {
560 g_string_append(pretty
->string
, COLOR_RST
);
563 g_string_append(pretty
->string
, ": ");
565 g_string_append(pretty
->string
, ", ");
569 bt_put(stream_class
);
575 enum bt_component_status
print_integer(struct pretty_component
*pretty
,
576 struct bt_field
*field
)
578 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
579 struct bt_field_type
*field_type
= NULL
;
580 enum bt_integer_base base
;
581 enum bt_string_encoding encoding
;
587 bool rst_color
= false;
589 field_type
= bt_field_get_type(field
);
591 ret
= BT_COMPONENT_STATUS_ERROR
;
594 signedness
= bt_field_type_integer_is_signed(field_type
);
595 if (signedness
< 0) {
596 ret
= BT_COMPONENT_STATUS_ERROR
;
600 if (bt_field_integer_unsigned_get_value(field
, &v
.u
) < 0) {
601 ret
= BT_COMPONENT_STATUS_ERROR
;
605 if (bt_field_integer_signed_get_value(field
, &v
.s
) < 0) {
606 ret
= BT_COMPONENT_STATUS_ERROR
;
611 encoding
= bt_field_type_integer_get_encoding(field_type
);
613 case BT_STRING_ENCODING_UTF8
:
614 case BT_STRING_ENCODING_ASCII
:
615 g_string_append_c(pretty
->tmp_string
, (int) v
.u
);
617 case BT_STRING_ENCODING_NONE
:
618 case BT_STRING_ENCODING_UNKNOWN
:
621 ret
= BT_COMPONENT_STATUS_ERROR
;
625 if (pretty
->use_colors
) {
626 g_string_append(pretty
->string
, COLOR_NUMBER_VALUE
);
630 base
= bt_field_type_integer_get_base(field_type
);
632 case BT_INTEGER_BASE_BINARY
:
636 len
= bt_field_type_integer_get_size(field_type
);
638 ret
= BT_COMPONENT_STATUS_ERROR
;
641 g_string_append(pretty
->string
, "0b");
642 v
.u
= _bt_piecewise_lshift(v
.u
, 64 - len
);
643 for (bitnr
= 0; bitnr
< len
; bitnr
++) {
644 g_string_append_printf(pretty
->string
, "%u", (v
.u
& (1ULL << 63)) ? 1 : 0);
645 v
.u
= _bt_piecewise_lshift(v
.u
, 1);
649 case BT_INTEGER_BASE_OCTAL
:
654 len
= bt_field_type_integer_get_size(field_type
);
656 ret
= BT_COMPONENT_STATUS_ERROR
;
663 /* Round length to the nearest 3-bit */
664 rounded_len
= (((len
- 1) / 3) + 1) * 3;
665 v
.u
&= ((uint64_t) 1 << rounded_len
) - 1;
669 g_string_append_printf(pretty
->string
, "0%" PRIo64
, v
.u
);
672 case BT_INTEGER_BASE_DECIMAL
:
673 case BT_INTEGER_BASE_UNSPECIFIED
:
675 g_string_append_printf(pretty
->string
, "%" PRIu64
, v
.u
);
677 g_string_append_printf(pretty
->string
, "%" PRId64
, v
.s
);
680 case BT_INTEGER_BASE_HEXADECIMAL
:
684 len
= bt_field_type_integer_get_size(field_type
);
686 ret
= BT_COMPONENT_STATUS_ERROR
;
690 /* Round length to the nearest nibble */
691 uint8_t rounded_len
= ((len
+ 3) & ~0x3);
693 v
.u
&= ((uint64_t) 1 << rounded_len
) - 1;
696 g_string_append_printf(pretty
->string
, "0x%" PRIX64
, v
.u
);
700 ret
= BT_COMPONENT_STATUS_ERROR
;
705 g_string_append(pretty
->string
, COLOR_RST
);
712 void print_escape_string(struct pretty_component
*pretty
, const char *str
)
716 g_string_append_c(pretty
->string
, '"');
718 for (i
= 0; i
< strlen(str
); i
++) {
719 /* Escape sequences not recognized by iscntrl(). */
722 g_string_append(pretty
->string
, "\\\\");
725 g_string_append(pretty
->string
, "\\\'");
728 g_string_append(pretty
->string
, "\\\"");
731 g_string_append(pretty
->string
, "\\\?");
735 /* Standard characters. */
736 if (!iscntrl(str
[i
])) {
737 g_string_append_c(pretty
->string
, str
[i
]);
743 g_string_append(pretty
->string
, "\\0");
746 g_string_append(pretty
->string
, "\\a");
749 g_string_append(pretty
->string
, "\\b");
752 g_string_append(pretty
->string
, "\\e");
755 g_string_append(pretty
->string
, "\\f");
758 g_string_append(pretty
->string
, "\\n");
761 g_string_append(pretty
->string
, "\\r");
764 g_string_append(pretty
->string
, "\\t");
767 g_string_append(pretty
->string
, "\\v");
770 /* Unhandled control-sequence, print as hex. */
771 g_string_append_printf(pretty
->string
, "\\x%02x", str
[i
]);
776 g_string_append_c(pretty
->string
, '"');
780 enum bt_component_status
print_enum(struct pretty_component
*pretty
,
781 struct bt_field
*field
)
783 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
784 struct bt_field
*container_field
= NULL
;
785 struct bt_field_type
*enumeration_field_type
= NULL
;
786 struct bt_field_type
*container_field_type
= NULL
;
787 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
791 enumeration_field_type
= bt_field_get_type(field
);
792 if (!enumeration_field_type
) {
793 ret
= BT_COMPONENT_STATUS_ERROR
;
796 container_field
= bt_field_enumeration_get_container(field
);
797 if (!container_field
) {
798 ret
= BT_COMPONENT_STATUS_ERROR
;
801 container_field_type
= bt_field_get_type(container_field
);
802 if (!container_field_type
) {
803 ret
= BT_COMPONENT_STATUS_ERROR
;
806 is_signed
= bt_field_type_integer_is_signed(container_field_type
);
808 ret
= BT_COMPONENT_STATUS_ERROR
;
814 if (bt_field_integer_signed_get_value(container_field
,
816 ret
= BT_COMPONENT_STATUS_ERROR
;
819 iter
= bt_field_type_enumeration_signed_find_mappings_by_value(
820 enumeration_field_type
, value
);
824 if (bt_field_integer_unsigned_get_value(container_field
,
826 ret
= BT_COMPONENT_STATUS_ERROR
;
829 iter
= bt_field_type_enumeration_unsigned_find_mappings_by_value(
830 enumeration_field_type
, value
);
832 g_string_append(pretty
->string
, "( ");
833 ret
= bt_field_type_enumeration_mapping_iterator_next(iter
);
835 if (pretty
->use_colors
) {
836 g_string_append(pretty
->string
, COLOR_UNKNOWN
);
838 g_string_append(pretty
->string
, "<unknown>");
839 if (pretty
->use_colors
) {
840 g_string_append(pretty
->string
, COLOR_RST
);
845 const char *mapping_name
;
847 if (bt_field_type_enumeration_mapping_iterator_signed_get(
848 iter
, &mapping_name
, NULL
, NULL
) < 0) {
849 ret
= BT_COMPONENT_STATUS_ERROR
;
853 g_string_append(pretty
->string
, ", ");
854 if (pretty
->use_colors
) {
855 g_string_append(pretty
->string
, COLOR_ENUM_MAPPING_NAME
);
857 print_escape_string(pretty
, mapping_name
);
858 if (pretty
->use_colors
) {
859 g_string_append(pretty
->string
, COLOR_RST
);
861 if (bt_field_type_enumeration_mapping_iterator_next(iter
) < 0) {
866 g_string_append(pretty
->string
, " : container = ");
867 ret
= print_integer(pretty
, container_field
);
868 if (ret
!= BT_COMPONENT_STATUS_OK
) {
871 g_string_append(pretty
->string
, " )");
874 bt_put(container_field_type
);
875 bt_put(container_field
);
876 bt_put(enumeration_field_type
);
881 int filter_field_name(struct pretty_component
*pretty
, const char *field_name
,
882 GQuark
*filter_fields
, int filter_array_len
)
885 GQuark field_quark
= g_quark_try_string(field_name
);
887 if (!field_quark
|| pretty
->options
.verbose
) {
891 for (i
= 0; i
< filter_array_len
; i
++) {
892 if (field_quark
== filter_fields
[i
]) {
900 enum bt_component_status
print_struct_field(struct pretty_component
*pretty
,
901 struct bt_field
*_struct
,
902 struct bt_field_type
*struct_type
,
903 int i
, bool print_names
, int *nr_printed_fields
,
904 GQuark
*filter_fields
, int filter_array_len
)
906 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
907 const char *field_name
;
908 struct bt_field
*field
= NULL
;
909 struct bt_field_type
*field_type
= NULL
;;
911 field
= bt_field_structure_get_field_by_index(_struct
, i
);
913 ret
= BT_COMPONENT_STATUS_ERROR
;
916 if (bt_field_type_structure_get_field_by_index(struct_type
,
917 &field_name
, &field_type
, i
) < 0) {
918 ret
= BT_COMPONENT_STATUS_ERROR
;
922 if (filter_fields
&& !filter_field_name(pretty
, field_name
,
923 filter_fields
, filter_array_len
)) {
924 ret
= BT_COMPONENT_STATUS_OK
;
928 if (*nr_printed_fields
> 0) {
929 g_string_append(pretty
->string
, ", ");
931 g_string_append(pretty
->string
, " ");
934 print_field_name_equal(pretty
, field_name
);
936 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
937 *nr_printed_fields
+= 1;
945 enum bt_component_status
print_struct(struct pretty_component
*pretty
,
946 struct bt_field
*_struct
, bool print_names
,
947 GQuark
*filter_fields
, int filter_array_len
)
949 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
950 struct bt_field_type
*struct_type
= NULL
;
951 int nr_fields
, i
, nr_printed_fields
;
953 struct_type
= bt_field_get_type(_struct
);
955 ret
= BT_COMPONENT_STATUS_ERROR
;
958 nr_fields
= bt_field_type_structure_get_field_count(struct_type
);
960 ret
= BT_COMPONENT_STATUS_ERROR
;
963 g_string_append(pretty
->string
, "{");
965 nr_printed_fields
= 0;
966 for (i
= 0; i
< nr_fields
; i
++) {
967 ret
= print_struct_field(pretty
, _struct
, struct_type
, i
,
968 print_names
, &nr_printed_fields
, filter_fields
,
970 if (ret
!= BT_COMPONENT_STATUS_OK
) {
975 g_string_append(pretty
->string
, " }");
982 enum bt_component_status
print_array_field(struct pretty_component
*pretty
,
983 struct bt_field
*array
, uint64_t i
,
984 bool is_string
, bool print_names
)
986 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
987 struct bt_field
*field
= NULL
;
991 g_string_append(pretty
->string
, ", ");
993 g_string_append(pretty
->string
, " ");
996 g_string_append_printf(pretty
->string
, "[%" PRIu64
"] = ", i
);
999 field
= bt_field_array_get_field(array
, i
);
1001 ret
= BT_COMPONENT_STATUS_ERROR
;
1004 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
1011 enum bt_component_status
print_array(struct pretty_component
*pretty
,
1012 struct bt_field
*array
, bool print_names
)
1014 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1015 struct bt_field_type
*array_type
= NULL
, *field_type
= NULL
;
1016 enum bt_field_type_id type_id
;
1019 bool is_string
= false;
1021 array_type
= bt_field_get_type(array
);
1023 ret
= BT_COMPONENT_STATUS_ERROR
;
1026 field_type
= bt_field_type_array_get_element_field_type(array_type
);
1028 ret
= BT_COMPONENT_STATUS_ERROR
;
1031 len
= bt_field_type_array_get_length(array_type
);
1033 ret
= BT_COMPONENT_STATUS_ERROR
;
1036 type_id
= bt_field_type_get_type_id(field_type
);
1037 if (type_id
== BT_FIELD_TYPE_ID_INTEGER
) {
1038 enum bt_string_encoding encoding
;
1040 encoding
= bt_field_type_integer_get_encoding(field_type
);
1041 if (encoding
== BT_STRING_ENCODING_UTF8
1042 || encoding
== BT_STRING_ENCODING_ASCII
) {
1043 int integer_len
, integer_alignment
;
1045 integer_len
= bt_field_type_integer_get_size(field_type
);
1046 if (integer_len
< 0) {
1047 return BT_COMPONENT_STATUS_ERROR
;
1049 integer_alignment
= bt_field_type_get_alignment(field_type
);
1050 if (integer_alignment
< 0) {
1051 return BT_COMPONENT_STATUS_ERROR
;
1053 if (integer_len
== CHAR_BIT
1054 && integer_alignment
== CHAR_BIT
) {
1061 g_string_assign(pretty
->tmp_string
, "");
1063 g_string_append(pretty
->string
, "[");
1067 for (i
= 0; i
< len
; i
++) {
1068 ret
= print_array_field(pretty
, array
, i
, is_string
, print_names
);
1069 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1076 if (pretty
->use_colors
) {
1077 g_string_append(pretty
->string
, COLOR_STRING_VALUE
);
1079 print_escape_string(pretty
, pretty
->tmp_string
->str
);
1080 if (pretty
->use_colors
) {
1081 g_string_append(pretty
->string
, COLOR_RST
);
1084 g_string_append(pretty
->string
, " ]");
1093 enum bt_component_status
print_sequence_field(struct pretty_component
*pretty
,
1094 struct bt_field
*seq
, uint64_t i
,
1095 bool is_string
, bool print_names
)
1097 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1098 struct bt_field
*field
= NULL
;
1102 g_string_append(pretty
->string
, ", ");
1104 g_string_append(pretty
->string
, " ");
1107 g_string_append_printf(pretty
->string
, "[%" PRIu64
"] = ", i
);
1110 field
= bt_field_sequence_get_field(seq
, i
);
1112 ret
= BT_COMPONENT_STATUS_ERROR
;
1115 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
1122 enum bt_component_status
print_sequence(struct pretty_component
*pretty
,
1123 struct bt_field
*seq
, bool print_names
)
1125 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1126 struct bt_field_type
*seq_type
= NULL
, *field_type
= NULL
;
1127 struct bt_field
*length_field
= NULL
;
1128 enum bt_field_type_id type_id
;
1131 bool is_string
= false;
1133 seq_type
= bt_field_get_type(seq
);
1135 ret
= BT_COMPONENT_STATUS_ERROR
;
1138 length_field
= bt_field_sequence_get_length(seq
);
1139 if (!length_field
) {
1140 ret
= BT_COMPONENT_STATUS_ERROR
;
1143 if (bt_field_integer_unsigned_get_value(length_field
, &len
) < 0) {
1144 ret
= BT_COMPONENT_STATUS_ERROR
;
1147 field_type
= bt_field_type_sequence_get_element_field_type(seq_type
);
1149 ret
= BT_COMPONENT_STATUS_ERROR
;
1152 type_id
= bt_field_type_get_type_id(field_type
);
1153 if (type_id
== BT_FIELD_TYPE_ID_INTEGER
) {
1154 enum bt_string_encoding encoding
;
1156 encoding
= bt_field_type_integer_get_encoding(field_type
);
1157 if (encoding
== BT_STRING_ENCODING_UTF8
1158 || encoding
== BT_STRING_ENCODING_ASCII
) {
1159 int integer_len
, integer_alignment
;
1161 integer_len
= bt_field_type_integer_get_size(field_type
);
1162 if (integer_len
< 0) {
1163 ret
= BT_COMPONENT_STATUS_ERROR
;
1166 integer_alignment
= bt_field_type_get_alignment(field_type
);
1167 if (integer_alignment
< 0) {
1168 ret
= BT_COMPONENT_STATUS_ERROR
;
1171 if (integer_len
== CHAR_BIT
1172 && integer_alignment
== CHAR_BIT
) {
1179 g_string_assign(pretty
->tmp_string
, "");
1181 g_string_append(pretty
->string
, "[");
1185 for (i
= 0; i
< len
; i
++) {
1186 ret
= print_sequence_field(pretty
, seq
, i
,
1187 is_string
, print_names
);
1188 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1195 if (pretty
->use_colors
) {
1196 g_string_append(pretty
->string
, COLOR_STRING_VALUE
);
1198 print_escape_string(pretty
, pretty
->tmp_string
->str
);
1199 if (pretty
->use_colors
) {
1200 g_string_append(pretty
->string
, COLOR_RST
);
1203 g_string_append(pretty
->string
, " ]");
1206 bt_put(length_field
);
1213 enum bt_component_status
print_variant(struct pretty_component
*pretty
,
1214 struct bt_field
*variant
, bool print_names
)
1216 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1217 struct bt_field
*field
= NULL
;
1219 field
= bt_field_variant_get_current_field(variant
);
1221 ret
= BT_COMPONENT_STATUS_ERROR
;
1224 g_string_append(pretty
->string
, "{ ");
1228 struct bt_field
*tag_field
= NULL
;
1229 const char *tag_choice
;
1230 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1232 tag_field
= bt_field_variant_get_tag(variant
);
1234 ret
= BT_COMPONENT_STATUS_ERROR
;
1238 iter
= bt_field_enumeration_get_mappings(tag_field
);
1239 iter_ret
= bt_field_type_enumeration_mapping_iterator_next(
1243 ret
= BT_COMPONENT_STATUS_ERROR
;
1248 bt_field_type_enumeration_mapping_iterator_signed_get(
1249 iter
, &tag_choice
, NULL
, NULL
);
1253 ret
= BT_COMPONENT_STATUS_ERROR
;
1256 print_field_name_equal(pretty
, tag_choice
);
1260 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
1261 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1265 g_string_append(pretty
->string
, " }");
1272 enum bt_component_status
print_field(struct pretty_component
*pretty
,
1273 struct bt_field
*field
, bool print_names
,
1274 GQuark
*filter_fields
, int filter_array_len
)
1276 enum bt_field_type_id type_id
;
1278 type_id
= bt_field_get_type_id(field
);
1280 case BT_CTF_FIELD_TYPE_ID_INTEGER
:
1281 return print_integer(pretty
, field
);
1282 case BT_CTF_FIELD_TYPE_ID_FLOAT
:
1286 if (bt_field_floating_point_get_value(field
, &v
)) {
1287 return BT_COMPONENT_STATUS_ERROR
;
1289 if (pretty
->use_colors
) {
1290 g_string_append(pretty
->string
, COLOR_NUMBER_VALUE
);
1292 g_string_append_printf(pretty
->string
, "%g", v
);
1293 if (pretty
->use_colors
) {
1294 g_string_append(pretty
->string
, COLOR_RST
);
1296 return BT_COMPONENT_STATUS_OK
;
1298 case BT_CTF_FIELD_TYPE_ID_ENUM
:
1299 return print_enum(pretty
, field
);
1300 case BT_CTF_FIELD_TYPE_ID_STRING
:
1304 str
= bt_field_string_get_value(field
);
1306 return BT_COMPONENT_STATUS_ERROR
;
1309 if (pretty
->use_colors
) {
1310 g_string_append(pretty
->string
, COLOR_STRING_VALUE
);
1312 print_escape_string(pretty
, str
);
1313 if (pretty
->use_colors
) {
1314 g_string_append(pretty
->string
, COLOR_RST
);
1316 return BT_COMPONENT_STATUS_OK
;
1318 case BT_CTF_FIELD_TYPE_ID_STRUCT
:
1319 return print_struct(pretty
, field
, print_names
, filter_fields
,
1321 case BT_CTF_FIELD_TYPE_ID_VARIANT
:
1322 return print_variant(pretty
, field
, print_names
);
1323 case BT_CTF_FIELD_TYPE_ID_ARRAY
:
1324 return print_array(pretty
, field
, print_names
);
1325 case BT_CTF_FIELD_TYPE_ID_SEQUENCE
:
1326 return print_sequence(pretty
, field
, print_names
);
1328 // TODO: log instead
1329 fprintf(pretty
->err
, "[error] Unknown type id: %d\n", (int) type_id
);
1330 return BT_COMPONENT_STATUS_ERROR
;
1335 enum bt_component_status
print_stream_packet_context(struct pretty_component
*pretty
,
1336 struct bt_event
*event
)
1338 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1339 struct bt_packet
*packet
= NULL
;
1340 struct bt_field
*main_field
= NULL
;
1342 packet
= bt_event_get_packet(event
);
1344 ret
= BT_COMPONENT_STATUS_ERROR
;
1347 main_field
= bt_packet_get_context(packet
);
1351 if (!pretty
->start_line
) {
1352 g_string_append(pretty
->string
, ", ");
1354 pretty
->start_line
= false;
1355 if (pretty
->options
.print_scope_field_names
) {
1356 print_name_equal(pretty
, "stream.packet.context");
1358 ret
= print_field(pretty
, main_field
,
1359 pretty
->options
.print_context_field_names
,
1360 stream_packet_context_quarks
,
1361 STREAM_PACKET_CONTEXT_QUARKS_LEN
);
1369 enum bt_component_status
print_event_header_raw(struct pretty_component
*pretty
,
1370 struct bt_event
*event
)
1372 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1373 struct bt_field
*main_field
= NULL
;
1375 main_field
= bt_event_get_header(event
);
1379 if (!pretty
->start_line
) {
1380 g_string_append(pretty
->string
, ", ");
1382 pretty
->start_line
= false;
1383 if (pretty
->options
.print_scope_field_names
) {
1384 print_name_equal(pretty
, "stream.event.header");
1386 ret
= print_field(pretty
, main_field
,
1387 pretty
->options
.print_header_field_names
, NULL
, 0);
1394 enum bt_component_status
print_stream_event_context(struct pretty_component
*pretty
,
1395 struct bt_event
*event
)
1397 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1398 struct bt_field
*main_field
= NULL
;
1400 main_field
= bt_event_get_stream_event_context(event
);
1404 if (!pretty
->start_line
) {
1405 g_string_append(pretty
->string
, ", ");
1407 pretty
->start_line
= false;
1408 if (pretty
->options
.print_scope_field_names
) {
1409 print_name_equal(pretty
, "stream.event.context");
1411 ret
= print_field(pretty
, main_field
,
1412 pretty
->options
.print_context_field_names
, NULL
, 0);
1419 enum bt_component_status
print_event_context(struct pretty_component
*pretty
,
1420 struct bt_event
*event
)
1422 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1423 struct bt_field
*main_field
= NULL
;
1425 main_field
= bt_event_get_context(event
);
1429 if (!pretty
->start_line
) {
1430 g_string_append(pretty
->string
, ", ");
1432 pretty
->start_line
= false;
1433 if (pretty
->options
.print_scope_field_names
) {
1434 print_name_equal(pretty
, "event.context");
1436 ret
= print_field(pretty
, main_field
,
1437 pretty
->options
.print_context_field_names
, NULL
, 0);
1444 enum bt_component_status
print_event_payload(struct pretty_component
*pretty
,
1445 struct bt_event
*event
)
1447 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1448 struct bt_field
*main_field
= NULL
;
1450 main_field
= bt_event_get_payload(event
);
1454 if (!pretty
->start_line
) {
1455 g_string_append(pretty
->string
, ", ");
1457 pretty
->start_line
= false;
1458 if (pretty
->options
.print_scope_field_names
) {
1459 print_name_equal(pretty
, "event.fields");
1461 ret
= print_field(pretty
, main_field
,
1462 pretty
->options
.print_payload_field_names
, NULL
, 0);
1469 int flush_buf(struct pretty_component
*pretty
)
1473 if (pretty
->string
->len
== 0) {
1477 if (fwrite(pretty
->string
->str
, pretty
->string
->len
, 1, pretty
->out
) != 1) {
1486 enum bt_component_status
pretty_print_event(struct pretty_component
*pretty
,
1487 struct bt_notification
*event_notif
)
1489 enum bt_component_status ret
;
1490 struct bt_event
*event
=
1491 bt_notification_event_get_event(event_notif
);
1492 struct bt_clock_class_priority_map
*cc_prio_map
=
1493 bt_notification_event_get_clock_class_priority_map(event_notif
);
1496 BT_ASSERT(cc_prio_map
);
1497 pretty
->start_line
= true;
1498 g_string_assign(pretty
->string
, "");
1499 ret
= print_event_header(pretty
, event
, cc_prio_map
);
1500 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1504 ret
= print_stream_packet_context(pretty
, event
);
1505 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1509 if (pretty
->options
.verbose
) {
1510 ret
= print_event_header_raw(pretty
, event
);
1511 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1516 ret
= print_stream_event_context(pretty
, event
);
1517 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1521 ret
= print_event_context(pretty
, event
);
1522 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1526 ret
= print_event_payload(pretty
, event
);
1527 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1531 g_string_append_c(pretty
->string
, '\n');
1532 if (flush_buf(pretty
)) {
1533 ret
= BT_COMPONENT_STATUS_ERROR
;
1539 bt_put(cc_prio_map
);
1544 enum bt_component_status
pretty_print_discarded_elements(
1545 struct pretty_component
*pretty
,
1546 struct bt_notification
*notif
)
1548 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1549 struct bt_stream
*stream
= NULL
;
1550 struct bt_stream_class
*stream_class
= NULL
;
1551 struct bt_trace
*trace
= NULL
;
1552 const char *stream_name
;
1553 const char *trace_name
;
1554 const unsigned char *trace_uuid
;
1555 int64_t stream_class_id
;
1557 bool is_discarded_events
;
1559 struct bt_clock_value
*clock_value
= NULL
;
1562 switch (bt_notification_get_type(notif
)) {
1563 case BT_NOTIFICATION_TYPE_DISCARDED_EVENTS
:
1564 stream
= bt_notification_discarded_events_get_stream(notif
);
1565 count
= bt_notification_discarded_events_get_count(notif
);
1566 is_discarded_events
= true;
1568 case BT_NOTIFICATION_TYPE_DISCARDED_PACKETS
:
1569 stream
= bt_notification_discarded_packets_get_stream(notif
);
1570 count
= bt_notification_discarded_packets_get_count(notif
);
1571 is_discarded_events
= false;
1578 stream_name
= bt_stream_get_name(stream
);
1580 /* Stream class ID */
1581 stream_class
= bt_stream_get_class(stream
);
1582 BT_ASSERT(stream_class
);
1583 stream_class_id
= bt_stream_class_get_id(stream_class
);
1586 stream_id
= bt_stream_get_id(stream
);
1589 trace
= bt_stream_class_get_trace(stream_class
);
1591 trace_name
= bt_trace_get_name(trace
);
1593 trace_name
= "(unknown)";
1597 trace_uuid
= bt_trace_get_uuid(trace
);
1600 * Print to standard error stream to remain backward compatible
1601 * with Babeltrace 1.
1604 "%s%sWARNING%s%s: Tracer discarded %" PRId64
" %s%s between [",
1605 bt_common_color_fg_yellow(),
1606 bt_common_color_bold(),
1607 bt_common_color_reset(),
1608 bt_common_color_fg_yellow(),
1609 count
, is_discarded_events
? "event" : "packet",
1610 count
== 1 ? "" : "s");
1611 g_string_assign(pretty
->string
, "");
1612 clock_value
= is_discarded_events
?
1613 bt_notification_discarded_events_get_begin_clock_value(notif
) :
1614 bt_notification_discarded_packets_get_begin_clock_value(notif
);
1615 print_timestamp_wall(pretty
, clock_value
);
1616 BT_PUT(clock_value
);
1617 fprintf(stderr
, "%s] and [", pretty
->string
->str
);
1618 g_string_assign(pretty
->string
, "");
1619 clock_value
= is_discarded_events
?
1620 bt_notification_discarded_events_get_end_clock_value(notif
) :
1621 bt_notification_discarded_packets_get_end_clock_value(notif
);
1622 print_timestamp_wall(pretty
, clock_value
);
1623 BT_PUT(clock_value
);
1624 fprintf(stderr
, "%s] in trace \"%s\" ",
1625 pretty
->string
->str
, trace_name
);
1629 "(UUID: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x) ",
1647 fprintf(stderr
, "(no UUID) ");
1650 fprintf(stderr
, "within stream \"%s\" (stream class ID: %" PRId64
", ",
1651 stream_name
, stream_class_id
);
1653 if (stream_id
>= 0) {
1654 fprintf(stderr
, "stream ID: %" PRId64
, stream_id
);
1656 fprintf(stderr
, "no stream ID");
1659 fprintf(stderr
, ").%s\n", bt_common_color_reset());
1661 bt_put(stream_class
);
1663 bt_put(clock_value
);