[lttng-dev] [lttng-ust PATCH] Python module

Danny Serres danny.serres at efficios.com
Fri Aug 10 13:42:35 EDT 2012


Proof of concept:
A simple library to create tracepoints and allow
tracing in Python programs.

To build, configure with Python:
  ./configure --with-python

To use, import the module in Python:
  import lttngust

Signed-off-by: Danny Serres <danny.serres at efficios.com>
---
 Makefile.am                     |    4 +
 README                          |    4 +
 configure.ac                    |   31 ++++++
 liblttng-ust-python/Makefile.am |   13 +++
 liblttng-ust-python/README      |    8 ++
 liblttng-ust-python/lttngust.c  |  198 +++++++++++++++++++++++++++++++++++++++
 liblttng-ust-python/lttngust.h  |  103 ++++++++++++++++++++
 7 files changed, 361 insertions(+)
 create mode 100644 liblttng-ust-python/Makefile.am
 create mode 100644 liblttng-ust-python/README
 create mode 100644 liblttng-ust-python/lttngust.c
 create mode 100644 liblttng-ust-python/lttngust.h

diff --git a/Makefile.am b/Makefile.am
index e61735d..d43aeab 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,6 +13,10 @@ if BUILD_JNI_INTERFACE
 SUBDIRS += liblttng-ust-java
 endif
 
+if USE_PYTHON
+SUBDIRS += liblttng-ust-python
+endif
+
 #temporarily disabled
 # liblttng-ust-malloc
 
diff --git a/README b/README
index 55c72df..c9a455d 100644
--- a/README
+++ b/README
@@ -170,3 +170,7 @@ PACKAGE CONTENTS:
   - liblttng-ust-java
     A simple library that uses JNI to allow tracing in java programs.
     See liblttng-ust-java/README for build instructions.
