trace-event-json-export.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*
  2. * trace-event-json-export. Export events to JSON format.
  3. *
  4. * derived from: trace-event-python.c
  5. *
  6. * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  7. * Copyright (C) 2010 Tom Zanussi <tzanussi@gmail.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. *
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <ctype.h>
  28. #include <errno.h>
  29. #include "../../perf.h"
  30. #include "../util.h"
  31. #include "../trace-event.h"
  32. #include "../event.h"
  33. #include "../thread.h"
  34. #define FTRACE_MAX_EVENT \
  35. ((1 << (sizeof(unsigned short) * 8)) - 1)
  36. FILE *ofp;
  37. struct event *events[FTRACE_MAX_EVENT];
  38. static char *cur_field_name;
  39. static void define_value(enum print_arg_type field_type,
  40. int id,
  41. const char *field_name,
  42. const char *field_value,
  43. const char *field_str)
  44. {
  45. const char *handler_name = (field_type == PRINT_SYMBOL) ?
  46. "define_symbol" : "define_flag";
  47. unsigned long long value;
  48. value = eval_flag(field_value);
  49. fprintf(ofp,
  50. ",\n[\"%s\",%d,{\"field\":\"%s\",\"value\":%llu,\"name\":\"%s\"}]",
  51. handler_name, id, field_name, value, field_str);
  52. }
  53. static void define_values(enum print_arg_type field_type,
  54. struct print_flag_sym *field,
  55. int id,
  56. const char *field_name)
  57. {
  58. define_value(field_type, id, field_name, field->value,
  59. field->str);
  60. if (field->next)
  61. define_values(field_type, field->next, id, field_name);
  62. }
  63. static void define_field(enum print_arg_type field_type,
  64. int id,
  65. const char *field_name,
  66. const char *delim)
  67. {
  68. if (field_type == PRINT_FLAGS) {
  69. const char *handler_name = "define_flag_field";
  70. fprintf(ofp,
  71. ",\n[\"%s\",%d,{\"field\":\"%s\",\"delim\":\"%s\"}]",
  72. handler_name, id, field_name, delim);
  73. } else {
  74. const char *handler_name = "define_symbol_field";
  75. fprintf(ofp, ",\n[\"%s\",%d,{\"field\":\"%s\"}]",
  76. handler_name, id, field_name);
  77. }
  78. }
  79. static void define_event_symbols(struct event *event,
  80. struct print_arg *args)
  81. {
  82. switch (args->type) {
  83. case PRINT_NULL:
  84. break;
  85. case PRINT_ATOM:
  86. define_value(PRINT_FLAGS, event->id, cur_field_name, "0",
  87. args->atom.atom);
  88. break;
  89. case PRINT_FIELD:
  90. cur_field_name = args->field.name;
  91. break;
  92. case PRINT_FLAGS:
  93. define_event_symbols(event, args->flags.field);
  94. define_field(PRINT_FLAGS, event->id, cur_field_name,
  95. args->flags.delim);
  96. define_values(PRINT_FLAGS, args->flags.flags, event->id,
  97. cur_field_name);
  98. break;
  99. case PRINT_SYMBOL:
  100. define_event_symbols(event, args->symbol.field);
  101. define_field(PRINT_SYMBOL, event->id, cur_field_name, NULL);
  102. define_values(PRINT_SYMBOL, args->symbol.symbols, event->id,
  103. cur_field_name);
  104. break;
  105. case PRINT_STRING:
  106. break;
  107. case PRINT_TYPE:
  108. define_event_symbols(event, args->typecast.item);
  109. break;
  110. case PRINT_OP:
  111. define_event_symbols(event, args->op.left);
  112. define_event_symbols(event, args->op.right);
  113. break;
  114. default:
  115. /* we should warn... */
  116. return;
  117. }
  118. if (args->next)
  119. define_event_symbols(event, args->next);
  120. }
  121. #define prefix(indx) (indx ? "," : "")
  122. static void define_event(struct event *event)
  123. {
  124. const char *ev_system = event->system;
  125. const char *ev_name = event->name;
  126. int indx = 0;
  127. const char *handler_name = "define_event";
  128. struct format_field *field = 0;
  129. fprintf(ofp,
  130. ",\n[\"%s\",%d,{\"system\":\"%s\",\"name\":\"%s\",\"args\":{",
  131. handler_name, event->id, ev_system, ev_name);
  132. fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_s", indx);
  133. indx++;
  134. fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_ns", indx);
  135. indx++;
  136. fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_cpu", indx);
  137. indx++;
  138. fprintf(ofp, "%s\"%s\":%d", prefix(indx), "common_comm", indx);
  139. indx++;
  140. for (field = event->format.common_fields; field; field = field->next) {
  141. fprintf(ofp, "%s\"%s\":%d", prefix(indx), field->name, indx);
  142. indx++;
  143. }
  144. for (field = event->format.fields; field; field = field->next) {
  145. fprintf(ofp, "%s\"%s\":%d", prefix(indx), field->name, indx);
  146. indx++;
  147. }
  148. fprintf(ofp, "}}]");
  149. }
  150. static inline struct event *find_cache_event(int type)
  151. {
  152. struct event *event;
  153. if (events[type])
  154. return events[type];
  155. events[type] = event = trace_find_event(type);
  156. if (!event)
  157. return NULL;
  158. define_event(event);
  159. define_event_symbols(event, event->print_fmt.args);
  160. return event;
  161. }
  162. static void json_process_field(int indx, void *data, struct format_field *field)
  163. {
  164. unsigned long long val;
  165. if (field->flags & FIELD_IS_STRING) {
  166. int offset;
  167. if (field->flags & FIELD_IS_DYNAMIC) {
  168. offset = *(int *)(data + field->offset);
  169. offset &= 0xffff;
  170. } else
  171. offset = field->offset;
  172. fprintf(ofp, "%s\"%s\"", prefix(indx), (char *)data + offset);
  173. } else { /* FIELD_IS_NUMERIC */
  174. val = read_size(data + field->offset, field->size);
  175. if (field->flags & FIELD_IS_SIGNED)
  176. fprintf(ofp, "%s%lld", prefix(indx),
  177. (long long int) val);
  178. else
  179. fprintf(ofp, "%s%llu", prefix(indx), val);
  180. }
  181. }
  182. static void json_process_event(union perf_event *pevent __unused,
  183. struct perf_sample *sample,
  184. struct perf_evsel *evsel __unused,
  185. struct machine *machine __unused,
  186. struct thread *thread)
  187. {
  188. struct format_field *field;
  189. unsigned long s, ns;
  190. struct event *event;
  191. int type;
  192. int indx = 0;
  193. int cpu = sample->cpu;
  194. void *data = sample->raw_data;
  195. unsigned long long nsecs = sample->time;
  196. char *comm = thread->comm;
  197. type = trace_parse_common_type(data);
  198. event = find_cache_event(type);
  199. if (!event)
  200. die("ug! no event found for type %d", type);
  201. s = nsecs / NSECS_PER_SEC;
  202. ns = nsecs - s * NSECS_PER_SEC;
  203. fprintf(ofp, ",\n[\"event\",%d,[%lu,%lu,%d,\"%s\"",
  204. type, s, ns, cpu, comm);
  205. indx += 4;
  206. for (field = event->format.common_fields; field; field = field->next)
  207. json_process_field(indx++, data, field);
  208. for (field = event->format.fields; field; field = field->next)
  209. json_process_field(indx++, data, field);
  210. fprintf(ofp , "]]");
  211. }
  212. /*
  213. * Start trace script
  214. */
  215. static int json_start_script(const char *script, int argc __unused,
  216. const char **argv __unused)
  217. {
  218. int err = 0;
  219. if (script[0]) {
  220. ofp = fopen(script, "w");
  221. if (ofp == NULL) {
  222. fprintf(stderr, "couldn't open %s\n", script);
  223. return -EBADF;
  224. }
  225. } else
  226. ofp = stdout;
  227. fprintf(ofp, "[[\"trace_start\"]");
  228. return err;
  229. }
  230. /*
  231. * Stop trace script
  232. */
  233. static int json_stop_script(void)
  234. {
  235. int err = 0;
  236. fprintf(ofp, ",\n[\"trace_end\"]]");
  237. return err;
  238. }
  239. static int json_generate_script(const char *outfile)
  240. {
  241. struct event *event = NULL;
  242. char fname[PATH_MAX];
  243. snprintf(fname, sizeof(fname), "%s.json", outfile);
  244. ofp = fopen(fname, "w");
  245. if (ofp == NULL) {
  246. fprintf(stderr, "couldn't open %s\n", fname);
  247. return -EBADF;
  248. }
  249. fprintf(ofp, "[[\"generate_start\"]");
  250. while ((event = trace_find_next_event(event))) {
  251. define_event(event);
  252. define_event_symbols(event, event->print_fmt.args);
  253. }
  254. fprintf(ofp, ",\n[\"generate_end\"]]");
  255. fclose(ofp);
  256. fprintf(stderr, "generated json script: %s\n", fname);
  257. return 0;
  258. }
  259. struct scripting_ops json_scripting_ops = {
  260. .name = "JSON",
  261. .start_script = json_start_script,
  262. .stop_script = json_stop_script,
  263. .process_event = json_process_event,
  264. .generate_script = json_generate_script,
  265. };
  266. void setup_json_export(void)
  267. {
  268. int err;
  269. err = script_spec_register("JSON", &json_scripting_ops);
  270. if (err)
  271. die("error registering JSON export extension");
  272. }