[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