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>
38 #define NSEC_PER_SEC 1000000000LL
40 #define COLOR_NAME BT_COMMON_COLOR_BOLD
41 #define COLOR_FIELD_NAME BT_COMMON_COLOR_FG_CYAN
42 #define COLOR_RST BT_COMMON_COLOR_RESET
43 #define COLOR_STRING_VALUE BT_COMMON_COLOR_BOLD
44 #define COLOR_NUMBER_VALUE BT_COMMON_COLOR_BOLD
45 #define COLOR_ENUM_MAPPING_NAME BT_COMMON_COLOR_BOLD
46 #define COLOR_UNKNOWN BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_RED
47 #define COLOR_EVENT_NAME BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_MAGENTA
48 #define COLOR_TIMESTAMP BT_COMMON_COLOR_BOLD BT_COMMON_COLOR_FG_YELLOW
51 int64_t real_timestamp
; /* Relative to UNIX epoch. */
52 uint64_t clock_value
; /* In cycles. */
56 enum bt_component_status
print_field(struct pretty_component
*pretty
,
57 struct bt_field
*field
, bool print_names
,
58 GQuark
*filters_fields
, int filter_array_len
);
61 void print_name_equal(struct pretty_component
*pretty
, const char *name
)
63 if (pretty
->use_colors
) {
64 g_string_append_printf(pretty
->string
, "%s%s%s = ", COLOR_NAME
,
67 g_string_append_printf(pretty
->string
, "%s = ", name
);
72 void print_field_name_equal(struct pretty_component
*pretty
, const char *name
)
74 if (pretty
->use_colors
) {
75 g_string_append_printf(pretty
->string
, "%s%s%s = ",
76 COLOR_FIELD_NAME
, name
, COLOR_RST
);
78 g_string_append_printf(pretty
->string
, "%s = ", name
);
83 void print_timestamp_cycles(struct pretty_component
*pretty
,
84 struct bt_clock_class
*clock_class
,
85 struct bt_event
*event
)
88 struct bt_clock_value
*clock_value
;
91 clock_value
= bt_event_get_clock_value(event
, clock_class
);
93 g_string_append(pretty
->string
, "????????????????????");
97 ret
= bt_clock_value_get_value(clock_value
, &cycles
);
100 // TODO: log, this is unexpected
101 g_string_append(pretty
->string
, "Error");
105 g_string_append_printf(pretty
->string
, "%020" PRIu64
, cycles
);
107 if (pretty
->last_cycles_timestamp
!= -1ULL) {
108 pretty
->delta_cycles
= cycles
- pretty
->last_cycles_timestamp
;
110 pretty
->last_cycles_timestamp
= cycles
;
114 void print_timestamp_wall(struct pretty_component
*pretty
,
115 struct bt_clock_value
*clock_value
)
118 int64_t ts_nsec
= 0; /* add configurable offset */
119 int64_t ts_sec
= 0; /* add configurable offset */
120 uint64_t ts_sec_abs
, ts_nsec_abs
;
124 g_string_append(pretty
->string
, "??:??:??.?????????");
128 ret
= bt_clock_value_get_value_ns_from_epoch(clock_value
, &ts_nsec
);
130 // TODO: log, this is unexpected
131 g_string_append(pretty
->string
, "Error");
135 if (pretty
->last_real_timestamp
!= -1ULL) {
136 pretty
->delta_real_timestamp
= ts_nsec
- pretty
->last_real_timestamp
;
139 pretty
->last_real_timestamp
= ts_nsec
;
140 ts_sec
+= ts_nsec
/ NSEC_PER_SEC
;
141 ts_nsec
= ts_nsec
% NSEC_PER_SEC
;
143 if (ts_sec
>= 0 && ts_nsec
>= 0) {
146 ts_nsec_abs
= ts_nsec
;
147 } else if (ts_sec
> 0 && ts_nsec
< 0) {
149 ts_sec_abs
= ts_sec
- 1;
150 ts_nsec_abs
= NSEC_PER_SEC
+ ts_nsec
;
151 } else if (ts_sec
== 0 && ts_nsec
< 0) {
154 ts_nsec_abs
= -ts_nsec
;
155 } else if (ts_sec
< 0 && ts_nsec
> 0) {
157 ts_sec_abs
= -(ts_sec
+ 1);
158 ts_nsec_abs
= NSEC_PER_SEC
- ts_nsec
;
159 } else if (ts_sec
< 0 && ts_nsec
== 0) {
161 ts_sec_abs
= -ts_sec
;
162 ts_nsec_abs
= ts_nsec
;
163 } else { /* (ts_sec < 0 && ts_nsec < 0) */
165 ts_sec_abs
= -ts_sec
;
166 ts_nsec_abs
= -ts_nsec
;
169 if (!pretty
->options
.clock_seconds
) {
171 time_t time_s
= (time_t) ts_sec_abs
;
173 if (is_negative
&& !pretty
->negative_timestamp_warning_done
) {
175 fprintf(stderr
, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n");
176 pretty
->negative_timestamp_warning_done
= true;
180 if (!pretty
->options
.clock_gmt
) {
183 res
= bt_localtime_r(&time_s
, &tm
);
186 fprintf(stderr
, "[warning] Unable to get localtime.\n");
192 res
= bt_gmtime_r(&time_s
, &tm
);
195 fprintf(stderr
, "[warning] Unable to get gmtime.\n");
199 if (pretty
->options
.clock_date
) {
203 /* Print date and time */
204 res
= strftime(timestr
, sizeof(timestr
),
208 fprintf(stderr
, "[warning] Unable to print ascii time.\n");
212 g_string_append(pretty
->string
, timestr
);
215 /* Print time in HH:MM:SS.ns */
216 g_string_append_printf(pretty
->string
,
217 "%02d:%02d:%02d.%09" PRIu64
, tm
.tm_hour
, tm
.tm_min
,
218 tm
.tm_sec
, ts_nsec_abs
);
222 g_string_append_printf(pretty
->string
, "%s%" PRId64
".%09" PRIu64
,
223 is_negative
? "-" : "", ts_sec_abs
, ts_nsec_abs
);
229 enum bt_component_status
print_event_timestamp(struct pretty_component
*pretty
,
230 struct bt_event
*event
,
231 struct bt_clock_class_priority_map
*cc_prio_map
,
234 bool print_names
= pretty
->options
.print_header_field_names
;
235 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
236 struct bt_stream
*stream
= NULL
;
237 struct bt_stream_class
*stream_class
= NULL
;
238 struct bt_trace
*trace
= NULL
;
239 struct bt_clock_class
*clock_class
= NULL
;
241 stream
= bt_event_get_stream(event
);
243 ret
= BT_COMPONENT_STATUS_ERROR
;
247 stream_class
= bt_stream_get_class(stream
);
249 ret
= BT_COMPONENT_STATUS_ERROR
;
252 trace
= bt_stream_class_get_trace(stream_class
);
254 ret
= BT_COMPONENT_STATUS_ERROR
;
258 if (bt_clock_class_priority_map_get_clock_class_count(cc_prio_map
) == 0) {
259 /* No clock class: skip the timestamp without an error */
264 bt_clock_class_priority_map_get_highest_priority_clock_class(
267 ret
= BT_COMPONENT_STATUS_ERROR
;
272 print_name_equal(pretty
, "timestamp");
274 g_string_append(pretty
->string
, "[");
276 if (pretty
->use_colors
) {
277 g_string_append(pretty
->string
, COLOR_TIMESTAMP
);
279 if (pretty
->options
.print_timestamp_cycles
) {
280 print_timestamp_cycles(pretty
, clock_class
, event
);
282 struct bt_clock_value
*clock_value
=
283 bt_event_get_clock_value(event
, clock_class
);
285 print_timestamp_wall(pretty
, clock_value
);
288 if (pretty
->use_colors
) {
289 g_string_append(pretty
->string
, COLOR_RST
);
293 g_string_append(pretty
->string
, "] ");
295 if (pretty
->options
.print_delta_field
) {
297 g_string_append(pretty
->string
, ", ");
298 print_name_equal(pretty
, "delta");
300 g_string_append(pretty
->string
, "(");
302 if (pretty
->options
.print_timestamp_cycles
) {
303 if (pretty
->delta_cycles
== -1ULL) {
304 g_string_append(pretty
->string
,
305 "+??????????\?\?) "); /* Not a trigraph. */
307 g_string_append_printf(pretty
->string
,
308 "+%012" PRIu64
, pretty
->delta_cycles
);
311 if (pretty
->delta_real_timestamp
!= -1ULL) {
312 uint64_t delta_sec
, delta_nsec
, delta
;
314 delta
= pretty
->delta_real_timestamp
;
315 delta_sec
= delta
/ NSEC_PER_SEC
;
316 delta_nsec
= delta
% NSEC_PER_SEC
;
317 g_string_append_printf(pretty
->string
,
318 "+%" PRIu64
".%09" PRIu64
,
319 delta_sec
, delta_nsec
);
321 g_string_append(pretty
->string
, "+?.?????????");
325 g_string_append(pretty
->string
, ") ");
328 *start_line
= !print_names
;
333 bt_put(stream_class
);
339 enum bt_component_status
print_event_header(struct pretty_component
*pretty
,
340 struct bt_event
*event
,
341 struct bt_clock_class_priority_map
*cc_prio_map
)
343 bool print_names
= pretty
->options
.print_header_field_names
;
344 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
345 struct bt_event_class
*event_class
= NULL
;
346 struct bt_stream_class
*stream_class
= NULL
;
347 struct bt_trace
*trace_class
= NULL
;
350 event_class
= bt_event_get_class(event
);
352 ret
= BT_COMPONENT_STATUS_ERROR
;
355 stream_class
= bt_event_class_get_stream_class(event_class
);
357 ret
= BT_COMPONENT_STATUS_ERROR
;
360 trace_class
= bt_stream_class_get_trace(stream_class
);
362 ret
= BT_COMPONENT_STATUS_ERROR
;
365 ret
= print_event_timestamp(pretty
, event
, cc_prio_map
,
366 &pretty
->start_line
);
367 if (ret
!= BT_COMPONENT_STATUS_OK
) {
370 if (pretty
->options
.print_trace_field
) {
373 name
= bt_trace_get_name(trace_class
);
375 if (!pretty
->start_line
) {
376 g_string_append(pretty
->string
, ", ");
379 print_name_equal(pretty
, "trace");
382 g_string_append(pretty
->string
, name
);
385 g_string_append(pretty
->string
, " ");
389 if (pretty
->options
.print_trace_hostname_field
) {
390 struct bt_value
*hostname_str
;
392 hostname_str
= bt_trace_get_environment_field_value_by_name(trace_class
,
397 if (!pretty
->start_line
) {
398 g_string_append(pretty
->string
, ", ");
401 print_name_equal(pretty
, "trace:hostname");
403 if (bt_value_string_get(hostname_str
, &str
)
404 == BT_VALUE_STATUS_OK
) {
405 g_string_append(pretty
->string
, str
);
407 bt_put(hostname_str
);
411 if (pretty
->options
.print_trace_domain_field
) {
412 struct bt_value
*domain_str
;
414 domain_str
= bt_trace_get_environment_field_value_by_name(trace_class
,
419 if (!pretty
->start_line
) {
420 g_string_append(pretty
->string
, ", ");
423 print_name_equal(pretty
, "trace:domain");
424 } else if (dom_print
) {
425 g_string_append(pretty
->string
, ":");
427 if (bt_value_string_get(domain_str
, &str
)
428 == BT_VALUE_STATUS_OK
) {
429 g_string_append(pretty
->string
, str
);
435 if (pretty
->options
.print_trace_procname_field
) {
436 struct bt_value
*procname_str
;
438 procname_str
= bt_trace_get_environment_field_value_by_name(trace_class
,
443 if (!pretty
->start_line
) {
444 g_string_append(pretty
->string
, ", ");
447 print_name_equal(pretty
, "trace:procname");
448 } else if (dom_print
) {
449 g_string_append(pretty
->string
, ":");
451 if (bt_value_string_get(procname_str
, &str
)
452 == BT_VALUE_STATUS_OK
) {
453 g_string_append(pretty
->string
, str
);
455 bt_put(procname_str
);
459 if (pretty
->options
.print_trace_vpid_field
) {
460 struct bt_value
*vpid_value
;
462 vpid_value
= bt_trace_get_environment_field_value_by_name(trace_class
,
467 if (!pretty
->start_line
) {
468 g_string_append(pretty
->string
, ", ");
471 print_name_equal(pretty
, "trace:vpid");
472 } else if (dom_print
) {
473 g_string_append(pretty
->string
, ":");
475 if (bt_value_integer_get(vpid_value
, &value
)
476 == BT_VALUE_STATUS_OK
) {
477 g_string_append_printf(pretty
->string
, "(%" PRId64
")", value
);
483 if (pretty
->options
.print_loglevel_field
) {
484 static const char *log_level_names
[] = {
485 [ BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY
] = "TRACE_EMERG",
486 [ BT_EVENT_CLASS_LOG_LEVEL_ALERT
] = "TRACE_ALERT",
487 [ BT_EVENT_CLASS_LOG_LEVEL_CRITICAL
] = "TRACE_CRIT",
488 [ BT_EVENT_CLASS_LOG_LEVEL_ERROR
] = "TRACE_ERR",
489 [ BT_EVENT_CLASS_LOG_LEVEL_WARNING
] = "TRACE_WARNING",
490 [ BT_EVENT_CLASS_LOG_LEVEL_NOTICE
] = "TRACE_NOTICE",
491 [ BT_EVENT_CLASS_LOG_LEVEL_INFO
] = "TRACE_INFO",
492 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
] = "TRACE_DEBUG_SYSTEM",
493 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
] = "TRACE_DEBUG_PROGRAM",
494 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
] = "TRACE_DEBUG_PROCESS",
495 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
] = "TRACE_DEBUG_MODULE",
496 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
] = "TRACE_DEBUG_UNIT",
497 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
] = "TRACE_DEBUG_FUNCTION",
498 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
] = "TRACE_DEBUG_LINE",
499 [ BT_EVENT_CLASS_LOG_LEVEL_DEBUG
] = "TRACE_DEBUG",
501 enum bt_event_class_log_level log_level
;
502 const char *log_level_str
= NULL
;
504 log_level
= bt_event_class_get_log_level(event_class
);
505 assert(log_level
!= BT_EVENT_CLASS_LOG_LEVEL_UNKNOWN
);
506 if (log_level
!= BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
) {
507 log_level_str
= log_level_names
[log_level
];
511 if (!pretty
->start_line
) {
512 g_string_append(pretty
->string
, ", ");
515 print_name_equal(pretty
, "loglevel");
516 } else if (dom_print
) {
517 g_string_append(pretty
->string
, ":");
520 g_string_append(pretty
->string
, log_level_str
);
521 g_string_append_printf(
522 pretty
->string
, " (%d)", (int) log_level
);
526 if (pretty
->options
.print_emf_field
) {
529 uri_str
= bt_event_class_get_emf_uri(event_class
);
531 if (!pretty
->start_line
) {
532 g_string_append(pretty
->string
, ", ");
535 print_name_equal(pretty
, "model.emf.uri");
536 } else if (dom_print
) {
537 g_string_append(pretty
->string
, ":");
540 g_string_append(pretty
->string
, uri_str
);
544 if (dom_print
&& !print_names
) {
545 g_string_append(pretty
->string
, " ");
547 if (!pretty
->start_line
) {
548 g_string_append(pretty
->string
, ", ");
550 pretty
->start_line
= true;
552 print_name_equal(pretty
, "name");
554 if (pretty
->use_colors
) {
555 g_string_append(pretty
->string
, COLOR_EVENT_NAME
);
557 g_string_append(pretty
->string
, bt_event_class_get_name(event_class
));
558 if (pretty
->use_colors
) {
559 g_string_append(pretty
->string
, COLOR_RST
);
562 g_string_append(pretty
->string
, ": ");
564 g_string_append(pretty
->string
, ", ");
568 bt_put(stream_class
);
574 enum bt_component_status
print_integer(struct pretty_component
*pretty
,
575 struct bt_field
*field
)
577 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
578 struct bt_field_type
*field_type
= NULL
;
579 enum bt_integer_base base
;
580 enum bt_string_encoding encoding
;
586 bool rst_color
= false;
588 field_type
= bt_field_get_type(field
);
590 ret
= BT_COMPONENT_STATUS_ERROR
;
593 signedness
= bt_ctf_field_type_integer_get_signed(field_type
);
594 if (signedness
< 0) {
595 ret
= BT_COMPONENT_STATUS_ERROR
;
599 if (bt_field_unsigned_integer_get_value(field
, &v
.u
) < 0) {
600 ret
= BT_COMPONENT_STATUS_ERROR
;
604 if (bt_field_signed_integer_get_value(field
, &v
.s
) < 0) {
605 ret
= BT_COMPONENT_STATUS_ERROR
;
610 encoding
= bt_field_type_integer_get_encoding(field_type
);
612 case BT_STRING_ENCODING_UTF8
:
613 case BT_STRING_ENCODING_ASCII
:
614 g_string_append_c(pretty
->tmp_string
, (int) v
.u
);
616 case BT_STRING_ENCODING_NONE
:
617 case BT_STRING_ENCODING_UNKNOWN
:
620 ret
= BT_COMPONENT_STATUS_ERROR
;
624 if (pretty
->use_colors
) {
625 g_string_append(pretty
->string
, COLOR_NUMBER_VALUE
);
629 base
= bt_field_type_integer_get_base(field_type
);
631 case BT_INTEGER_BASE_BINARY
:
635 len
= bt_field_type_integer_get_size(field_type
);
637 ret
= BT_COMPONENT_STATUS_ERROR
;
640 g_string_append(pretty
->string
, "0b");
641 v
.u
= _bt_piecewise_lshift(v
.u
, 64 - len
);
642 for (bitnr
= 0; bitnr
< len
; bitnr
++) {
643 g_string_append_printf(pretty
->string
, "%u", (v
.u
& (1ULL << 63)) ? 1 : 0);
644 v
.u
= _bt_piecewise_lshift(v
.u
, 1);
648 case BT_INTEGER_BASE_OCTAL
:
653 len
= bt_field_type_integer_get_size(field_type
);
655 ret
= BT_COMPONENT_STATUS_ERROR
;
662 /* Round length to the nearest 3-bit */
663 rounded_len
= (((len
- 1) / 3) + 1) * 3;
664 v
.u
&= ((uint64_t) 1 << rounded_len
) - 1;
668 g_string_append_printf(pretty
->string
, "0%" PRIo64
, v
.u
);
671 case BT_INTEGER_BASE_DECIMAL
:
672 case BT_INTEGER_BASE_UNSPECIFIED
:
674 g_string_append_printf(pretty
->string
, "%" PRIu64
, v
.u
);
676 g_string_append_printf(pretty
->string
, "%" PRId64
, v
.s
);
679 case BT_INTEGER_BASE_HEXADECIMAL
:
683 len
= bt_field_type_integer_get_size(field_type
);
685 ret
= BT_COMPONENT_STATUS_ERROR
;
689 /* Round length to the nearest nibble */
690 uint8_t rounded_len
= ((len
+ 3) & ~0x3);
692 v
.u
&= ((uint64_t) 1 << rounded_len
) - 1;
695 g_string_append_printf(pretty
->string
, "0x%" PRIX64
, v
.u
);
699 ret
= BT_COMPONENT_STATUS_ERROR
;
704 g_string_append(pretty
->string
, COLOR_RST
);
711 void print_escape_string(struct pretty_component
*pretty
, const char *str
)
715 g_string_append_c(pretty
->string
, '"');
717 for (i
= 0; i
< strlen(str
); i
++) {
718 /* Escape sequences not recognized by iscntrl(). */
721 g_string_append(pretty
->string
, "\\\\");
724 g_string_append(pretty
->string
, "\\\'");
727 g_string_append(pretty
->string
, "\\\"");
730 g_string_append(pretty
->string
, "\\\?");
734 /* Standard characters. */
735 if (!iscntrl(str
[i
])) {
736 g_string_append_c(pretty
->string
, str
[i
]);
742 g_string_append(pretty
->string
, "\\0");
745 g_string_append(pretty
->string
, "\\a");
748 g_string_append(pretty
->string
, "\\b");
751 g_string_append(pretty
->string
, "\\e");
754 g_string_append(pretty
->string
, "\\f");
757 g_string_append(pretty
->string
, "\\n");
760 g_string_append(pretty
->string
, "\\r");
763 g_string_append(pretty
->string
, "\\t");
766 g_string_append(pretty
->string
, "\\v");
769 /* Unhandled control-sequence, print as hex. */
770 g_string_append_printf(pretty
->string
, "\\x%02x", str
[i
]);
775 g_string_append_c(pretty
->string
, '"');
779 enum bt_component_status
print_enum(struct pretty_component
*pretty
,
780 struct bt_field
*field
)
782 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
783 struct bt_field
*container_field
= NULL
;
784 struct bt_field_type
*enumeration_field_type
= NULL
;
785 struct bt_field_type
*container_field_type
= NULL
;
786 struct bt_field_type_enumeration_mapping_iterator
*iter
= NULL
;
790 enumeration_field_type
= bt_field_get_type(field
);
791 if (!enumeration_field_type
) {
792 ret
= BT_COMPONENT_STATUS_ERROR
;
795 container_field
= bt_field_enumeration_get_container(field
);
796 if (!container_field
) {
797 ret
= BT_COMPONENT_STATUS_ERROR
;
800 container_field_type
= bt_field_get_type(container_field
);
801 if (!container_field_type
) {
802 ret
= BT_COMPONENT_STATUS_ERROR
;
805 is_signed
= bt_ctf_field_type_integer_get_signed(container_field_type
);
807 ret
= BT_COMPONENT_STATUS_ERROR
;
813 if (bt_field_signed_integer_get_value(container_field
,
815 ret
= BT_COMPONENT_STATUS_ERROR
;
818 iter
= bt_field_type_enumeration_find_mappings_by_signed_value(
819 enumeration_field_type
, value
);
823 if (bt_field_unsigned_integer_get_value(container_field
,
825 ret
= BT_COMPONENT_STATUS_ERROR
;
828 iter
= bt_field_type_enumeration_find_mappings_by_unsigned_value(
829 enumeration_field_type
, value
);
831 g_string_append(pretty
->string
, "( ");
832 ret
= bt_field_type_enumeration_mapping_iterator_next(iter
);
834 if (pretty
->use_colors
) {
835 g_string_append(pretty
->string
, COLOR_UNKNOWN
);
837 g_string_append(pretty
->string
, "<unknown>");
838 if (pretty
->use_colors
) {
839 g_string_append(pretty
->string
, COLOR_RST
);
844 const char *mapping_name
;
846 if (bt_field_type_enumeration_mapping_iterator_get_signed(
847 iter
, &mapping_name
, NULL
, NULL
) < 0) {
848 ret
= BT_COMPONENT_STATUS_ERROR
;
852 g_string_append(pretty
->string
, ", ");
853 if (pretty
->use_colors
) {
854 g_string_append(pretty
->string
, COLOR_ENUM_MAPPING_NAME
);
856 print_escape_string(pretty
, mapping_name
);
857 if (pretty
->use_colors
) {
858 g_string_append(pretty
->string
, COLOR_RST
);
860 if (bt_field_type_enumeration_mapping_iterator_next(iter
) < 0) {
865 g_string_append(pretty
->string
, " : container = ");
866 ret
= print_integer(pretty
, container_field
);
867 if (ret
!= BT_COMPONENT_STATUS_OK
) {
870 g_string_append(pretty
->string
, " )");
873 bt_put(container_field_type
);
874 bt_put(container_field
);
875 bt_put(enumeration_field_type
);
880 int filter_field_name(struct pretty_component
*pretty
, const char *field_name
,
881 GQuark
*filter_fields
, int filter_array_len
)
884 GQuark field_quark
= g_quark_try_string(field_name
);
886 if (!field_quark
|| pretty
->options
.verbose
) {
890 for (i
= 0; i
< filter_array_len
; i
++) {
891 if (field_quark
== filter_fields
[i
]) {
899 enum bt_component_status
print_struct_field(struct pretty_component
*pretty
,
900 struct bt_field
*_struct
,
901 struct bt_field_type
*struct_type
,
902 int i
, bool print_names
, int *nr_printed_fields
,
903 GQuark
*filter_fields
, int filter_array_len
)
905 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
906 const char *field_name
;
907 struct bt_field
*field
= NULL
;
908 struct bt_field_type
*field_type
= NULL
;;
910 field
= bt_field_structure_get_field_by_index(_struct
, i
);
912 ret
= BT_COMPONENT_STATUS_ERROR
;
915 if (bt_field_type_structure_get_field_by_index(struct_type
,
916 &field_name
, &field_type
, i
) < 0) {
917 ret
= BT_COMPONENT_STATUS_ERROR
;
921 if (filter_fields
&& !filter_field_name(pretty
, field_name
,
922 filter_fields
, filter_array_len
)) {
923 ret
= BT_COMPONENT_STATUS_OK
;
927 if (*nr_printed_fields
> 0) {
928 g_string_append(pretty
->string
, ", ");
930 g_string_append(pretty
->string
, " ");
933 print_field_name_equal(pretty
, field_name
);
935 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
936 *nr_printed_fields
+= 1;
944 enum bt_component_status
print_struct(struct pretty_component
*pretty
,
945 struct bt_field
*_struct
, bool print_names
,
946 GQuark
*filter_fields
, int filter_array_len
)
948 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
949 struct bt_field_type
*struct_type
= NULL
;
950 int nr_fields
, i
, nr_printed_fields
;
952 struct_type
= bt_field_get_type(_struct
);
954 ret
= BT_COMPONENT_STATUS_ERROR
;
957 nr_fields
= bt_field_type_structure_get_field_count(struct_type
);
959 ret
= BT_COMPONENT_STATUS_ERROR
;
962 g_string_append(pretty
->string
, "{");
964 nr_printed_fields
= 0;
965 for (i
= 0; i
< nr_fields
; i
++) {
966 ret
= print_struct_field(pretty
, _struct
, struct_type
, i
,
967 print_names
, &nr_printed_fields
, filter_fields
,
969 if (ret
!= BT_COMPONENT_STATUS_OK
) {
974 g_string_append(pretty
->string
, " }");
981 enum bt_component_status
print_array_field(struct pretty_component
*pretty
,
982 struct bt_field
*array
, uint64_t i
,
983 bool is_string
, bool print_names
)
985 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
986 struct bt_field
*field
= NULL
;
990 g_string_append(pretty
->string
, ", ");
992 g_string_append(pretty
->string
, " ");
995 g_string_append_printf(pretty
->string
, "[%" PRIu64
"] = ", i
);
998 field
= bt_field_array_get_field(array
, i
);
1000 ret
= BT_COMPONENT_STATUS_ERROR
;
1003 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
1010 enum bt_component_status
print_array(struct pretty_component
*pretty
,
1011 struct bt_field
*array
, bool print_names
)
1013 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1014 struct bt_field_type
*array_type
= NULL
, *field_type
= NULL
;
1015 enum bt_field_type_id type_id
;
1018 bool is_string
= false;
1020 array_type
= bt_field_get_type(array
);
1022 ret
= BT_COMPONENT_STATUS_ERROR
;
1025 field_type
= bt_field_type_array_get_element_type(array_type
);
1027 ret
= BT_COMPONENT_STATUS_ERROR
;
1030 len
= bt_field_type_array_get_length(array_type
);
1032 ret
= BT_COMPONENT_STATUS_ERROR
;
1035 type_id
= bt_field_type_get_type_id(field_type
);
1036 if (type_id
== BT_FIELD_TYPE_ID_INTEGER
) {
1037 enum bt_string_encoding encoding
;
1039 encoding
= bt_field_type_integer_get_encoding(field_type
);
1040 if (encoding
== BT_STRING_ENCODING_UTF8
1041 || encoding
== BT_STRING_ENCODING_ASCII
) {
1042 int integer_len
, integer_alignment
;
1044 integer_len
= bt_field_type_integer_get_size(field_type
);
1045 if (integer_len
< 0) {
1046 return BT_COMPONENT_STATUS_ERROR
;
1048 integer_alignment
= bt_field_type_get_alignment(field_type
);
1049 if (integer_alignment
< 0) {
1050 return BT_COMPONENT_STATUS_ERROR
;
1052 if (integer_len
== CHAR_BIT
1053 && integer_alignment
== CHAR_BIT
) {
1060 g_string_assign(pretty
->tmp_string
, "");
1062 g_string_append(pretty
->string
, "[");
1066 for (i
= 0; i
< len
; i
++) {
1067 ret
= print_array_field(pretty
, array
, i
, is_string
, print_names
);
1068 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1075 if (pretty
->use_colors
) {
1076 g_string_append(pretty
->string
, COLOR_STRING_VALUE
);
1078 print_escape_string(pretty
, pretty
->tmp_string
->str
);
1079 if (pretty
->use_colors
) {
1080 g_string_append(pretty
->string
, COLOR_RST
);
1083 g_string_append(pretty
->string
, " ]");
1092 enum bt_component_status
print_sequence_field(struct pretty_component
*pretty
,
1093 struct bt_field
*seq
, uint64_t i
,
1094 bool is_string
, bool print_names
)
1096 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1097 struct bt_field
*field
= NULL
;
1101 g_string_append(pretty
->string
, ", ");
1103 g_string_append(pretty
->string
, " ");
1106 g_string_append_printf(pretty
->string
, "[%" PRIu64
"] = ", i
);
1109 field
= bt_field_sequence_get_field(seq
, i
);
1111 ret
= BT_COMPONENT_STATUS_ERROR
;
1114 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
1121 enum bt_component_status
print_sequence(struct pretty_component
*pretty
,
1122 struct bt_field
*seq
, bool print_names
)
1124 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1125 struct bt_field_type
*seq_type
= NULL
, *field_type
= NULL
;
1126 struct bt_field
*length_field
= NULL
;
1127 enum bt_field_type_id type_id
;
1130 bool is_string
= false;
1132 seq_type
= bt_field_get_type(seq
);
1134 ret
= BT_COMPONENT_STATUS_ERROR
;
1137 length_field
= bt_field_sequence_get_length(seq
);
1138 if (!length_field
) {
1139 ret
= BT_COMPONENT_STATUS_ERROR
;
1142 if (bt_field_unsigned_integer_get_value(length_field
, &len
) < 0) {
1143 ret
= BT_COMPONENT_STATUS_ERROR
;
1146 field_type
= bt_field_type_sequence_get_element_type(seq_type
);
1148 ret
= BT_COMPONENT_STATUS_ERROR
;
1151 type_id
= bt_field_type_get_type_id(field_type
);
1152 if (type_id
== BT_FIELD_TYPE_ID_INTEGER
) {
1153 enum bt_string_encoding encoding
;
1155 encoding
= bt_field_type_integer_get_encoding(field_type
);
1156 if (encoding
== BT_STRING_ENCODING_UTF8
1157 || encoding
== BT_STRING_ENCODING_ASCII
) {
1158 int integer_len
, integer_alignment
;
1160 integer_len
= bt_field_type_integer_get_size(field_type
);
1161 if (integer_len
< 0) {
1162 ret
= BT_COMPONENT_STATUS_ERROR
;
1165 integer_alignment
= bt_field_type_get_alignment(field_type
);
1166 if (integer_alignment
< 0) {
1167 ret
= BT_COMPONENT_STATUS_ERROR
;
1170 if (integer_len
== CHAR_BIT
1171 && integer_alignment
== CHAR_BIT
) {
1178 g_string_assign(pretty
->tmp_string
, "");
1180 g_string_append(pretty
->string
, "[");
1184 for (i
= 0; i
< len
; i
++) {
1185 ret
= print_sequence_field(pretty
, seq
, i
,
1186 is_string
, print_names
);
1187 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1194 if (pretty
->use_colors
) {
1195 g_string_append(pretty
->string
, COLOR_STRING_VALUE
);
1197 print_escape_string(pretty
, pretty
->tmp_string
->str
);
1198 if (pretty
->use_colors
) {
1199 g_string_append(pretty
->string
, COLOR_RST
);
1202 g_string_append(pretty
->string
, " ]");
1205 bt_put(length_field
);
1212 enum bt_component_status
print_variant(struct pretty_component
*pretty
,
1213 struct bt_field
*variant
, bool print_names
)
1215 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1216 struct bt_field
*field
= NULL
;
1218 field
= bt_field_variant_get_current_field(variant
);
1220 ret
= BT_COMPONENT_STATUS_ERROR
;
1223 g_string_append(pretty
->string
, "{ ");
1227 struct bt_field
*tag_field
= NULL
;
1228 const char *tag_choice
;
1229 struct bt_field_type_enumeration_mapping_iterator
*iter
;
1231 tag_field
= bt_field_variant_get_tag(variant
);
1233 ret
= BT_COMPONENT_STATUS_ERROR
;
1237 iter
= bt_field_enumeration_get_mappings(tag_field
);
1238 iter_ret
= bt_field_type_enumeration_mapping_iterator_next(
1242 ret
= BT_COMPONENT_STATUS_ERROR
;
1247 bt_field_type_enumeration_mapping_iterator_get_signed(
1248 iter
, &tag_choice
, NULL
, NULL
);
1252 ret
= BT_COMPONENT_STATUS_ERROR
;
1255 print_field_name_equal(pretty
, tag_choice
);
1259 ret
= print_field(pretty
, field
, print_names
, NULL
, 0);
1260 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1264 g_string_append(pretty
->string
, " }");
1271 enum bt_component_status
print_field(struct pretty_component
*pretty
,
1272 struct bt_field
*field
, bool print_names
,
1273 GQuark
*filter_fields
, int filter_array_len
)
1275 enum bt_field_type_id type_id
;
1277 type_id
= bt_field_get_type_id(field
);
1279 case CTF_TYPE_INTEGER
:
1280 return print_integer(pretty
, field
);
1281 case CTF_TYPE_FLOAT
:
1285 if (bt_field_floating_point_get_value(field
, &v
)) {
1286 return BT_COMPONENT_STATUS_ERROR
;
1288 if (pretty
->use_colors
) {
1289 g_string_append(pretty
->string
, COLOR_NUMBER_VALUE
);
1291 g_string_append_printf(pretty
->string
, "%g", v
);
1292 if (pretty
->use_colors
) {
1293 g_string_append(pretty
->string
, COLOR_RST
);
1295 return BT_COMPONENT_STATUS_OK
;
1298 return print_enum(pretty
, field
);
1299 case CTF_TYPE_STRING
:
1303 str
= bt_field_string_get_value(field
);
1305 return BT_COMPONENT_STATUS_ERROR
;
1308 if (pretty
->use_colors
) {
1309 g_string_append(pretty
->string
, COLOR_STRING_VALUE
);
1311 print_escape_string(pretty
, str
);
1312 if (pretty
->use_colors
) {
1313 g_string_append(pretty
->string
, COLOR_RST
);
1315 return BT_COMPONENT_STATUS_OK
;
1317 case CTF_TYPE_STRUCT
:
1318 return print_struct(pretty
, field
, print_names
, filter_fields
,
1320 case CTF_TYPE_VARIANT
:
1321 return print_variant(pretty
, field
, print_names
);
1322 case CTF_TYPE_ARRAY
:
1323 return print_array(pretty
, field
, print_names
);
1324 case CTF_TYPE_SEQUENCE
:
1325 return print_sequence(pretty
, field
, print_names
);
1327 // TODO: log instead
1328 fprintf(pretty
->err
, "[error] Unknown type id: %d\n", (int) type_id
);
1329 return BT_COMPONENT_STATUS_ERROR
;
1334 enum bt_component_status
print_stream_packet_context(struct pretty_component
*pretty
,
1335 struct bt_event
*event
)
1337 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1338 struct bt_packet
*packet
= NULL
;
1339 struct bt_field
*main_field
= NULL
;
1341 packet
= bt_event_get_packet(event
);
1343 ret
= BT_COMPONENT_STATUS_ERROR
;
1346 main_field
= bt_packet_get_context(packet
);
1350 if (!pretty
->start_line
) {
1351 g_string_append(pretty
->string
, ", ");
1353 pretty
->start_line
= false;
1354 if (pretty
->options
.print_scope_field_names
) {
1355 print_name_equal(pretty
, "stream.packet.context");
1357 ret
= print_field(pretty
, main_field
,
1358 pretty
->options
.print_context_field_names
,
1359 stream_packet_context_quarks
,
1360 STREAM_PACKET_CONTEXT_QUARKS_LEN
);
1368 enum bt_component_status
print_event_header_raw(struct pretty_component
*pretty
,
1369 struct bt_event
*event
)
1371 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1372 struct bt_field
*main_field
= NULL
;
1374 main_field
= bt_event_get_header(event
);
1378 if (!pretty
->start_line
) {
1379 g_string_append(pretty
->string
, ", ");
1381 pretty
->start_line
= false;
1382 if (pretty
->options
.print_scope_field_names
) {
1383 print_name_equal(pretty
, "stream.event.header");
1385 ret
= print_field(pretty
, main_field
,
1386 pretty
->options
.print_header_field_names
, NULL
, 0);
1393 enum bt_component_status
print_stream_event_context(struct pretty_component
*pretty
,
1394 struct bt_event
*event
)
1396 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1397 struct bt_field
*main_field
= NULL
;
1399 main_field
= bt_event_get_stream_event_context(event
);
1403 if (!pretty
->start_line
) {
1404 g_string_append(pretty
->string
, ", ");
1406 pretty
->start_line
= false;
1407 if (pretty
->options
.print_scope_field_names
) {
1408 print_name_equal(pretty
, "stream.event.context");
1410 ret
= print_field(pretty
, main_field
,
1411 pretty
->options
.print_context_field_names
, NULL
, 0);
1418 enum bt_component_status
print_event_context(struct pretty_component
*pretty
,
1419 struct bt_event
*event
)
1421 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1422 struct bt_field
*main_field
= NULL
;
1424 main_field
= bt_event_get_event_context(event
);
1428 if (!pretty
->start_line
) {
1429 g_string_append(pretty
->string
, ", ");
1431 pretty
->start_line
= false;
1432 if (pretty
->options
.print_scope_field_names
) {
1433 print_name_equal(pretty
, "event.context");
1435 ret
= print_field(pretty
, main_field
,
1436 pretty
->options
.print_context_field_names
, NULL
, 0);
1443 enum bt_component_status
print_event_payload(struct pretty_component
*pretty
,
1444 struct bt_event
*event
)
1446 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1447 struct bt_field
*main_field
= NULL
;
1449 main_field
= bt_event_get_event_payload(event
);
1453 if (!pretty
->start_line
) {
1454 g_string_append(pretty
->string
, ", ");
1456 pretty
->start_line
= false;
1457 if (pretty
->options
.print_scope_field_names
) {
1458 print_name_equal(pretty
, "event.fields");
1460 ret
= print_field(pretty
, main_field
,
1461 pretty
->options
.print_payload_field_names
, NULL
, 0);
1468 int flush_buf(struct pretty_component
*pretty
)
1472 if (pretty
->string
->len
== 0) {
1476 if (fwrite(pretty
->string
->str
, pretty
->string
->len
, 1, pretty
->out
) != 1) {
1485 enum bt_component_status
pretty_print_event(struct pretty_component
*pretty
,
1486 struct bt_notification
*event_notif
)
1488 enum bt_component_status ret
;
1489 struct bt_event
*event
=
1490 bt_notification_event_get_event(event_notif
);
1491 struct bt_clock_class_priority_map
*cc_prio_map
=
1492 bt_notification_event_get_clock_class_priority_map(event_notif
);
1495 assert(cc_prio_map
);
1496 pretty
->start_line
= true;
1497 g_string_assign(pretty
->string
, "");
1498 ret
= print_event_header(pretty
, event
, cc_prio_map
);
1499 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1503 ret
= print_stream_packet_context(pretty
, event
);
1504 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1508 if (pretty
->options
.verbose
) {
1509 ret
= print_event_header_raw(pretty
, event
);
1510 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1515 ret
= print_stream_event_context(pretty
, event
);
1516 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1520 ret
= print_event_context(pretty
, event
);
1521 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1525 ret
= print_event_payload(pretty
, event
);
1526 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1530 g_string_append_c(pretty
->string
, '\n');
1531 if (flush_buf(pretty
)) {
1532 ret
= BT_COMPONENT_STATUS_ERROR
;
1538 bt_put(cc_prio_map
);
1543 enum bt_component_status
pretty_print_discarded_elements(
1544 struct pretty_component
*pretty
,
1545 struct bt_notification
*notif
)
1547 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
1548 struct bt_stream
*stream
= NULL
;
1549 struct bt_stream_class
*stream_class
= NULL
;
1550 struct bt_trace
*trace
= NULL
;
1551 const char *stream_name
;
1552 const char *trace_name
;
1553 const unsigned char *trace_uuid
;
1554 int64_t stream_class_id
;
1556 bool is_discarded_events
;
1558 struct bt_clock_value
*clock_value
= NULL
;
1561 switch (bt_notification_get_type(notif
)) {
1562 case BT_NOTIFICATION_TYPE_DISCARDED_EVENTS
:
1563 stream
= bt_notification_discarded_events_get_stream(notif
);
1564 count
= bt_notification_discarded_events_get_count(notif
);
1565 is_discarded_events
= true;
1567 case BT_NOTIFICATION_TYPE_DISCARDED_PACKETS
:
1568 stream
= bt_notification_discarded_packets_get_stream(notif
);
1569 count
= bt_notification_discarded_packets_get_count(notif
);
1570 is_discarded_events
= false;
1577 stream_name
= bt_stream_get_name(stream
);
1579 /* Stream class ID */
1580 stream_class
= bt_stream_get_class(stream
);
1581 assert(stream_class
);
1582 stream_class_id
= bt_stream_class_get_id(stream_class
);
1585 stream_id
= bt_stream_get_id(stream
);
1588 trace
= bt_stream_class_get_trace(stream_class
);
1590 trace_name
= bt_trace_get_name(trace
);
1592 trace_name
= "(unknown)";
1596 trace_uuid
= bt_trace_get_uuid(trace
);
1599 * Print to standard error stream to remain backward compatible
1600 * with Babeltrace 1.
1603 "%s%sWARNING%s%s: Tracer discarded %" PRId64
" %s%s between [",
1604 bt_common_color_fg_yellow(),
1605 bt_common_color_bold(),
1606 bt_common_color_reset(),
1607 bt_common_color_fg_yellow(),
1608 count
, is_discarded_events
? "event" : "packet",
1609 count
== 1 ? "" : "s");
1610 g_string_assign(pretty
->string
, "");
1611 clock_value
= is_discarded_events
?
1612 bt_notification_discarded_events_get_begin_clock_value(notif
) :
1613 bt_notification_discarded_packets_get_begin_clock_value(notif
);
1614 print_timestamp_wall(pretty
, clock_value
);
1615 BT_PUT(clock_value
);
1616 fprintf(stderr
, "%s] and [", pretty
->string
->str
);
1617 g_string_assign(pretty
->string
, "");
1618 clock_value
= is_discarded_events
?
1619 bt_notification_discarded_events_get_end_clock_value(notif
) :
1620 bt_notification_discarded_packets_get_end_clock_value(notif
);
1621 print_timestamp_wall(pretty
, clock_value
);
1622 BT_PUT(clock_value
);
1623 fprintf(stderr
, "%s] in trace \"%s\" ",
1624 pretty
->string
->str
, trace_name
);
1628 "(UUID: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x) ",
1646 fprintf(stderr
, "(no UUID) ");
1649 fprintf(stderr
, "within stream \"%s\" (stream class ID: %" PRId64
", ",
1650 stream_name
, stream_class_id
);
1652 if (stream_id
>= 0) {
1653 fprintf(stderr
, "stream ID: %" PRId64
, stream_id
);
1655 fprintf(stderr
, "no stream ID");
1658 fprintf(stderr
, ").%s\n", bt_common_color_reset());
1660 bt_put(stream_class
);
1662 bt_put(clock_value
);