+
+  - liblttng-ust-python
+    A simple library to allow tracing in Python programs.
+    See liblttng-ust-python/README for build instructions.
diff --git a/configure.ac b/configure.ac
index 4d40f75..e85bd0d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -144,6 +144,33 @@ AC_CHECK_LIB([urcu-bp], [synchronize_rcu_bp], [], [AC_MSG_ERROR([Cannot find lib
 AC_CHECK_LIB([urcu-bp], [call_rcu_bp], [], [AC_MSG_ERROR([liburcu 0.6 or newer is needed, please update your version or use [LDFLAGS]=-Ldir to specify the right location.])])
 
 
+# For Python
+AC_ARG_WITH([python],
+              [AS_HELP_STRING([--with-python],
+                              [compile with Python bindings])],
+              [enable_python=yes], [enable_python=no])
+
+AM_CONDITIONAL([USE_PYTHON], [test "x${enable_python:-yes}" = xyes])
+
+if test "x${enable_python:-yes}" = xyes; then
+  AM_PATH_PYTHON
+
+  AC_ARG_VAR([PYTHON_INCLUDE], [Include flags for python, bypassing python-config])
+  AC_ARG_VAR([PYTHON_CONFIG], [Path to python-config])
+  AS_IF([test -z "$PYTHON_INCLUDE"], [
+    AS_IF([test -z "$PYTHON_CONFIG"], [
+      AC_PATH_PROGS([PYTHON_CONFIG],
+                    [python$PYTHON_VERSION-config python-config],
+                    [no],
+                    [`dirname $PYTHON`])
+      AS_IF([test "$PYTHON_CONFIG" = no], [AC_MSG_ERROR([cannot find python-config for $PYTHON.])])
+    ])
+    AC_MSG_CHECKING([python include flags])
+    PYTHON_INCLUDE=`$PYTHON_CONFIG --includes`
+    AC_MSG_RESULT([$PYTHON_INCLUDE])
+  ])
+fi
+
 # Check for various supplementary host information (beyond the
 # triplet) which might affect the library format choices.  E.g., we
 # can be building with `i686-unknown-linux-gnu-gcc -m64'
@@ -300,6 +327,7 @@ AC_CONFIG_FILES([
 	liblttng-ust-fork/Makefile
 	liblttng-ust-java/Makefile
 	liblttng-ust-libc-wrapper/Makefile
+	liblttng-ust-python/Makefile
 	tools/Makefile
 	tests/Makefile
 	tests/hello/Makefile
@@ -327,6 +355,9 @@ AS_ECHO()
 AS_ECHO_N("Java support (JNI): ")
 AS_IF([test "x$jni_interface" = "xyes"], [AS_ECHO("Enabled")], [AS_ECHO("Disabled")])
 
+AS_ECHO_N("Python support:     ")
+AS_IF([test "x$enable_python" = "xyes"], [AS_ECHO("Enabled")], [AS_ECHO("Disabled")])
+
 AS_ECHO_N("sdt.h integration:  ")
 AS_IF([test "x$with_sdt" = "xyes"], [AS_ECHO("Enabled")], [AS_ECHO("Disabled")])
 
diff --git a/liblttng-ust-python/Makefile.am b/liblttng-ust-python/Makefile.am
new file mode 100644
index 0000000..993e0b9
--- /dev/null
+++ b/liblttng-ust-python/Makefile.am
@@ -0,0 +1,13 @@
+AM_CFLAGS = -I$(PYTHON_INCLUDE) -I$(top_srcdir)/include/
+
+pyexec_LTLIBRARIES = lttngust.la
+
+MAINTAINERCLEANFILES = lttngust.c
+
+lttngust_la_SOURCES = lttngust.c
+
+lttngust_la_LDFLAGS = -module
+
+lttngust_la_CFLAGS = $(AM_CFLAGS)
+
+lttngust_la_LIBADD = -lc -L$(top_builddir)/liblttng-ust/.libs ../liblttng-ust/liblttng-ust.la
diff --git a/liblttng-ust-python/README b/liblttng-ust-python/README
new file mode 100644
index 0000000..405ef62
--- /dev/null
+++ b/liblttng-ust-python/README
@@ -0,0 +1,8 @@
+This directory contains a simple API for instrumenting Python applications.
+
+Configuration to build this library:
+
+	./configure --with-python
+
+After building, you can use the generated module in a
+Python project ('import lttngust').
diff --git a/liblttng-ust-python/lttngust.c b/liblttng-ust-python/lttngust.c
new file mode 100644
index 0000000..39ecb1d
--- /dev/null
+++ b/liblttng-ust-python/lttngust.c
@@ -0,0 +1,198 @@
+#define TRACEPOINT_DEFINE
+#define TRACEPOINT_CREATE_PROBES
+
+#include <Python.h>
+#include "lttngust.h"
+
+/* Tracepoint with int value */
+static PyObject *
+lttngust_tracepointInt(PyObject *self, PyObject *args)
+{
+	const char *name;
+	int val;
+
+	if (!PyArg_ParseTuple(args, "si", &name, &val))
+		return NULL;
+	tracepoint(lttngust_python, int_event, name, val);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* Tracepoint with long value */
+static PyObject *
+lttngust_tracepointLong(PyObject *self, PyObject *args)
+{
+	const char *name;
+	long val;
+
+	if (!PyArg_ParseTuple(args, "sl", &name, &val))
+		return NULL;
+	tracepoint(lttngust_python, long_event, name, val);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* Tracepoint with string value */
+static PyObject *
+lttngust_tracepointString(PyObject *self, PyObject *args)
+{
+	const char *name;
+	const char *val;
+
+	if (!PyArg_ParseTuple(args, "ss", &name, &val))
+		return NULL;
+	tracepoint(lttngust_python, string_event, name, val);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* Tracepoint with double value */
+static PyObject *
+lttngust_tracepointDouble(PyObject *self, PyObject *args)
+{
+	const char *name;
+	double val;
+
+	if (!PyArg_ParseTuple(args, "sd", &name, &val))
+		return NULL;
+	tracepoint(lttngust_python, double_event, name, val);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* Tracepoint with complex object value */
+static PyObject *
+lttngust_tracepointComplex(PyObject *self, PyObject *args)
+{
+	const char *name;
+	Py_complex complex;
+	char val[256];
+
+	if (!PyArg_ParseTuple(args, "sD", &name, &complex))
+		return NULL;
+	sprintf(val, "%g+%gj", complex.real, complex.imag);
+	tracepoint(lttngust_python, complex_event, name, val);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* Tracepoint with bool(object) value */
+static PyObject *
+lttngust_tracepointBool(PyObject *self, PyObject *args)
+{
+	const char *name;
+	PyObject *obj;
+	char *val;
+
+
+	if (!PyArg_ParseTuple(args, "sO", &name, &obj))
+		return NULL;
+
+	if (PyObject_IsTrue(obj))
+		val = "True";
+	else
+		val = "False";
+
+	tracepoint(lttngust_python, bool_event, name, val);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* Tracepoint with repr(object) value */
+static PyObject *
+lttngust_tracepointRepr(PyObject *self, PyObject *args)
+{
+	const char *name;
+	PyObject *obj;
+	const char *repr;
+
+	if (!PyArg_ParseTuple(args, "sO", &name, &obj))
+		return NULL;
+
+	repr = PyString_AsString(PyObject_Repr(obj));
+	tracepoint(lttngust_python, obj_repr, name, repr);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* Tracepoint with message, loglevel TRACE_INFO */
+static PyObject *
+lttngust_tracepointMessage(PyObject *self, PyObject *args)
+{
+	const char *text;
+
+	if (!PyArg_ParseTuple(args, "s", &text))
+		return NULL;
+	tracepoint(lttngust_python, message, text);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+/* Tracepoint with warning, loglevel TRACE_WARNING */
+static PyObject *
+lttngust_tracepointWarning(PyObject *self, PyObject *args)
+{
+	const char *text;
+
+	if (!PyArg_ParseTuple(args, "s", &text))
+		return NULL;
+	tracepoint(lttngust_python, warning, text);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+/* Definition of Python methods */
+static PyMethodDef UstMethods[] = {
+
+	{"tracepointInt",  lttngust_tracepointInt, METH_VARARGS,
+		"tracepointInt(name, value)\n\nTracepoint with Int value."},
+
+	{"tracepointLong",  lttngust_tracepointLong, METH_VARARGS,
+		"tracepointLong(name, value)\n\nTracepoint with Long value."},
+
+	{"tracepointDouble",  lttngust_tracepointDouble, METH_VARARGS,
+		"tracepointDouble(name, value)\n\n"
+		"Tracepoint with Double value."},
+
+	{"tracepointComplex",  lttngust_tracepointComplex, METH_VARARGS,
+		"tracepointComplex(name, complex_number)\n\n"
+		"Tracepoint with Complex number value."},
+
+	{"tracepointString",  lttngust_tracepointString, METH_VARARGS,
+		"tracepointString(name, value)\n\n"
+		"Tracepoint with String value."},
+
+	{"tracepointBool",  lttngust_tracepointBool, METH_VARARGS,
+		"tracepointBool(name, object)\n\n"
+		"Tracepoint with Object value, uses bool()."},
+
+	{"tracepointRepr",  lttngust_tracepointRepr, METH_VARARGS,
+		"tracepointRepr(name, object)\n\n"
+		"Tracepoint with Object value, uses repr()."},
+
+	{"tracepointMessage",  lttngust_tracepointMessage, METH_VARARGS,
+		"tracepointMessage(text)\n\nTracepoint with string info."},
+
+	{"tracepointWarning",  lttngust_tracepointWarning, METH_VARARGS,
+		"tracepointWarning(text)\n\nTracepoint with string warning."},
+
+	{NULL, NULL, 0, NULL}        /* Sentinel */
+};
+
+
+/* Init module */
+PyMODINIT_FUNC
+initlttngust(void)
+{
+	(void) Py_InitModule("lttngust", UstMethods);
+}
diff --git a/liblttng-ust-python/lttngust.h b/liblttng-ust-python/lttngust.h
new file mode 100644
index 0000000..f668ee1
--- /dev/null
+++ b/liblttng-ust-python/lttngust.h
@@ -0,0 +1,103 @@
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER lttngust_python
+
+#undef TRACEPOINT_INCLUDE_FILE
+#define TRACEPOINT_INCLUDE_FILE ./lttngust.h
+
+#ifdef __cplusplus
+extern "C"{
+#endif /* __cplusplus */
+
+#if !defined(_lttngust_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
+#define _lttngust_H
+
+#include <lttng/tracepoint.h>
+
+/* Tracepoint with int value */
+TRACEPOINT_EVENT(lttngust_python, int_event,
+	TP_ARGS(const char *, name, int, val),
+	TP_FIELDS(
+		ctf_string(name, name)
+		ctf_integer(int, value, val)
+	)
+)
+
+/* Tracepoint with long value */
+TRACEPOINT_EVENT(lttngust_python, long_event,
+	TP_ARGS(const char *, name, long, val),
+	TP_FIELDS(
+		ctf_string(name, name)
+		ctf_integer(int, value, val)
+	)
+)
+
+/* Tracepoint with string value */
+TRACEPOINT_EVENT(lttngust_python, string_event,
+	TP_ARGS(const char *, name, const char *, val),
+	TP_FIELDS(
+		ctf_string(name, name)
+		ctf_string(value, val)
+	)
+)
+
+/* Tracepoint with double value */
+TRACEPOINT_EVENT(lttngust_python, double_event,
+	TP_ARGS(const char *, name, double, val),
+	TP_FIELDS(
+		ctf_string(name, name)
+		ctf_float(double, value, val)
+	)
+)
+
+/* Tracepoint with complex object value */
+TRACEPOINT_EVENT(lttngust_python, complex_event,
+	TP_ARGS(const char *, name, char *, val),
+	TP_FIELDS(
+		ctf_string(name, name)
+		ctf_string(value, val)
+	)
+)
+
+/* Tracepoint with bool(object) value */
+TRACEPOINT_EVENT(lttngust_python, bool_event,
+	TP_ARGS(const char *, name, char *, val),
+	TP_FIELDS(
+		ctf_string(name, name)
+		ctf_string(value, val)
+	)
+)
+
+/* Tracepoint with repr(object) value */
+TRACEPOINT_EVENT(lttngust_python, obj_repr,
+	TP_ARGS(const char *, name, const char *, repr),
+	TP_FIELDS(
+		ctf_string(name, name)
+		ctf_string(repr, repr)
+	)
+)
+
+/* Tracepoint with message, loglevel TRACE_INFO */
+TRACEPOINT_EVENT(lttngust_python, message,
+	TP_ARGS(const char *, text),
+	TP_FIELDS(
+		ctf_string(message, text)
+	)
+)
+TRACEPOINT_LOGLEVEL(lttngust_python, message, TRACE_INFO)
+
+/* Tracepoint with warning, loglevel TRACE_WARNING */
+TRACEPOINT_EVENT(lttngust_python, warning,
+	TP_ARGS(const char *, text),
+	TP_FIELDS(
+		ctf_string(message, text)
+	)
+)
+TRACEPOINT_LOGLEVEL(lttngust_python, warning, TRACE_WARNING)
+
+#endif /* _lttngust_H */
+
+#include <lttng/tracepoint-event.h>
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
-- 
1.7.9.5




More information about the lttng-dev mailing list