old files clean
[lttv.git] / ltt / branches / poly / lttv / modules / text / textDump.c
CommitLineData
48f6f3c2 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
3 after each trace. */
4
996acd92 5#include <lttv/lttv.h>
6#include <lttv/option.h>
7#include <lttv/module.h>
8#include <lttv/hook.h>
9#include <lttv/attribute.h>
10#include <lttv/iattribute.h>
b445142a 11#include <lttv/stats.h>
ffd54a90 12#include <ltt/ltt.h>
13#include <ltt/event.h>
14#include <ltt/type.h>
15#include <ltt/trace.h>
16#include <stdio.h>
996acd92 17
dc877563 18static gboolean
19 a_field_names,
b445142a 20 a_state,
21 a_cpu_stats,
22 a_process_stats;
dc877563 23
24static char
b445142a 25 *a_file_name = NULL;
dc877563 26
27static LttvHooks
28 *before_traceset,
29 *after_traceset,
30 *before_trace,
31 *before_event;
32
f60d7a47 33
ffd54a90 34void print_field(LttEvent *e, LttField *f, GString *s, gboolean field_names) {
dc877563 35
ffd54a90 36 LttType *type;
dc877563 37
ffd54a90 38 LttField *element;
dc877563 39
ffd54a90 40 char *name;
dc877563 41
ffd54a90 42 int nb, i;
dc877563 43
ffd54a90 44 type = ltt_field_type(f);
45 switch(ltt_type_class(type)) {
46 case LTT_INT:
47 g_string_append_printf(s, " %ld", ltt_event_get_long_int(e,f));
48 break;
dc877563 49
ffd54a90 50 case LTT_UINT:
51 g_string_append_printf(s, " %lu", ltt_event_get_long_unsigned(e,f));
52 break;
dc877563 53
ffd54a90 54 case LTT_FLOAT:
55 g_string_append_printf(s, " %g", ltt_event_get_double(e,f));
56 break;
dc877563 57
ffd54a90 58 case LTT_STRING:
59 g_string_append_printf(s, " \"%s\"", ltt_event_get_string(e,f));
60 break;
61
62 case LTT_ENUM:
63 g_string_append_printf(s, " %s", ltt_enum_string_get(type,
c6bc9cb9 64 ltt_event_get_unsigned(e,f)-1));
ffd54a90 65 break;
66
67 case LTT_ARRAY:
68 case LTT_SEQUENCE:
69 g_string_append_printf(s, " {");
70 nb = ltt_event_field_element_number(e,f);
71 element = ltt_field_element(f);
72 for(i = 0 ; i < nb ; i++) {
73 ltt_event_field_element_select(e,f,i);
74 print_field(e, element, s, field_names);
75 }
76 g_string_append_printf(s, " }");
77 break;
78
79 case LTT_STRUCT:
80 g_string_append_printf(s, " {");
81 nb = ltt_type_member_number(type);
82 for(i = 0 ; i < nb ; i++) {
83 element = ltt_field_member(f,i);
c432246e 84 if(field_names) {
ffd54a90 85 ltt_type_member_type(type, i, &name);
c432246e 86 g_string_append_printf(s, " %s = ", name);
ffd54a90 87 }
88 print_field(e, element, s, field_names);
89 }
90 g_string_append_printf(s, " }");
91 break;
92 }
48f6f3c2 93}
94
95
ffd54a90 96void lttv_event_to_string(LttEvent *e, LttTracefile *tf, GString *s,
3d27549e 97 gboolean mandatory_fields, gboolean field_names, LttvTracefileState *tfs)
98{
ffd54a90 99 LttFacility *facility;
48f6f3c2 100
ffd54a90 101 LttEventType *event_type;
48f6f3c2 102
ffd54a90 103 LttType *type;
104
105 LttField *field;
48f6f3c2 106
ffd54a90 107 LttTime time;
48f6f3c2 108
ffd54a90 109 g_string_set_size(s,0);
dc877563 110
ffd54a90 111 facility = ltt_event_facility(e);
112 event_type = ltt_event_eventtype(e);
113 field = ltt_event_field(e);
48f6f3c2 114
ffd54a90 115 if(mandatory_fields) {
116 time = ltt_event_time(e);
b445142a 117 g_string_append_printf(s,"%s.%s: %ld.%09ld (%s)",
118 ltt_facility_name(facility),
ffd54a90 119 ltt_eventtype_name(event_type), (long)time.tv_sec, time.tv_nsec,
b445142a 120 g_quark_to_string(tfs->cpu_name));
c432246e 121 /* Print the process id and the state/interrupt type of the process */
07bb8c8f 122 g_string_append_printf(s,", %u, %u, %s", tfs->process->pid,
123 tfs->process->ppid,
124 g_quark_to_string(tfs->process->state->t));
ffd54a90 125 }
126
c6bc9cb9 127 if(field)
128 print_field(e, field, s, field_names);
ffd54a90 129}
48f6f3c2 130
131
b445142a 132static void
133print_tree(FILE *fp, GString *indent, LttvAttribute *tree)
134{
135 int i, nb, saved_length;
136
137 LttvAttribute *subtree;
138
139 LttvAttributeName name;
140
141 LttvAttributeValue value;
142
143 LttvAttributeType type;
144
145 nb = lttv_attribute_get_number(tree);
146 for(i = 0 ; i < nb ; i++) {
147 type = lttv_attribute_get(tree, i, &name, &value);
148 fprintf(fp, "%s%s: ", indent->str, g_quark_to_string(name));
149
150 switch(type) {
151 case LTTV_INT:
152 fprintf(fp, "%d\n", *value.v_int);
153 break;
154 case LTTV_UINT:
155 fprintf(fp, "%u\n", *value.v_uint);
156 break;
157 case LTTV_LONG:
158 fprintf(fp, "%ld\n", *value.v_long);
159 break;
160 case LTTV_ULONG:
161 fprintf(fp, "%lu\n", *value.v_ulong);
162 break;
163 case LTTV_FLOAT:
164 fprintf(fp, "%f\n", (double)*value.v_float);
165 break;
166 case LTTV_DOUBLE:
167 fprintf(fp, "%f\n", *value.v_double);
168 break;
169 case LTTV_TIME:
170 fprintf(fp, "%10u.%09u\n", value.v_time->tv_sec,
171 value.v_time->tv_nsec);
172 break;
173 case LTTV_POINTER:
174 fprintf(fp, "POINTER\n");
175 break;
176 case LTTV_STRING:
177 fprintf(fp, "%s\n", *value.v_string);
178 break;
179 case LTTV_GOBJECT:
180 if(LTTV_IS_ATTRIBUTE(*(value.v_gobject))) {
181 fprintf(fp, "\n");
182 subtree = (LttvAttribute *)*(value.v_gobject);
183 saved_length = indent->len;
184 g_string_append(indent, " ");
185 print_tree(fp, indent, subtree);
186 g_string_truncate(indent, saved_length);
187 }
188 else fprintf(fp, "GOBJECT\n");
189 break;
190 case LTTV_NONE:
191 break;
192 }
193 }
194}
195
196
197static void
198print_stats(FILE *fp, LttvTracesetStats *tscs)
199{
200 int i, nb, saved_length;
201
202 LttvTraceset *ts;
203
204 LttvTraceStats *tcs;
205
206 GString *indent;
207
208 LttSystemDescription *desc;
209
210 if(tscs->stats == NULL) return;
211 indent = g_string_new("");
212 fprintf(fp, "Traceset statistics:\n\n");
213 print_tree(fp, indent, tscs->stats);
214
215 ts = tscs->parent.parent.ts;
216 nb = lttv_traceset_number(ts);
217
218 for(i = 0 ; i < nb ; i++) {
219 tcs = (LttvTraceStats *)(LTTV_TRACESET_CONTEXT(tscs)->traces[i]);
220 desc = ltt_trace_system_description(tcs->parent.parent.t);
a5dcde2f 221 fprintf(fp, "Trace on system %s at time %d secs:\n",
222 ltt_trace_system_description_node_name(desc),
223 (ltt_trace_system_description_trace_start_time(desc)).tv_sec);
b445142a 224 saved_length = indent->len;
225 g_string_append(indent, " ");
226 print_tree(fp, indent, tcs->stats);
227 g_string_truncate(indent, saved_length);
228 }
229 g_string_free(indent, TRUE);
230}
231
232
dc877563 233/* Insert the hooks before and after each trace and tracefile, and for each
234 event. Print a global header. */
235
236static FILE *a_file;
48f6f3c2 237
dc877563 238static GString *a_string;
239
ffd54a90 240static gboolean write_traceset_header(void *hook_data, void *call_data)
48f6f3c2 241{
dc877563 242 LttvTracesetContext *tc = (LttvTracesetContext *)call_data;
48f6f3c2 243
b445142a 244 g_info("TextDump traceset header");
245
dc877563 246 if(a_file_name == NULL) a_file = stdout;
247 else a_file = fopen(a_file_name, "w");
48f6f3c2 248
dc877563 249 if(a_file == NULL) g_error("cannot open file %s", a_file_name);
48f6f3c2 250
dc877563 251 /* Print the trace set header */
252 fprintf(a_file,"Trace set contains %d traces\n\n",
ffd54a90 253 lttv_traceset_number(tc->ts));
48f6f3c2 254
dc877563 255 return FALSE;
48f6f3c2 256}
257
258
ffd54a90 259static gboolean write_traceset_footer(void *hook_data, void *call_data)
48f6f3c2 260{
dc877563 261 LttvTracesetContext *tc = (LttvTracesetContext *)call_data;
48f6f3c2 262
b445142a 263 g_info("TextDump traceset footer");
264
dc877563 265 fprintf(a_file,"End trace set\n\n");
48f6f3c2 266
b445142a 267 if(LTTV_IS_TRACESET_STATS(tc)) {
268 print_stats(a_file, (LttvTracesetStats *)tc);
269 }
270
ffd54a90 271 if(a_file_name != NULL) fclose(a_file);
272
dc877563 273 return FALSE;
48f6f3c2 274}
275
276
dc877563 277static gboolean write_trace_header(void *hook_data, void *call_data)
48f6f3c2 278{
dc877563 279 LttvTraceContext *tc = (LttvTraceContext *)call_data;
280
281 LttSystemDescription *system = ltt_trace_system_description(tc->t);
48f6f3c2 282
a5dcde2f 283 fprintf(a_file," Trace from %s in %s\n%s\n\n",
284 ltt_trace_system_description_node_name(system),
285 ltt_trace_system_description_domain_name(system),
286 ltt_trace_system_description_description(system));
dc877563 287 return FALSE;
48f6f3c2 288}
289
290
dc877563 291static int write_event_content(void *hook_data, void *call_data)
48f6f3c2 292{
dc877563 293 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
48f6f3c2 294
dc877563 295 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
48f6f3c2 296
dc877563 297 LttEvent *e;
48f6f3c2 298
dc877563 299 e = tfc->e;
48f6f3c2 300
3d27549e 301 lttv_event_to_string(e, tfc->tf, a_string, TRUE, a_field_names, tfs);
c6bc9cb9 302 g_string_append_printf(a_string,"\n");
dc877563 303
304 if(a_state) {
9d0bb8d1 305 g_string_append_printf(a_string, " %s ",
ffd54a90 306 g_quark_to_string(tfs->process->state->s));
dc877563 307 }
48f6f3c2 308
ffd54a90 309 fputs(a_string->str, a_file);
dc877563 310 return FALSE;
48f6f3c2 311}
312
313
d83f6739 314G_MODULE_EXPORT void init(LttvModule *self, int argc, char **argv)
48f6f3c2 315{
ffd54a90 316 LttvAttributeValue value;
48f6f3c2 317
ffd54a90 318 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
48f6f3c2 319
b445142a 320 g_info("Init textDump.c");
9402662d 321
308711e5 322 lttv_module_require(self, "libbatchAnalysis", argc, argv);
323
c6bc9cb9 324 a_string = g_string_new("");
325
ffd54a90 326 a_file_name = NULL;
327 lttv_option_add("output", 'o',
328 "output file where the text is written",
329 "file name",
330 LTTV_OPT_STRING, &a_file_name, NULL, NULL);
48f6f3c2 331
ffd54a90 332 a_field_names = FALSE;
333 lttv_option_add("field_names", 'l',
334 "write the field names for each event",
335 "",
336 LTTV_OPT_NONE, &a_field_names, NULL, NULL);
48f6f3c2 337
ffd54a90 338 a_state = FALSE;
339 lttv_option_add("process_state", 's',
340 "write the pid and state for each event",
341 "",
342 LTTV_OPT_NONE, &a_state, NULL, NULL);
dc877563 343
b445142a 344 a_cpu_stats = FALSE;
9d0bb8d1 345 lttv_option_add("cpu_stats", 'c',
b445142a 346 "write the per cpu statistics",
347 "",
348 LTTV_OPT_NONE, &a_cpu_stats, NULL, NULL);
349
350 a_process_stats = FALSE;
9d0bb8d1 351 lttv_option_add("process_stats", 'p',
b445142a 352 "write the per process statistics",
353 "",
354 LTTV_OPT_NONE, &a_process_stats, NULL, NULL);
355
ffd54a90 356 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/before",
357 LTTV_POINTER, &value));
358 g_assert((before_event = *(value.v_pointer)) != NULL);
359 lttv_hooks_add(before_event, write_event_content, NULL);
dc877563 360
ffd54a90 361 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/before",
362 LTTV_POINTER, &value));
363 g_assert((before_trace = *(value.v_pointer)) != NULL);
364 lttv_hooks_add(before_trace, write_trace_header, NULL);
dc877563 365
ffd54a90 366 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/before",
367 LTTV_POINTER, &value));
368 g_assert((before_traceset = *(value.v_pointer)) != NULL);
369 lttv_hooks_add(before_traceset, write_traceset_header, NULL);
dc877563 370
ffd54a90 371 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/after",
372 LTTV_POINTER, &value));
373 g_assert((after_traceset = *(value.v_pointer)) != NULL);
374 lttv_hooks_add(after_traceset, write_traceset_footer, NULL);
375}
48f6f3c2 376
48f6f3c2 377
d83f6739 378G_MODULE_EXPORT void destroy()
ffd54a90 379{
b445142a 380 g_info("Destroy textDump");
381
ffd54a90 382 lttv_option_remove("output");
48f6f3c2 383
ffd54a90 384 lttv_option_remove("field_names");
48f6f3c2 385
ffd54a90 386 lttv_option_remove("process_state");
48f6f3c2 387
b445142a 388 lttv_option_remove("cpu_stats");
389
390 lttv_option_remove("process_stats");
391
c6bc9cb9 392 g_string_free(a_string, TRUE);
393
ffd54a90 394 lttv_hooks_remove_data(before_event, write_event_content, NULL);
48f6f3c2 395
ffd54a90 396 lttv_hooks_remove_data(before_trace, write_trace_header, NULL);
48f6f3c2 397
ffd54a90 398 lttv_hooks_remove_data(before_trace, write_traceset_header, NULL);
48f6f3c2 399
ffd54a90 400 lttv_hooks_remove_data(before_trace, write_traceset_footer, NULL);
48f6f3c2 401}
402
403
404
405
This page took 0.043782 seconds and 4 git commands to generate.