├── .gitignore ├── Makefile ├── README.md ├── probes.d ├── pystap.py ├── pytap.c └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/python 3 | 4 | ### Python ### 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | env/ 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | downloads/ 20 | eggs/ 21 | .eggs/ 22 | lib/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *,cover 50 | .hypothesis/ 51 | 52 | # Translations 53 | *.mo 54 | *.pot 55 | 56 | # Django stuff: 57 | *.log 58 | local_settings.py 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | docs/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # IPython Notebook 74 | .ipynb_checkpoints 75 | 76 | # pyenv 77 | .python-version 78 | 79 | # celery beat schedule file 80 | celerybeat-schedule 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv/ 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | 93 | # Rope project settings 94 | .ropeproject 95 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DTRACE=dtrace 2 | CFLAGS = -O2 -g -Wall -D_GNU_SOURCE -fPIC 3 | TARGET=libpystap.so 4 | CC = gcc 5 | 6 | all: lib 7 | $(CC) $(CFLAGS) -c -m64 -o pytap.o pytap.c 8 | $(CC) -shared -o $(TARGET) pytap.o probes.o 9 | 10 | lib: probes.h probes.o 11 | 12 | probes.h: probes.d 13 | $(DTRACE) -C -h -s $< -o $@ 14 | 15 | probes.o: probes.d 16 | $(DTRACE) -64 -C -G -s $< -o $@ 17 | 18 | clean: 19 | rm $(TARGET) probes.h probes.o pytap.o 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python binding for systemtap 2 | 3 | ## Build 4 | 5 | Only for **Centos** or other redhat alternatives. 6 | 7 | ``` 8 | sudo yum install systemtap systemtap-devel systemtap-sdt-devel 9 | make 10 | ``` 11 | 12 | ## Usage 13 | 14 | This library provide the following probe: 15 | 16 | ``` 17 | provider pystap { 18 | probe entry(char *, char *); 19 | }; 20 | ``` 21 | 22 | An easy decorator is implemented: 23 | 24 | ```python 25 | from pystap import dtrace_deco 26 | 27 | @dtrace_deco 28 | def its_a_test(a_para, that_para=None): 29 | print a_para, that_para 30 | ``` 31 | 32 | 33 | ## Example: 34 | 35 | Usage is shown in `test.py`, execute bash command like following: 36 | 37 | ```bash 38 | sudo stap -e 'probe process.library("/home/vagrant/github/python-systemtap/libpystap.so").mark("entry"){printf("%s - %s", user_string($arg1), user_string($arg2))}' -c "python test.py" 39 | ``` 40 | 41 | Note: You should manually give the location of `libpystap.so` to `stap`. 42 | 43 | -------------------------------------------------------------------------------- /probes.d: -------------------------------------------------------------------------------- 1 | provider pystap { 2 | probe entry(char *, char *); 3 | }; 4 | -------------------------------------------------------------------------------- /pystap.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import ctypes 4 | import functools 5 | 6 | pystap = ctypes.cdll.LoadLibrary('./libpystap.so') 7 | 8 | pystap.probe.argtypes = [ctypes.c_char_p, ctypes.c_char_p] 9 | pystap.probe.restype = ctypes.POINTER(ctypes.c_void_p) 10 | 11 | def dtrace_deco(func): 12 | @functools.wraps(func) 13 | def wrapper(*args, **kwds): 14 | pystap.probe(func.__name__, "%r, %r" % (args, kwds)) 15 | return func(*args, **kwds) 16 | return wrapper 17 | 18 | -------------------------------------------------------------------------------- /pytap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pytap.c 3 | * Copyright (C) 2016 WooParadog 4 | * 5 | * Distributed under terms of the MIT license. 6 | */ 7 | 8 | #include 9 | #include "probes.h" 10 | 11 | void probe(char* api_name, char* args){ 12 | DTRACE_PROBE2(pystap, entry, api_name, args); 13 | } 14 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pystap import dtrace_deco 5 | 6 | @dtrace_deco 7 | def its_a_test(a_para, that_para=None): 8 | print a_para, that_para 9 | 10 | if __name__ == '__main__': 11 | import time 12 | i = 0 13 | while 1: 14 | i += 1 15 | its_a_test(time.time(), that_para=i) 16 | time.sleep(1) 17 | --------------------------------------------------------------------------------