All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
To: linux-trace-devel@vger.kernel.org
Cc: "Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
Subject: [PATCH 1/2] trace-cruncher: Add generic methods for printing
Date: Thu, 29 Jul 2021 16:22:55 +0300	[thread overview]
Message-ID: <20210729132256.86569-1-y.karadz@gmail.com> (raw)

The new methods makes it easy to print:
 - the name and PID of the process that generated the trace record,
 - the unique fields of the record (called also 'info') or
 - all information for the event all together.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 examples/kprobe_open.py |   8 +-
 src/ftracepy-utils.c    | 159 ++++++++++++++++++++++++++++++++++++++++
 src/ftracepy-utils.h    |   9 +++
 src/ftracepy.c          |  15 ++++
 4 files changed, 186 insertions(+), 5 deletions(-)

diff --git a/examples/kprobe_open.py b/examples/kprobe_open.py
index f8d4d8b..5b217d3 100755
--- a/examples/kprobe_open.py
+++ b/examples/kprobe_open.py
@@ -26,12 +26,10 @@ open_probe.add_ptr_arg(name='mode',
 
 open_probe.register()
 
+tep = tc.local_tep()
+
 def callback(event, record):
-    if event.id() == open_probe.id():
-        file_name = event.parse_record_field(record=record, field='file')
-        flags = event.parse_record_field(record, 'flags')
-        mode = event.parse_record_field(record, 'mode')
-        print('file: {0}  (flags: {1}; mode: {2})'.format(file_name, hex(flags), hex(mode)))
+    print(tep.info(event, record))
 
 
 if __name__ == "__main__":
diff --git a/src/ftracepy-utils.c b/src/ftracepy-utils.c
index 6739db7..3c000a7 100644
--- a/src/ftracepy-utils.c
+++ b/src/ftracepy-utils.c
@@ -298,6 +298,162 @@ PyObject *PyTep_get_event(PyTep *self, PyObject *args,
 	return PyTepEvent_New(event);
 }
 
+static struct trace_seq seq;
+
+static bool init_print_seq(void)
+{
+	if (!seq.buffer)
+		trace_seq_init(&seq);
+
+	if (!seq.buffer) {
+		PyErr_SetString(TFS_ERROR, "Unable to initialize 'trace_seq'.");
+		return false;
+	}
+
+	trace_seq_reset(&seq);
+
+	return true;
+}
+
+static char *get_comm_from_pid(int pid)
+{
+	char *comm_file, *comm = NULL;
+	char buff[PATH_MAX];
+	int fd, r;
+
+	if (asprintf(&comm_file, "/proc/%i/comm", pid) <= 0) {
+		MEM_ERROR;
+		return NULL;
+	}
+
+	/*
+	 * This file is not guaranteed to exist. Return NULL if the process
+	 * is no longer active.
+	 */
+	fd = open(comm_file, O_RDONLY);
+	free(comm_file);
+	if (fd < 0)
+		return NULL;
+
+	r = read(fd, buff, PATH_MAX);
+	close(fd);
+	if (r <= 0)
+		return NULL;
+
+	comm = strdup(buff);
+	if (!comm)
+		MEM_ERROR;
+
+	return comm;
+}
+
+static void print_comm_pid(struct tep_handle *tep,
+			   struct trace_seq *seq,
+			   struct tep_record *record,
+			   struct tep_event *event)
+{
+	int pid = get_pid(event, record);
+	if (!tep_is_pid_registered(tep, pid)) {
+		char *comm = get_comm_from_pid(pid);
+		if (comm) {
+			tep_register_comm(tep, comm, pid);
+			free(comm);
+		}
+	}
+
+	tep_print_event(tep, seq, record, "%s-%i",
+			TEP_PRINT_COMM,
+			TEP_PRINT_PID);
+}
+
+static void print_name_info(struct tep_handle *tep,
+			    struct trace_seq *seq,
+			    struct tep_record *record,
+			    struct tep_event *event)
+{
+	trace_seq_printf(seq, " %s: ", event->name);
+	tep_print_event(tep, seq, record, "%s", TEP_PRINT_INFO);
+}
+
+static void print_event(struct tep_handle *tep,
+			struct trace_seq *seq,
+			struct tep_record *record,
+			struct tep_event *event)
+{
+	tep_print_event(tep, seq, record, "%6.1000d ", TEP_PRINT_TIME);
+	print_comm_pid(tep, seq, record, event);
+	tep_print_event(tep, seq, record, " cpu=%i ", TEP_PRINT_CPU);
+	print_name_info(tep, seq, record, event);
+}
+
+static bool print_init(PyObject *args, PyObject *kwargs,
+		       struct tep_event **event,
+		       struct tep_record **record)
+{
+	static char *kwlist[] = { "event", "record", NULL};
+	PyTepRecord *py_record;
+	PyTepEvent *py_event;
+
+	if (!init_print_seq())
+		return false;
+
+	if(!PyArg_ParseTupleAndKeywords(args,
+					kwargs,
+					"OO",
+					kwlist,
+					&py_event,
+					&py_record)) {
+		return false;
+	}
+
+	*event = py_event->ptrObj;
+	*record = py_record->ptrObj;
+
+	return true;
+}
+
+PyObject *PyTep_event_record(PyTep *self, PyObject *args,
+					  PyObject *kwargs)
+{
+	struct tep_record *record;
+	struct tep_event *event;
+
+	if (!print_init(args, kwargs, &event, &record))
+		return NULL;
+
+	print_event(self->ptrObj, &seq, record, event);
+
+	return PyUnicode_FromString(seq.buffer);
+}
+
+PyObject *PyTep_info(PyTep *self, PyObject *args,
+				  PyObject *kwargs)
+{
+	struct tep_record *record;
+	struct tep_event *event;
+
+	if (!print_init(args, kwargs, &event, &record))
+		return NULL;
+
+	print_name_info(self->ptrObj, &seq, record, event);
+
+	return PyUnicode_FromString(seq.buffer);
+}
+
+PyObject *PyTep_process(PyTep *self, PyObject *args,
+				     PyObject *kwargs)
+{
+	struct tep_record *record;
+	struct tep_event *event;
+
+	if (!print_init(args, kwargs, &event, &record))
+		return NULL;
+
+	print_comm_pid(self->ptrObj, &seq, record, event);
+
+	return PyUnicode_FromString(seq.buffer);
+}
+
 static bool check_file(struct tracefs_instance *instance, const char *file)
 {
 	if (!tracefs_file_exists(instance, file)) {
@@ -2222,4 +2378,7 @@ void PyFtrace_at_exit(void)
 {
 	destroy_all_kprobes();
 	destroy_all_instances();
+
+	if (seq.buffer)
+		trace_seq_destroy(&seq);
 }
diff --git a/src/ftracepy-utils.h b/src/ftracepy-utils.h
index 5d7c19c..aca1ccc 100644
--- a/src/ftracepy-utils.h
+++ b/src/ftracepy-utils.h
@@ -44,6 +44,15 @@ PyObject *PyTep_init_local(PyTep *self, PyObject *args,
 PyObject *PyTep_get_event(PyTep *self, PyObject *args,
 				       PyObject *kwargs);
 
+PyObject *PyTep_event_record(PyTep *self, PyObject *args,
+					  PyObject *kwargs);
+
+PyObject *PyTep_info(PyTep *self, PyObject *args,
+				  PyObject *kwargs);
+
+PyObject *PyTep_process(PyTep *self, PyObject *args,
+				     PyObject *kwargs);
+
 PyObject *PyFtrace_dir(PyObject *self);
 
 PyObject *PyFtrace_create_instance(PyObject *self, PyObject *args,
diff --git a/src/ftracepy.c b/src/ftracepy.c
index e3fec7b..e948b15 100644
--- a/src/ftracepy.c
+++ b/src/ftracepy.c
@@ -68,6 +68,21 @@ static PyMethodDef PyTep_methods[] = {
 	 METH_VARARGS | METH_KEYWORDS,
 	 "Get a PyTepEvent object."
 	},
+	{"event_record",
+	 (PyCFunction) PyTep_event_record,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Generic print of a trace event."
+	},
+	{"process",
+	 (PyCFunction) PyTep_process,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Generic print of the process that generated the trace event."
+	},
+	{"info",
+	 (PyCFunction) PyTep_info,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Generic print of a trace event info."
+	},
 	{NULL}
 };
 
-- 
2.30.2


             reply	other threads:[~2021-07-29 13:23 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-29 13:22 Yordan Karadzhov (VMware) [this message]
2021-07-29 13:22 ` [PATCH 2/2] trace-cruncher: Provide short info print Yordan Karadzhov (VMware)
2021-09-13 13:56 [PATCH 1/2] trace-cruncher: Add generic methods for printing Yordan Karadzhov (VMware)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210729132256.86569-1-y.karadz@gmail.com \
    --to=y.karadz@gmail.com \
    --cc=linux-trace-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.