1 /* The text dump facility needs to print headers before the trace set and
2 before each trace, to print each event, and to print statistics
6 #include <lttv/attribute.h>
9 void init(int argc
, char **argv
)
12 lttv_hooks
*before
, *after
;
14 a
= lttv_global_attributes();
15 before
= (lttv_hooks
*)lttv_attributes_get_pointer_pathname(a
,
16 "hooks/trace_set/before");
17 after
= (lttv_hooks
*)lttv_attributes_get_pointer_pathname(a
,
18 "hooks/trace_set/after");
19 lttv_hooks_add(before
, textDump_trace_set_before
, NULL
);
20 lttv_hooks_add(after
, textDump_trace_set_after
, NULL
);
27 lttv_hooks
*before
, *after
;
29 a
= lttv_global_attributes();
30 before
= (lttv_hooks
*)lttv_attributes_get_pointer_pathname(a
,
31 "hooks/trace_set/before");
32 after
= (lttv_hooks
*)lttv_attributes_get_pointer_pathname(a
,
33 "hooks/trace_set/after");
34 lttv_hooks_remove(before
, textDump_trace_set_before
, NULL
);
35 lttv_hooks_remove(after
, textDump_trace_set_after
, NULL
);
38 /* Insert the hooks before and after each trace and tracefile, and for each
39 event. Print a global header. */
41 typedef struct _trace_context
{
44 bool mandatory_fields
;
48 static bool textDump_trace_set_before(void *hook_data
, void *call_data
)
56 a
= lttv_global_attributes();
57 s
= (lttv_trace_set
*)call_data
59 /* Get the file pointer */
61 fp
= (FILE *)lttv_attributes_get_pointer_pathname(a
, "textDump/file");
63 /* For each trace prepare the contexts and insert the hooks */
65 nb
= lttv_trace_set_number(s
);
66 for(i
= 0 ; i
< nb
; i
++) {
67 c
= g_new(trace_context
);
68 a
= lttv_trace_set_trace_attributes(s
, i
);
70 if(lttv_attributes_get_pointer_pathname(a
, "textDump/context") != NULL
) {
71 g_error("Recursive call to TextDump");
75 c
->mandatory_fields
= TRUE
;
76 c
->s
= g_string_new();
79 lttv_attributes_set_pointer_pathname(a
, "textDump/context", c
);
81 h
= lttv_attributes_get_hooks(a
, "hooks/before");
82 lttv_hooks_add(h
, textDump_trace_before
, c
);
83 h
= lttv_attributes_get_hooks(a
, "hooks/after");
84 lttv_hooks_add(h
, textDump_trace_after
, c
);
85 h
= lttv_attributes_get_hooks(a
, "hooks/tacefile/before");
86 lttv_hooks_add(h
, textDump_tracefile_before
, c
);
87 h
= lttv_attributes_get_hooks(a
, "hooks/tracefile/after");
88 lttv_hooks_add(h
, textDump_tracefile_after
, c
);
89 h
= lttv_attributes_get_hooks(a
, "hooks/event/selected");
90 lttv_hooks_add(h
, textDump_event
, c
);
93 /* Print the trace set header */
94 fprintf(fp
,"Trace set contains %d traces\n\n", nb
);
100 /* Remove the hooks before and after each trace and tracefile, and for each
101 event. Print trace set level statistics. */
103 static bool textDump_trace_set_after(void *hook_data
, void *call_data
)
108 lttv_attributes
*ga
, *a
;
111 ga
= lttv_global_attributes();
112 s
= (lttv_trace_set
*)lttv_attributes_get_pointer_pathname(ga
,
115 /* Get the file pointer */
117 fp
= (FILE *)lttv_attributes_get_pointer_pathname(ga
, "textDump/file");
119 /* For each trace remove the hooks */
121 nb
= lttv_trace_set_number(s
);
122 for(i
= 0 ; i
< nb
; i
++) {
123 a
= lttv_trace_set_trace_attributes(s
, i
);
124 c
= (trace_context
*)lttv_attributes_get_pointer_pathname(a
,
126 lttv_attributes_set_pointer_pathname(a
, "textDump/context", NULL
);
129 h
= lttv_attributes_get_hooks(a
, "hooks/before");
130 lttv_hooks_remove(h
, textDump_trace_before
, c
);
131 h
= lttv_attributes_get_hooks(a
, "hooks/after");
132 lttv_hooks_remove(h
, textDump_trace_after
, c
);
133 h
= lttv_attributes_get_hooks(a
, "hooks/tacefile/before");
134 lttv_hooks_remove(h
, textDump_tracefile_before
, c
);
135 h
= lttv_attributes_get_hooks(a
, "hooks/tracefile/after");
136 lttv_hooks_remove(h
, textDump_tracefile_after
, c
);
137 h
= lttv_attributes_get_hooks(a
, "hooks/event/selected");
138 lttv_hooks_remove(h
, textDump_event
, c
);
142 /* Print the trace set statistics */
144 fprintf(fp
,"Trace set contains %d traces\n\n", nb
);
152 /* Print a trace level header */
154 static bool textDump_trace_before(void *hook_data
, void *call_data
)
159 c
= (trace_context
*)hook_data
;
160 t
= (ltt_trace
*)call_data
;
161 fprintf(c
->fp
,"Start trace\n");
166 /* Print trace level statistics */
168 static bool textDump_trace_after(void *hook_data
, void *call_data
)
173 c
= (trace_context
*)hook_data
;
174 t
= (ltt_trace
*)call_data
;
175 fprintf(c
->fp
,"End trace\n");
176 print_stats(c
->fp
,c
->a
);
181 static bool textDump_tracefile_before(void *hook_data
, void *call_data
)
186 c
= (trace_context
*)hook_data
;
187 tf
= (ltt_tracefile
*)call_data
;
188 fprintf(c
->fp
,"Start tracefile\n");
193 static bool textDump_tracefile_after(void *hook_data
, void *call_data
)
198 c
= (trace_context
*)hook_data
;
199 tf
= (ltt_tracefile
*)call_data
;
200 fprintf(c
->fp
,"End tracefile\n");
205 /* Print the event content */
207 static bool textDump_event(void *hook_data
, void *call_data
)
212 e
= (ltt_event
*)call_data
;
213 c
= (event_context
*)hook_data
;
214 lttv_event_to_string(e
,c
->s
,c
->mandatory_fields
);
220 static void print_stats(FILE *fp
, lttv_attributes
*a
)
222 int i
, j
, k
, nb
, nbc
;
224 lttv_attributes
*sa
, *ra
;
225 lttv_attribute
*reports
, *content
;
226 lttv_key
*key
, *previous_key
, null_key
;
228 null_key
= lttv_key_new_pathname("");
229 sa
= (lttv_attributes
*)lttv_attributes_get_pointer_pathname(a
,"stats");
230 reports
= lttv_attributes_array_get(sa
);
231 nb
= lttv_attributes_number(sa
);
233 for(i
= 0 ; i
< nb
; i
++) {
234 ra
= (lttv_attributes
*)reports
[i
].v
.p
;
235 key
= reports
[i
].key
;
236 g_assert(reports
[i
].t
== LTTV_POINTER
);
238 /* CHECK maybe have custom handlers registered for some specific reports */
242 content
= lttv_attributes_array_get(ra
);
243 nbc
= lttv_attributes_number(ra
);
244 lttv_attribute_array_sort_lexicographic(content
, nbc
, NULL
, 0);
245 previous_key
= nullKey
;
246 for(j
= 0 ; j
< nbc
; j
++) {
247 key
= content
[j
].key
;
248 for(k
= 0 ; lttv_key_index(previous_key
,k
) == lttv_index(key
,k
) ; k
++)
249 for(; k
< lttv_key_number(key
) ; k
++) {
250 for(l
= 0 ; l
< k
; l
++) fprintf(fp
," ");
251 fprintf(fp
, "%s", lttv_string_id_to_string(lttv_index(key
,k
)));
252 if(k
== lttv_key_number(key
)) {
253 switch(content
[j
].t
) {
255 fprintf(fp
," %d\n", content
[j
].v
.i
);
258 fprintf(fp
," %d.%09d\n", content
[j
].v
.t
.tv_sec
,
259 content
[j
].v
.t
.tv_nsec
);
262 fprintf(fp
," %g\n", content
[j
].v
.d
);
265 fprintf(fp
," pointer\n");
269 else fprintf(fp
,"\n");
272 lttv_attribute_array_destroy(content
);
274 lttv_attribute_array_destroy(reports
);
275 lttv_key_destroy(null_key
);
279 void lttv_event_to_string(ltt_event
*e
, lttv_string
*s
, bool mandatory_fields
)
281 ltt_facility
*facility
;
282 ltt_eventtype
*eventtype
;
287 g_string_set_size(s
,0);
289 facility
= lttv_event_facility(e
);
290 eventtype
= ltt_event_eventtype(e
);
291 field
= ltt_event_field(e
);
293 if(mandatory_fields
) {
294 time
= ltt_event_time(e
);
295 g_string_append_printf(s
,"%s.%s: %ld.%ld",ltt_facility_name(facility
),
296 ltt_eventtype_name(eventtype
), (long)time
.tv_sec
, time
.tv_nsec
);
302 void print_field(ltt_event
*e
, ltt_field
*f
, lttv_string
*s
) {
308 type
= ltt_field_type(f
);
309 switch(ltt_type_class(type
)) {
311 g_string_append_printf(s
, " %ld", ltt_event_get_long_int(e
,f
));
315 g_string_append_printf(s
, " %lu", ltt_event_get_long_unsigned(e
,f
));
319 g_string_append_printf(s
, " %g", ltt_event_get_double(e
,f
));
323 g_string_append_printf(s
, " \"%s\"", ltt_event_get_string(e
,f
));
327 g_string_append_printf(s
, " %s", ltt_enum_string_get(type
,
328 event_get_unsigned(e
,f
));
333 g_string_append_printf(s
, " {");
334 nb
= ltt_event_field_element_number(e
,f
);
335 element
= ltt_field_element(f
);
336 for(i
= 0 ; i
< nb
; i
++) {
337 ltt_event_field_element_select(e
,f
,i
);
338 print_field(e
,element
,s
);
340 g_string_append_printf(s
, " }");
344 g_string_append_printf(s
, " {");
345 nb
= ltt_type_member_number(type
);
346 for(i
= 0 ; i
< nb
; i
++) {
347 element
= ltt_field_member(f
,i
);
348 print_field(e
,element
,s
);
350 g_string_append_printf(s
, " }");