A debugging and profiling tool that can trace and visualize python code execution
Project description
VizTracer
VizTracer is a deterministic debugging/profiling tool that can trace and visualize python code. The major data VizTracer displays is FEE(function entry/exit), or equivalently, the call stack.
Unlike traditional flamegraph, which is normally generated by sampling profiler, VizTracer can display every function executed and the corresponding entry/exit time from the beginning of the program to the end, which is helpful for programmers to catch sporatic performance issues. However, VizTracer is also capable of generating traditional flamegraph which is a good summary of the execution of the program
With VizTracer, the programmer can intuitively understand what their code is doing and how long each function takes.
You can take a look at the demo result of multiple example programs
trace viewer is used to display the stand alone html data.
VizTracer also supports json output that complies with Chrome trace event format, which can be loaded using perfetto
VizTracer generates HTML report for flamegraph using d3-flamegraph
Requirements
VizTracer requires python 3.6+. No other package is needed. For now, VizTracer only supports CPython + Linux/MacOS.
Install
The prefered way to install VizTracer is via pip
pip install viztracer
You can also download the source code and build it yourself.
Usage
There are a couple ways to use VizTracer
Command Line
The easiest way to use VizTracer is through command line. Assume you have a python script to profile and the normal way to run it is:
python3 my_script.py
You can simply use VizTracer as
python3 -m viztracer my_script.py
which will generate a result.html
file in the directory you run this command. Open it in browser and there's your result.
If your script needs arguments like
python3 my_script.py arg1 arg2
Just feed it as it is to VizTracer
python3 -m viztracer my_script.py arg1 arg2
You can also specify the tracer to be used in command line by passing --tracer argument. c tracer is the default value, you can use python tracer(deprecated) instead
python3 -m viztracer --tracer c my_script.py
python3 -m viztracer --tracer python my_script.py
You can specify the output file using -o or --output_file argument. The default output file is result.html. Two types of files are supported, html and json.
python3 -m viztracer -o other_name.html my_script.py
python3 -m viztracer -o other_name.json my_script.py
By default, VizTracer only generates trace file, either in HTML format or json. You can have VizTracer to generate a flamegraph as well by
python3 -m viztracer --save_flamegraph my_script.py
Inline
Sometimes the command line may not work as you expected, or you do not want to profile the whole script. You can manually start/stop the profiling in your script as well.
First of all, you need to import VizTracer
class from the package, and make an object of it.
from viztracer import VizTracer
tracer = VizTracer()
If your code is executable by exec
function, you can simply call tracer.run()
tracer.run("import random;random.randrange(10)")
This will as well generate a result.html
file in your current directory. You can pass other file path to the function if you do not like the name result.html
tracer.run("import random; random.randrange(10)", output_file="better_name.html")
When you need a more delicate profiler, you can manually enable/disable the profile using start()
and stop()
function.
tracer.start()
# Something happens here
tracer.stop()
tracer.save() # also takes output_file as an optional argument
Or, you can do it with with
statement
with VizTracer(output_file="optional.html") as tracer:
# Something happens here
You can record only the part that you are interested in
# Some code that I don't care
tracer.start()
# Some code I do care
tracer.stop()
# Some code that I want to skip
tracer.start()
# Important code again
tracer.stop()
tracer.save()
It is higly recommended that start()
and stop()
function should be in the same frame(same level on call stack). Problem might happen if the condition is not met
Display Result
By default, VizTracer will generate a stand alone HTML file which you can simply open with Chrome(maybe Firefox?). The front-end uses trace-viewer to show all the data.
However, you can generate json file as well, which complies to the chrome trace event format. You can load the json file on perfetto, which will replace the deprecated trace viewer in the future.
At the moment, perfetto does not support locally stand alone HTML file generation, so I'm not able to switch completely to it. The good news is that once you load the perfetto page, you can use it even when you are offline.
Trace Filter
Sometimes your code is really complicated or you need to run you program for a long time, which means the parsing time would be too long and the HTML/JSON file would be too large. There are ways in VizTracer to filter out the data you don't need.
The filter mechanism only works in C tracer, and it works at tracing time, not parsing time. That means, using filters will introduce some extra overhead while your tracing, but will save significant memory, parsing time and disk space.
Currently we support the following kinds of filters:
max_stack_depth
max_stack_depth
is a straight forward way to filter your data. It limits the stack depth VizTracer will trace, which cuts out deep call stacks, including some nasty recursive calls.
You can specify max_stack_depth
in command line:
python3 -m viztracer --max_stack_depth 10 my_script.py
Or you can pass it as an argument to the VizTracer
object:
from viztracer import VizTracer
tracer = VizTracer(max_stack_depth=10)
include_files and exclude_files
There are cases when you are only interested in functions in certain files. You can use include_files
and exclude_files
feature to filter out data you are not insterested in.
When you are using include_files
, only the files and directories you specify are recorded. Similarly, when you are using exclude_files
, files and directories you specify will not be recorded.
IMPORTANT: include_files
and exclude_files
can't be both spcified. You can only use one of them.
If a function is not recorded based on include_files
or exclude_files
rules, none of its descendent functions will be recorded, even if they match the rules
You can specify include_files
and exclude_files
in command line, but they can take more than one argument, which will make the following command ambiguous:
# Ambiguous command which should NOT be used
python3 -m viztracer --include_files ./src my_script.py
Instead, when you are using --include_files
or --exclude_files
, --run
should be passed for the command that you actually want to execute:
# --run is used to solve ambiguity
python3 -m viztracer --include_files ./src --run my_script.py
However, if you have some other commands that can separate them and solve ambiguity, that works as well:
# This will work too
python3 -m viztracer --include_files ./src --max_stack_depth 5 my_script.py
You can also pass a list
as an argument to VizTracer
:
from viztracer import VizTracer
tracer = VizTracer(include_files=["./src", "./test/test1.py"])
ignore_c_function
By default, VizTracer
will record all the C functions called by python script. You can turn it off by:
python3 -m viztracer --ignore_c_function my_script.py
You can turn it off in your script as well:
tracer = VizTracer(ignore_c_function=True)
ignore_function
Unlike ignore_c_function
, ignore_function
is a decorator which you can apply to any function to skip tracing it and its descendants.
from viztracer import ignore_function
@ignore_function
def some_function():
# nothing inside will be traced
Choose Tracer
The default tracer for current version is c tracer, which introduces a relatively small overhead(worst case 2-3x) but only works for CPython on Linux. However, if there's other reason that you would prefer a pure-python tracer, you can use python tracer using tracer
argument when you initialize VizTracer
object.
tracer = VizTracer(tracer="python")
python tracer will be deprecated because of the performance issue in the future No filter feature is supported with python tracer
Cleanup of c Tracer
The interface for c trace is almost exactly the same as python tracer. However, to achieve lower overhead, some optimization is applied to c tracer so it will withhold the memory it allocates for future use to reduce the time it calls malloc()
. If you want the c trace to free all the memory it allocates while collecting trace, use
tracer.cleanup()
Add Custom Event
VizTracer
supports custom event added while the program is running. This works like a print debug, but you can know when this print happens while looking at trace data.
When your code is running with VizTracer
on, you can use
tracer.add_instant(name, args, scope)
to add an event that will be shown in the report. In trace viewer, you would be able to see what args
is.
name
should be a string
for this event.
args
should be a json serializable object(dict, list, string, number).
scope
is an optional argument, default is "g"
for global. You can use p
for process or t
for thread. This affects how long the event shows in the final report.
Log Print
VizTracer
can log your print to the report using instant events. In this way, you can simply add print
functions in your code just like you are doing print debug and see what happens on the timeline.
You can specify --log_print
on the command line
python -m viztracer --log_print my_script.py
Or do it when you initialize your VizTracer
object
tracer = VizTracer(log_print=True)
Multi Thread Support
VizTracer
supports python native threading
module without the need to do any modification to your code. Just start VizTracer
before you create threads and it will just work.
Performance
Overhead is a big consideration when people choose profilers. VizTracer now has a similar overhead as native cProfiler. It works slightly worse in the worst case(Pure FEE) and better in easier case because even though it collects some extra information than cProfiler, the structure is lighter.
Admittedly, VizTracer is only focusing on FEE now, so cProfiler also gets other information that VizTracer does not acquire.
An example run for test_performance with Python 3.8 / Ubuntu 18.04.4 on Github VM
fib (10336, 10336): 0.000852800 vs 0.013735200(16.11)[py] vs 0.001585900(1.86)[c] vs 0.001628400(1.91)[cProfile]
hanoi (8192, 8192): 0.000621400 vs 0.012924899(20.80)[py] vs 0.001801800(2.90)[c] vs 0.001292900(2.08)[cProfile]
qsort (10586, 10676): 0.003457500 vs 0.042572898(12.31)[py] vs 0.005594100(1.62)[c] vs 0.007573200(2.19)[cProfile]
slow_fib (1508, 1508): 0.033606299 vs 0.038840998(1.16)[py] vs 0.033270399(0.99)[c] vs 0.032577599(0.97)[cProfile]
Limitations
VizTracer uses sys.setprofile()
for its profiler capabilities, so it will conflict with other profiling tools which also use this function. Be aware of it when using VizTracer.
Bugs/Requirements
Please send bug reports and feature requirements through github issue tracker. VizTracer is currently under development now and it's open to any constructive suggestions.
License
Copyright Tian Gao, 2020.
Distributed under the terms of the Apache 2.0 license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
File details
Details for the file viztracer-0.2.3.tar.gz
.
File metadata
- Download URL: viztracer-0.2.3.tar.gz
- Upload date:
- Size: 662.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 15684fd2c815e7063984dc3dd72896870aff123dd2750ebebfee45f4821fc605 |
|
MD5 | c4097da92a30acc70563b1f6df5fb3bb |
|
BLAKE2b-256 | 2fc2804b41db6c47dc7ea5c549a56f52ce99bcb9fd4ed296a499faae15e8c5f8 |
File details
Details for the file viztracer-0.2.3-cp38-cp38-manylinux2010_x86_64.whl
.
File metadata
- Download URL: viztracer-0.2.3-cp38-cp38-manylinux2010_x86_64.whl
- Upload date:
- Size: 690.4 kB
- Tags: CPython 3.8, manylinux: glibc 2.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 46a84680847372165c5fff4bc89721cd588c3388f81a60e9ac5391f2e82b650f |
|
MD5 | f2b5acd5246ff499ae38a178692ec585 |
|
BLAKE2b-256 | e03cde3cb54f4f215d981347c03d58d369f6b92fbdacfbcb7a88263736911d73 |
File details
Details for the file viztracer-0.2.3-cp38-cp38-manylinux1_x86_64.whl
.
File metadata
- Download URL: viztracer-0.2.3-cp38-cp38-manylinux1_x86_64.whl
- Upload date:
- Size: 690.4 kB
- Tags: CPython 3.8
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6a898b22cc972b19a08d65f88e251486d3866a9a6a362f36dfb3103729b8e52e |
|
MD5 | 3954de418d43dbbe28c1c317f949d5a8 |
|
BLAKE2b-256 | c5c578f9d7ababb897f7798dffcd219ee100e444bec7f62ce9c688cf48d56efd |
File details
Details for the file viztracer-0.2.3-cp38-cp38-macosx_10_14_x86_64.whl
.
File metadata
- Download URL: viztracer-0.2.3-cp38-cp38-macosx_10_14_x86_64.whl
- Upload date:
- Size: 664.2 kB
- Tags: CPython 3.8, macOS 10.14+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | debeaaa7536072e798624878f7aae2fdd4870d0b6f0022d40f38e881617acbd6 |
|
MD5 | 39f3da7cc47d19bf1cb3b06e7d9d0a70 |
|
BLAKE2b-256 | 58d142db3cb035c66259d920f267cb52cc564dcb6362df2ce44dc24a66a4185e |
File details
Details for the file viztracer-0.2.3-cp37-cp37m-manylinux2010_x86_64.whl
.
File metadata
- Download URL: viztracer-0.2.3-cp37-cp37m-manylinux2010_x86_64.whl
- Upload date:
- Size: 688.6 kB
- Tags: CPython 3.7m, manylinux: glibc 2.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 617a3deb77b5441eebf87353edf5d7e4f305e2476ac590f0bb04d9f676cb06bc |
|
MD5 | c3486e67a4251d314027847094f86907 |
|
BLAKE2b-256 | be5a79f16b1c6129f800c13c90a2981fbbbe95de2be4aa89e2654e36e73e6b72 |
File details
Details for the file viztracer-0.2.3-cp37-cp37m-manylinux1_x86_64.whl
.
File metadata
- Download URL: viztracer-0.2.3-cp37-cp37m-manylinux1_x86_64.whl
- Upload date:
- Size: 688.6 kB
- Tags: CPython 3.7m
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 21d66db7c7d285fe75e1f67e3de13119ba01e8252ca7fbfdb2f6ff1d9bbe9241 |
|
MD5 | 2542e4aa69f248078109913af1c3762d |
|
BLAKE2b-256 | 04f26fde8fa78cc9eefef7c04acb44084b5f9d5f656cf389ef49ee05b7fcb5a4 |
File details
Details for the file viztracer-0.2.3-cp37-cp37m-macosx_10_14_x86_64.whl
.
File metadata
- Download URL: viztracer-0.2.3-cp37-cp37m-macosx_10_14_x86_64.whl
- Upload date:
- Size: 664.2 kB
- Tags: CPython 3.7m, macOS 10.14+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.7.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9c65ca4fc3a774aa78a182b1a311f8eac6ea24cdc421e31e2182a0a87595ca56 |
|
MD5 | aa52a8d37bfe5f20f38e11ab8a28050b |
|
BLAKE2b-256 | 642aacc9d4e2580797ead5099f38f502a5e7b66ab2af446e169134f79bd883e7 |
File details
Details for the file viztracer-0.2.3-cp36-cp36m-manylinux2010_x86_64.whl
.
File metadata
- Download URL: viztracer-0.2.3-cp36-cp36m-manylinux2010_x86_64.whl
- Upload date:
- Size: 687.7 kB
- Tags: CPython 3.6m, manylinux: glibc 2.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9b8b7d7f6dc5b5b5c2c34001a594d68347ff9bff8be9af2dcd31ce52cb7ad82c |
|
MD5 | 534bc352bd47eaf398059f0e2ee83500 |
|
BLAKE2b-256 | c4f3b024753c35376d15b19eb564b76998c0dadc9c112ea9fc3cc8d3db3ca69a |
File details
Details for the file viztracer-0.2.3-cp36-cp36m-manylinux1_x86_64.whl
.
File metadata
- Download URL: viztracer-0.2.3-cp36-cp36m-manylinux1_x86_64.whl
- Upload date:
- Size: 687.7 kB
- Tags: CPython 3.6m
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c12f3a6f3eb04c0ca94b717f4d141449b8aec26b76a06bd5415fe8c671b92aa2 |
|
MD5 | 1e1039387cc8484e6e79dfd3ba092526 |
|
BLAKE2b-256 | d9885dbfce8153d9554a35f6ba49c95f58af648faed0a9921ba53ad4fa1dbfb0 |
File details
Details for the file viztracer-0.2.3-cp36-cp36m-macosx_10_14_x86_64.whl
.
File metadata
- Download URL: viztracer-0.2.3-cp36-cp36m-macosx_10_14_x86_64.whl
- Upload date:
- Size: 664.2 kB
- Tags: CPython 3.6m, macOS 10.14+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/40.6.2 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.6.11
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7c053ec65803873dd4d6688bc0e1361ce7e0c15fd591fe83a94706128691b047 |
|
MD5 | 7f3d67e1a4c5354395e43e37d8dc68db |
|
BLAKE2b-256 | 8f618325be718dfeae7affadd6c94a42b7d6669c1f5c6a4619afa9175a682ff5 |