Skip to main content

A debugging and profiling tool that can trace and visualize python code execution

Project description

VizTracer

build pypi license commit

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 an example program running recursive merge and quick sort algorithm.

example_img

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.

example_img

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

viztracer-0.2.2.tar.gz (661.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

viztracer-0.2.2-cp38-cp38-manylinux2010_x86_64.whl (689.3 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.12+ x86-64

viztracer-0.2.2-cp38-cp38-manylinux1_x86_64.whl (689.3 kB view details)

Uploaded CPython 3.8

viztracer-0.2.2-cp38-cp38-macosx_10_14_x86_64.whl (663.5 kB view details)

Uploaded CPython 3.8macOS 10.14+ x86-64

viztracer-0.2.2-cp37-cp37m-manylinux2010_x86_64.whl (687.7 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.12+ x86-64

viztracer-0.2.2-cp37-cp37m-manylinux1_x86_64.whl (687.7 kB view details)

Uploaded CPython 3.7m

viztracer-0.2.2-cp37-cp37m-macosx_10_14_x86_64.whl (663.5 kB view details)

Uploaded CPython 3.7mmacOS 10.14+ x86-64

viztracer-0.2.2-cp36-cp36m-manylinux2010_x86_64.whl (686.8 kB view details)

Uploaded CPython 3.6mmanylinux: glibc 2.12+ x86-64

viztracer-0.2.2-cp36-cp36m-manylinux1_x86_64.whl (686.8 kB view details)

Uploaded CPython 3.6m

viztracer-0.2.2-cp36-cp36m-macosx_10_14_x86_64.whl (663.5 kB view details)

Uploaded CPython 3.6mmacOS 10.14+ x86-64

File details

Details for the file viztracer-0.2.2.tar.gz.

File metadata

  • Download URL: viztracer-0.2.2.tar.gz
  • Upload date:
  • Size: 661.9 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

Hashes for viztracer-0.2.2.tar.gz
Algorithm Hash digest
SHA256 0532e33efba5a423eb91e9cc95b7a6512760dbec480be71459e960b337c75795
MD5 1881ed8356769d1884213a77137aff5a
BLAKE2b-256 baefab30821b45a3b2c175b248be487911d1753247877534981711802b93a07b

See more details on using hashes here.

File details

Details for the file viztracer-0.2.2-cp38-cp38-manylinux2010_x86_64.whl.

File metadata

  • Download URL: viztracer-0.2.2-cp38-cp38-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 689.3 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

Hashes for viztracer-0.2.2-cp38-cp38-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 8dc31790a3fdc9b4dc2e292aa7d50178c13c98771f2f1ce143c827ae9a8b6113
MD5 b9b207bf69d85b71a88b872ccc5b2f6a
BLAKE2b-256 ef5e9193dc72d27da633004c92fb864581c5a1df5b651e853b0db9d5ef0619e6

See more details on using hashes here.

File details

Details for the file viztracer-0.2.2-cp38-cp38-manylinux1_x86_64.whl.

File metadata

  • Download URL: viztracer-0.2.2-cp38-cp38-manylinux1_x86_64.whl
  • Upload date:
  • Size: 689.3 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

Hashes for viztracer-0.2.2-cp38-cp38-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 78507db6f41f3347ff2a6612766b546b796cb351e9582faaf412ea3945be6f1b
MD5 1f1637ba18eb32194eaf57d55d6af247
BLAKE2b-256 9d35b0d114d9c5af9d6a5e3b5786276068e2a22d141e69ff59a9066e8e1eb387

See more details on using hashes here.

File details

Details for the file viztracer-0.2.2-cp38-cp38-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: viztracer-0.2.2-cp38-cp38-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 663.5 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

Hashes for viztracer-0.2.2-cp38-cp38-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 e2caf646b3b0ae6a5d92e24817afc1692263da49a5c9378931474bf40dccebb8
MD5 88b41bc8f1db853cb0bb7e1101c27d9a
BLAKE2b-256 fe447f24f187573686d4c804023f2e2825771b5489062cb60ad71ec7db4b2919

See more details on using hashes here.

File details

Details for the file viztracer-0.2.2-cp37-cp37m-manylinux2010_x86_64.whl.

File metadata

  • Download URL: viztracer-0.2.2-cp37-cp37m-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 687.7 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

Hashes for viztracer-0.2.2-cp37-cp37m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 37e3009c4a88f056a17be448c97a88f113fefc2108d8a11748a901c86e36fc29
MD5 4dff27cd7891d06080827d3ea7d8021e
BLAKE2b-256 c25faab3e7307eb09e9faf3ceb15371ba57d9747faf358313810060c76bd5c97

See more details on using hashes here.

File details

Details for the file viztracer-0.2.2-cp37-cp37m-manylinux1_x86_64.whl.

File metadata

  • Download URL: viztracer-0.2.2-cp37-cp37m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 687.7 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

Hashes for viztracer-0.2.2-cp37-cp37m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 a249129f487dc6ddc021c469aa8d28f516717f0e06091137e4be0171f22aeee4
MD5 bb0402a2bc18b7f7f215f96d11685dd8
BLAKE2b-256 fe4f39606cd717d74966a7a31cd666262454577441684b4271d81fcd8aa0c25b

See more details on using hashes here.

File details

Details for the file viztracer-0.2.2-cp37-cp37m-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: viztracer-0.2.2-cp37-cp37m-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 663.5 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

Hashes for viztracer-0.2.2-cp37-cp37m-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 c9590399c71f4a279a9e1e731f6d9d25c399f7dc6b3a95f0f61ef2400c2c5934
MD5 e8a7728c3a289aa67c3a9b846405f7b5
BLAKE2b-256 8a0510acd8e2bc75f700e17d3a38b64309c66bd2b6799a4e7c6d112e674b6b96

See more details on using hashes here.

File details

Details for the file viztracer-0.2.2-cp36-cp36m-manylinux2010_x86_64.whl.

File metadata

  • Download URL: viztracer-0.2.2-cp36-cp36m-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 686.8 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

Hashes for viztracer-0.2.2-cp36-cp36m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 572ffe0e660736bfe02f16db01a640dec554faba4cd83f479ab700e02d96a8c1
MD5 f9be7f7e8d88b339269e7fa4087f8688
BLAKE2b-256 6dc1ec43c9f28d63be2a8074855f634f10889408b5aa6f69db109ed4d42f6655

See more details on using hashes here.

File details

Details for the file viztracer-0.2.2-cp36-cp36m-manylinux1_x86_64.whl.

File metadata

  • Download URL: viztracer-0.2.2-cp36-cp36m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 686.8 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

Hashes for viztracer-0.2.2-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 7610cf584b36ccc492a01f18c1ff3860741ea0f6260bfac52bd3f55d6f1cb97e
MD5 4e98a95cdb628cc5c5acf57b3fddd17b
BLAKE2b-256 d6b8dfcb83dcca94fb3aec14a0537518e3ea9f5061771b3cc5975a36d282befa

See more details on using hashes here.

File details

Details for the file viztracer-0.2.2-cp36-cp36m-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: viztracer-0.2.2-cp36-cp36m-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 663.5 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

Hashes for viztracer-0.2.2-cp36-cp36m-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 03632f1cd9d0af4b2646e000d442f1c8743648d328e07e87fe478084b649b92f
MD5 b4128edaf6ac342974ea820bec3f68dc
BLAKE2b-256 da827b577f5d25422947a2dea1b2b0790c9b802610b72e93a030f23af60d8741

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page