xref: /freebsd/lib/libpmc/libpmc_json.cc (revision 94426d21bf62f2b36dc9b556ab27c401a412a026)
1f992dd4bSMatt Macy /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3f992dd4bSMatt Macy  *
4f992dd4bSMatt Macy  * Copyright (c) 2018, Matthew Macy
5f992dd4bSMatt Macy  *
6f992dd4bSMatt Macy  * Redistribution and use in source and binary forms, with or without
7f992dd4bSMatt Macy  * modification, are permitted provided that the following conditions
8f992dd4bSMatt Macy  * are met:
9f992dd4bSMatt Macy  * 1. Redistributions of source code must retain the above copyright
10f992dd4bSMatt Macy  *    notice, this list of conditions and the following disclaimer.
11f992dd4bSMatt Macy  * 2. Redistributions in binary form must reproduce the above copyright
12f992dd4bSMatt Macy  *    notice, this list of conditions and the following disclaimer in the
13f992dd4bSMatt Macy  *    documentation and/or other materials provided with the distribution.
14f992dd4bSMatt Macy  *
15f992dd4bSMatt Macy  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16f992dd4bSMatt Macy  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17f992dd4bSMatt Macy  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18f992dd4bSMatt Macy  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19f992dd4bSMatt Macy  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20f992dd4bSMatt Macy  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21f992dd4bSMatt Macy  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22f992dd4bSMatt Macy  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23f992dd4bSMatt Macy  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24f992dd4bSMatt Macy  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25f992dd4bSMatt Macy  * SUCH DAMAGE.
26f992dd4bSMatt Macy  *
27f992dd4bSMatt Macy  * $FreeBSD$
28f992dd4bSMatt Macy  *
29f992dd4bSMatt Macy  */
30f992dd4bSMatt Macy 
31f992dd4bSMatt Macy #include <sys/types.h>
32f992dd4bSMatt Macy #include <sys/sysctl.h>
33f992dd4bSMatt Macy #include <assert.h>
34b3d01a2aSEnji Cooper #include <err.h>
35b3d01a2aSEnji Cooper #include <errno.h>
36b3d01a2aSEnji Cooper #include <limits.h>
37b3d01a2aSEnji Cooper #include <stddef.h>
38b3d01a2aSEnji Cooper #include <stdio.h>
39b3d01a2aSEnji Cooper #include <stdlib.h>
40b3d01a2aSEnji Cooper #include <string.h>
41f992dd4bSMatt Macy #include <string>
42f992dd4bSMatt Macy #include <sysexits.h>
43b3d01a2aSEnji Cooper 
44b3d01a2aSEnji Cooper #include <pmc.h>
45f992dd4bSMatt Macy #include <pmcformat.h>
46b3d01a2aSEnji Cooper #include <pmclog.h>
47f992dd4bSMatt Macy 
48f992dd4bSMatt Macy using std::string;
49f992dd4bSMatt Macy 
50f992dd4bSMatt Macy static const char *typenames[] = {
51f992dd4bSMatt Macy 	"",
52f992dd4bSMatt Macy 	"{\"type\": \"closelog\"}\n",
53f992dd4bSMatt Macy 	"{\"type\": \"dropnotify\"}\n",
54f992dd4bSMatt Macy 	"{\"type\": \"initialize\"",
55f992dd4bSMatt Macy 	"",
56f992dd4bSMatt Macy 	"{\"type\": \"pmcallocate\"",
57f992dd4bSMatt Macy 	"{\"type\": \"pmcattach\"",
58f992dd4bSMatt Macy 	"{\"type\": \"pmcdetach\"",
59f992dd4bSMatt Macy 	"{\"type\": \"proccsw\"",
60f992dd4bSMatt Macy 	"{\"type\": \"procexec\"",
61f992dd4bSMatt Macy 	"{\"type\": \"procexit\"",
62f992dd4bSMatt Macy 	"{\"type\": \"procfork\"",
63f992dd4bSMatt Macy 	"{\"type\": \"sysexit\"",
64f992dd4bSMatt Macy 	"{\"type\": \"userdata\"",
65f992dd4bSMatt Macy 	"{\"type\": \"map_in\"",
66f992dd4bSMatt Macy 	"{\"type\": \"map_out\"",
67f992dd4bSMatt Macy 	"{\"type\": \"callchain\"",
68f992dd4bSMatt Macy 	"{\"type\": \"pmcallocatedyn\"",
69f992dd4bSMatt Macy 	"{\"type\": \"thr_create\"",
70f992dd4bSMatt Macy 	"{\"type\": \"thr_exit\"",
71f992dd4bSMatt Macy 	"{\"type\": \"proc_create\"",
72f992dd4bSMatt Macy };
73f992dd4bSMatt Macy 
74f992dd4bSMatt Macy static string
75f992dd4bSMatt Macy startentry(struct pmclog_ev *ev)
76f992dd4bSMatt Macy {
77f992dd4bSMatt Macy 	char eventbuf[128];
78f992dd4bSMatt Macy 
79f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"tsc\": \"%jd\"",
80a72a9036SMatt Macy 	    typenames[ev->pl_type], (uintmax_t)ev->pl_ts.tv_sec);
81f992dd4bSMatt Macy 	return (string(eventbuf));
82f992dd4bSMatt Macy }
83f992dd4bSMatt Macy 
84f992dd4bSMatt Macy static string
85f992dd4bSMatt Macy initialize_to_json(struct pmclog_ev *ev)
86f992dd4bSMatt Macy {
87f992dd4bSMatt Macy 	char eventbuf[256];
88f992dd4bSMatt Macy 	string startent;
89f992dd4bSMatt Macy 
90f992dd4bSMatt Macy 	startent = startentry(ev);
91f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
92f992dd4bSMatt Macy 	    "%s, \"version\": \"0x%08x\", \"arch\": \"0x%08x\", \"cpuid\": \"%s\", "
93f992dd4bSMatt Macy 		"\"tsc_freq\": \"%jd\", \"sec\": \"%jd\", \"nsec\": \"%jd\"}\n",
94f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_i.pl_version, ev->pl_u.pl_i.pl_arch,
95f992dd4bSMatt Macy 		ev->pl_u.pl_i.pl_cpuid, (uintmax_t)ev->pl_u.pl_i.pl_tsc_freq,
96f992dd4bSMatt Macy 		(uintmax_t)ev->pl_u.pl_i.pl_ts.tv_sec, (uintmax_t)ev->pl_u.pl_i.pl_ts.tv_nsec);
97f992dd4bSMatt Macy 	return string(eventbuf);
98f992dd4bSMatt Macy }
99f992dd4bSMatt Macy 
100f992dd4bSMatt Macy static string
101f992dd4bSMatt Macy pmcallocate_to_json(struct pmclog_ev *ev)
102f992dd4bSMatt Macy {
103f992dd4bSMatt Macy 	char eventbuf[256];
104f992dd4bSMatt Macy 	string startent;
105f992dd4bSMatt Macy 
106f992dd4bSMatt Macy 	startent = startentry(ev);
107f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
108f992dd4bSMatt Macy 	    "%s, \"pmcid\": \"0x%08x\", \"event\": \"0x%08x\", \"flags\": \"0x%08x\", "
109f992dd4bSMatt Macy 	    "\"rate\": \"%jd\"}\n",
110f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_a.pl_pmcid, ev->pl_u.pl_a.pl_event,
111f992dd4bSMatt Macy 	    ev->pl_u.pl_a.pl_flags, (intmax_t)ev->pl_u.pl_a.pl_rate);
112f992dd4bSMatt Macy 	return string(eventbuf);
113f992dd4bSMatt Macy }
114f992dd4bSMatt Macy 
115f992dd4bSMatt Macy static string
116f992dd4bSMatt Macy pmcattach_to_json(struct pmclog_ev *ev)
117f992dd4bSMatt Macy {
118f992dd4bSMatt Macy 	char eventbuf[2048];
119f992dd4bSMatt Macy 	string startent;
120f992dd4bSMatt Macy 
121f992dd4bSMatt Macy 	startent = startentry(ev);
122f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
123f992dd4bSMatt Macy 	    "%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", \"pathname\": \"%s\"}\n",
124f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_t.pl_pmcid, ev->pl_u.pl_t.pl_pid,
125f992dd4bSMatt Macy 	    ev->pl_u.pl_t.pl_pathname);
126f992dd4bSMatt Macy 	return string(eventbuf);
127f992dd4bSMatt Macy }
128f992dd4bSMatt Macy 
129f992dd4bSMatt Macy static string
130f992dd4bSMatt Macy pmcdetach_to_json(struct pmclog_ev *ev)
131f992dd4bSMatt Macy {
132f992dd4bSMatt Macy 	char eventbuf[128];
133f992dd4bSMatt Macy 	string startent;
134f992dd4bSMatt Macy 
135f992dd4bSMatt Macy 	startent = startentry(ev);
136f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
137f992dd4bSMatt Macy 		"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\"}\n",
138f992dd4bSMatt Macy 			 startent.c_str(), ev->pl_u.pl_d.pl_pmcid, ev->pl_u.pl_d.pl_pid);
139f992dd4bSMatt Macy 	return string(eventbuf);
140f992dd4bSMatt Macy }
141f992dd4bSMatt Macy 
142f992dd4bSMatt Macy 
143f992dd4bSMatt Macy static string
144f992dd4bSMatt Macy proccsw_to_json(struct pmclog_ev *ev)
145f992dd4bSMatt Macy {
146f992dd4bSMatt Macy 	char eventbuf[128];
147f992dd4bSMatt Macy 	string startent;
148f992dd4bSMatt Macy 
149f992dd4bSMatt Macy 	startent = startentry(ev);
150f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\" "
151f992dd4bSMatt Macy 	    "\"tid\": \"%d\", \"value\": \"0x%016jx\"}\n",
152f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_c.pl_pmcid, ev->pl_u.pl_c.pl_pid,
153f992dd4bSMatt Macy 	    ev->pl_u.pl_c.pl_tid, (uintmax_t)ev->pl_u.pl_c.pl_value);
154f992dd4bSMatt Macy 	return string(eventbuf);
155f992dd4bSMatt Macy }
156f992dd4bSMatt Macy 
157f992dd4bSMatt Macy static string
158f992dd4bSMatt Macy procexec_to_json(struct pmclog_ev *ev)
159f992dd4bSMatt Macy {
160f992dd4bSMatt Macy 	char eventbuf[2048];
161f992dd4bSMatt Macy 	string startent;
162f992dd4bSMatt Macy 
163f992dd4bSMatt Macy 	startent = startentry(ev);
164f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
165f992dd4bSMatt Macy 		"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", "
166*94426d21SJessica Clarke 	    "\"base\": \"0x%016jx\", \"dyn\": \"0x%016jx\", "
167*94426d21SJessica Clarke 	    "\"pathname\": \"%s\"}\n",
168f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_x.pl_pmcid, ev->pl_u.pl_x.pl_pid,
169*94426d21SJessica Clarke 		(uintmax_t)ev->pl_u.pl_x.pl_baseaddr,
170*94426d21SJessica Clarke 		(uintmax_t)ev->pl_u.pl_x.pl_dynaddr,
171*94426d21SJessica Clarke 		ev->pl_u.pl_x.pl_pathname);
172f992dd4bSMatt Macy 	return string(eventbuf);
173f992dd4bSMatt Macy }
174f992dd4bSMatt Macy 
175f992dd4bSMatt Macy static string
176f992dd4bSMatt Macy procexit_to_json(struct pmclog_ev *ev)
177f992dd4bSMatt Macy {
178f992dd4bSMatt Macy 	char eventbuf[128];
179f992dd4bSMatt Macy 	string startent;
180f992dd4bSMatt Macy 
181f992dd4bSMatt Macy 	startent = startentry(ev);
182f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
183f992dd4bSMatt Macy 		"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", "
184f992dd4bSMatt Macy 	    "\"value\": \"0x%016jx\"}\n",
185f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_e.pl_pmcid, ev->pl_u.pl_e.pl_pid,
186f992dd4bSMatt Macy 	    (uintmax_t)ev->pl_u.pl_e.pl_value);
187f992dd4bSMatt Macy 	return string(eventbuf);
188f992dd4bSMatt Macy }
189f992dd4bSMatt Macy 
190f992dd4bSMatt Macy static string
191f992dd4bSMatt Macy procfork_to_json(struct pmclog_ev *ev)
192f992dd4bSMatt Macy {
193f992dd4bSMatt Macy 	char eventbuf[128];
194f992dd4bSMatt Macy 	string startent;
195f992dd4bSMatt Macy 
196f992dd4bSMatt Macy 	startent = startentry(ev);
197f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
198f992dd4bSMatt Macy 		"%s, \"oldpid\": \"%d\", \"newpid\": \"%d\"}\n",
199f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_f.pl_oldpid, ev->pl_u.pl_f.pl_newpid);
200f992dd4bSMatt Macy 	return string(eventbuf);
201f992dd4bSMatt Macy }
202f992dd4bSMatt Macy 
203f992dd4bSMatt Macy static string
204f992dd4bSMatt Macy sysexit_to_json(struct pmclog_ev *ev)
205f992dd4bSMatt Macy {
206f992dd4bSMatt Macy 	char eventbuf[128];
207f992dd4bSMatt Macy 	string startent;
208f992dd4bSMatt Macy 
209f992dd4bSMatt Macy 	startent = startentry(ev);
210f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"pid\": \"%d\"}\n",
211f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_se.pl_pid);
212f992dd4bSMatt Macy 	return string(eventbuf);
213f992dd4bSMatt Macy }
214f992dd4bSMatt Macy 
215f992dd4bSMatt Macy static string
216f992dd4bSMatt Macy userdata_to_json(struct pmclog_ev *ev)
217f992dd4bSMatt Macy {
218f992dd4bSMatt Macy 	char eventbuf[128];
219f992dd4bSMatt Macy 	string startent;
220f992dd4bSMatt Macy 
221f992dd4bSMatt Macy 	startent = startentry(ev);
222f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"userdata\": \"0x%08x\"}\n",
223f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_u.pl_userdata);
224f992dd4bSMatt Macy 	return string(eventbuf);
225f992dd4bSMatt Macy }
226f992dd4bSMatt Macy 
227f992dd4bSMatt Macy static string
228f992dd4bSMatt Macy map_in_to_json(struct pmclog_ev *ev)
229f992dd4bSMatt Macy {
230f992dd4bSMatt Macy 	char eventbuf[2048];
231f992dd4bSMatt Macy 	string startent;
232f992dd4bSMatt Macy 
233f992dd4bSMatt Macy 	startent = startentry(ev);
234f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"pid\": \"%d\", "
235f992dd4bSMatt Macy 	    "\"start\": \"0x%016jx\", \"pathname\": \"%s\"}\n",
236f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_mi.pl_pid,
237f992dd4bSMatt Macy 	    (uintmax_t)ev->pl_u.pl_mi.pl_start, ev->pl_u.pl_mi.pl_pathname);
238f992dd4bSMatt Macy 	return string(eventbuf);
239f992dd4bSMatt Macy }
240f992dd4bSMatt Macy 
241f992dd4bSMatt Macy static string
242f992dd4bSMatt Macy map_out_to_json(struct pmclog_ev *ev)
243f992dd4bSMatt Macy {
244f992dd4bSMatt Macy 	char eventbuf[256];
245f992dd4bSMatt Macy 	string startent;
246f992dd4bSMatt Macy 
247f992dd4bSMatt Macy 	startent = startentry(ev);
248f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"pid\": \"%d\", "
249f992dd4bSMatt Macy 	    "\"start\": \"0x%016jx\", \"end\": \"0x%016jx\"}\n",
250f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_mi.pl_pid,
251f992dd4bSMatt Macy 	    (uintmax_t)ev->pl_u.pl_mi.pl_start,
252f992dd4bSMatt Macy 	    (uintmax_t)ev->pl_u.pl_mo.pl_end);
253f992dd4bSMatt Macy 	return string(eventbuf);
254f992dd4bSMatt Macy }
255f992dd4bSMatt Macy 
256f992dd4bSMatt Macy static string
257f992dd4bSMatt Macy callchain_to_json(struct pmclog_ev *ev)
258f992dd4bSMatt Macy {
259f992dd4bSMatt Macy 	char eventbuf[1024];
260f992dd4bSMatt Macy 	string result;
261f992dd4bSMatt Macy 	uint32_t i;
262f992dd4bSMatt Macy 	string startent;
263f992dd4bSMatt Macy 
264f992dd4bSMatt Macy 	startent = startentry(ev);
265f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
266f992dd4bSMatt Macy 	    "%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", \"tid\": \"%d\", "
267f992dd4bSMatt Macy 	    "\"cpuflags\": \"0x%08x\", \"cpuflags2\": \"0x%08x\", \"pc\": [ ",
268f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_cc.pl_pmcid, ev->pl_u.pl_cc.pl_pid,
269f992dd4bSMatt Macy 	    ev->pl_u.pl_cc.pl_tid, ev->pl_u.pl_cc.pl_cpuflags, ev->pl_u.pl_cc.pl_cpuflags2);
270f992dd4bSMatt Macy 	result = string(eventbuf);
271f992dd4bSMatt Macy 	for (i = 0; i < ev->pl_u.pl_cc.pl_npc - 1; i++) {
272a72a9036SMatt Macy 		snprintf(eventbuf, sizeof(eventbuf), "\"0x%016jx\", ", (uintmax_t)ev->pl_u.pl_cc.pl_pc[i]);
273f992dd4bSMatt Macy 		result += string(eventbuf);
274f992dd4bSMatt Macy 	}
275a72a9036SMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "\"0x%016jx\"]}\n", (uintmax_t)ev->pl_u.pl_cc.pl_pc[i]);
276f992dd4bSMatt Macy 	result += string(eventbuf);
277f992dd4bSMatt Macy 	return (result);
278f992dd4bSMatt Macy }
279f992dd4bSMatt Macy 
280f992dd4bSMatt Macy static string
281f992dd4bSMatt Macy pmcallocatedyn_to_json(struct pmclog_ev *ev)
282f992dd4bSMatt Macy {
283f992dd4bSMatt Macy 	char eventbuf[2048];
284f992dd4bSMatt Macy 	string startent;
285f992dd4bSMatt Macy 
286f992dd4bSMatt Macy 	startent = startentry(ev);
287f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
288f992dd4bSMatt Macy 	    "%s, \"pmcid\": \"0x%08x\", \"event\": \"%d\", \"flags\": \"0x%08x\", \"evname\": \"%s\"}\n",
289f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_ad.pl_pmcid, ev->pl_u.pl_ad.pl_event,
290f992dd4bSMatt Macy 	    ev->pl_u.pl_ad.pl_flags, ev->pl_u.pl_ad.pl_evname);
291f992dd4bSMatt Macy 	return string(eventbuf);
292f992dd4bSMatt Macy }
293f992dd4bSMatt Macy 
294f992dd4bSMatt Macy static string
295f992dd4bSMatt Macy proccreate_to_json(struct pmclog_ev *ev)
296f992dd4bSMatt Macy {
297f992dd4bSMatt Macy 	char eventbuf[2048];
298f992dd4bSMatt Macy 	string startent;
299f992dd4bSMatt Macy 
300f992dd4bSMatt Macy 	startent = startentry(ev);
301f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
302f992dd4bSMatt Macy 	    "%s, \"pid\": \"%d\", \"flags\": \"0x%08x\", \"pcomm\": \"%s\"}\n",
303f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_pc.pl_pid,
304f992dd4bSMatt Macy 	    ev->pl_u.pl_pc.pl_flags, ev->pl_u.pl_pc.pl_pcomm);
305f992dd4bSMatt Macy 	return string(eventbuf);
306f992dd4bSMatt Macy }
307f992dd4bSMatt Macy 
308f992dd4bSMatt Macy static string
309f992dd4bSMatt Macy threadcreate_to_json(struct pmclog_ev *ev)
310f992dd4bSMatt Macy {
311f992dd4bSMatt Macy 	char eventbuf[2048];
312f992dd4bSMatt Macy 	string startent;
313f992dd4bSMatt Macy 
314f992dd4bSMatt Macy 	startent = startentry(ev);
315f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
316f992dd4bSMatt Macy 	    "%s, \"tid\": \"%d\", \"pid\": \"%d\", \"flags\": \"0x%08x\", \"tdname\": \"%s\"}\n",
317f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_tc.pl_tid, ev->pl_u.pl_tc.pl_pid,
318f992dd4bSMatt Macy 	    ev->pl_u.pl_tc.pl_flags, ev->pl_u.pl_tc.pl_tdname);
319f992dd4bSMatt Macy 	return string(eventbuf);
320f992dd4bSMatt Macy }
321f992dd4bSMatt Macy 
322f992dd4bSMatt Macy static string
323f992dd4bSMatt Macy threadexit_to_json(struct pmclog_ev *ev)
324f992dd4bSMatt Macy {
325f992dd4bSMatt Macy 	char eventbuf[256];
326f992dd4bSMatt Macy 	string startent;
327f992dd4bSMatt Macy 
328f992dd4bSMatt Macy 	startent = startentry(ev);
329f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"tid\": \"%d\"}\n",
330f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_te.pl_tid);
331f992dd4bSMatt Macy 	return string(eventbuf);
332f992dd4bSMatt Macy }
333f992dd4bSMatt Macy 
334f992dd4bSMatt Macy static string
335f992dd4bSMatt Macy stub_to_json(struct pmclog_ev *ev)
336f992dd4bSMatt Macy {
337f992dd4bSMatt Macy 	string startent;
338f992dd4bSMatt Macy 
339f992dd4bSMatt Macy 	startent = startentry(ev);
340f992dd4bSMatt Macy 	startent += string("}\n");
341f992dd4bSMatt Macy 	return startent;
342f992dd4bSMatt Macy }
343f992dd4bSMatt Macy 
344f992dd4bSMatt Macy typedef string (*jconv) (struct pmclog_ev*);
345f992dd4bSMatt Macy 
346f992dd4bSMatt Macy static jconv jsonconvert[] = {
347f992dd4bSMatt Macy 	NULL,
348f992dd4bSMatt Macy 	stub_to_json,
349f992dd4bSMatt Macy 	stub_to_json,
350f992dd4bSMatt Macy 	initialize_to_json,
351f992dd4bSMatt Macy 	NULL,
352f992dd4bSMatt Macy 	pmcallocate_to_json,
353f992dd4bSMatt Macy 	pmcattach_to_json,
354f992dd4bSMatt Macy 	pmcdetach_to_json,
355f992dd4bSMatt Macy 	proccsw_to_json,
356f992dd4bSMatt Macy 	procexec_to_json,
357f992dd4bSMatt Macy 	procexit_to_json,
358f992dd4bSMatt Macy 	procfork_to_json,
359f992dd4bSMatt Macy 	sysexit_to_json,
360f992dd4bSMatt Macy 	userdata_to_json,
361f992dd4bSMatt Macy 	map_in_to_json,
362f992dd4bSMatt Macy 	map_out_to_json,
363f992dd4bSMatt Macy 	callchain_to_json,
364f992dd4bSMatt Macy 	pmcallocatedyn_to_json,
365f992dd4bSMatt Macy 	threadcreate_to_json,
366f992dd4bSMatt Macy 	threadexit_to_json,
367f992dd4bSMatt Macy 	proccreate_to_json,
368f992dd4bSMatt Macy };
369f992dd4bSMatt Macy 
370f992dd4bSMatt Macy string
371f992dd4bSMatt Macy event_to_json(struct pmclog_ev *ev){
372f992dd4bSMatt Macy 
373f992dd4bSMatt Macy 	switch (ev->pl_type) {
374f992dd4bSMatt Macy 	case PMCLOG_TYPE_DROPNOTIFY:
375f992dd4bSMatt Macy 	case PMCLOG_TYPE_CLOSELOG:
376f992dd4bSMatt Macy 	case PMCLOG_TYPE_INITIALIZE:
377f992dd4bSMatt Macy 	case PMCLOG_TYPE_PMCALLOCATE:
378f992dd4bSMatt Macy 	case PMCLOG_TYPE_PMCATTACH:
379f992dd4bSMatt Macy 	case PMCLOG_TYPE_PMCDETACH:
380f992dd4bSMatt Macy 	case PMCLOG_TYPE_PROCCSW:
381f992dd4bSMatt Macy 	case PMCLOG_TYPE_PROCEXEC:
382f992dd4bSMatt Macy 	case PMCLOG_TYPE_PROCEXIT:
383f992dd4bSMatt Macy 	case PMCLOG_TYPE_PROCFORK:
384f992dd4bSMatt Macy 	case PMCLOG_TYPE_SYSEXIT:
385f992dd4bSMatt Macy 	case PMCLOG_TYPE_USERDATA:
386f992dd4bSMatt Macy 	case PMCLOG_TYPE_MAP_IN:
387f992dd4bSMatt Macy 	case PMCLOG_TYPE_MAP_OUT:
388f992dd4bSMatt Macy 	case PMCLOG_TYPE_CALLCHAIN:
389f992dd4bSMatt Macy 	case PMCLOG_TYPE_PMCALLOCATEDYN:
390f992dd4bSMatt Macy 	case PMCLOG_TYPE_THR_CREATE:
391f992dd4bSMatt Macy 	case PMCLOG_TYPE_THR_EXIT:
392f992dd4bSMatt Macy 	case PMCLOG_TYPE_PROC_CREATE:
393f992dd4bSMatt Macy 		return jsonconvert[ev->pl_type](ev);
394f992dd4bSMatt Macy 	default:
395f992dd4bSMatt Macy 		errx(EX_USAGE, "ERROR: unrecognized event type: %d\n", ev->pl_type);
396f992dd4bSMatt Macy 	}
397f992dd4bSMatt Macy }
398f992dd4bSMatt Macy 
399