Skip to main content

Table of contents

Project description

Tracers is an Open-Source APM (Application monitoring) project that offers you minimal overhead wrappers for profiling your code execution flow

🛈  Finished transaction: 3.81 seconds

     # Timestamp                Net              Total    Call Chain

     1     0.00s     0.00s [  0.0%]     3.81s [100.0%]    ✓ async function_a
     2     0.00s     0.10s [  2.6%]     0.10s [  2.6%]    ¦   ✓ async asyncio.tasks.sleep
     3     0.10s     0.50s [ 13.1%]     0.50s [ 13.1%]    ¦   ✓ time.sleep
     4     0.60s     0.00s [  0.0%]     3.21s [ 84.2%]    ¦   ✓ async function_b
     5     0.60s     0.10s [  2.6%]     0.10s [  2.6%]    ¦   ¦   ✓ async asyncio.tasks.sleep
     6     0.70s     0.00s [  0.0%]     0.70s [ 18.4%]    ¦   ¦   ✓ async function_c
     7     0.70s     0.10s [  2.6%]     0.10s [  2.6%]    ¦   ¦   ¦   ✓ async asyncio.tasks.sleep
     8     0.80s     0.50s [ 13.1%]     0.50s [ 13.1%]    ¦   ¦   ¦   ✓ time.sleep
     9     1.31s     0.00s [  0.0%]     0.10s [  2.7%]    ¦   ¦   ¦   ✓ async function_d
    10     1.31s     0.10s [  2.6%]     0.10s [  2.6%]    ¦   ¦   ¦   ¦   ✓ async asyncio.tasks.sleep
    11     1.41s     2.00s [ 52.5%]     2.00s [ 52.5%]    ¦   ¦   ✓ time.sleep
    12     3.41s     0.10s [  2.7%]     0.10s [  2.7%]    ¦   ¦   ✓ async asyncio.tasks.sleep
    13     3.51s     0.00s [  0.0%]     0.10s [  2.7%]    ¦   ¦   ✓ async function_d
    14     3.51s     0.10s [  2.7%]     0.10s [  2.7%]    ¦   ¦   ¦   ✓ async asyncio.tasks.sleep
    15     3.61s     0.10s [  2.7%]     0.10s [  2.7%]    ¦   ¦   ✓ async asyncio.tasks.sleep
    16     3.71s     0.00s [  0.0%]     0.10s [  2.7%]    ¦   ¦   ✓ async function_e
    17     3.71s     0.10s [  2.7%]     0.10s [  2.7%]    ¦   ¦   ¦   ✓ async asyncio.tasks.sleep

           Count                Net              Total    Function

               3     3.00s [ 78.7%]     3.00s [ 78.7%]    ✓ time.sleep
               8     0.81s [ 21.2%]     0.81s [ 21.2%]    ✓ async asyncio.tasks.sleep
               1     0.00s [  0.0%]     3.21s [ 84.2%]    ✓ async function_b
               1     0.00s [  0.0%]     0.70s [ 18.4%]    ✓ async function_c
               1     0.00s [  0.0%]     3.81s [100.0%]    ✓ async function_a
               2     0.00s [  0.0%]     0.20s [  5.3%]    ✓ async function_d
               1     0.00s [  0.0%]     0.10s [  2.7%]    ✓ async function_e

  Some blocks (skews) occurred in the event loop ¹

  #    Timestamp     Delay

     0     1.40s     2.00s
     1     0.09s     0.50s
     2     0.80s     0.50s

  ¹ Consider reviewing them carefully to improve the overall system throughput

Key Features

  • Allows you to instrument any function or statement on your own code or any third party library
  • Handles asynchronous code out-of-the box, no config required
  • Exposes a high-level API:
    • A decorator: @trace, to instrument functions
      • Example:
        @trace
        def any_function(*args, **kwargs):
            pass
        
        @trace
        async def other_function(*args, **kwargs):
            pass
        
    • A function: call to instrument code in-line
      • Example:
        call(any_function, *args, **kwargs)
        await call(other_function, *args, **kwargs)
        
    • Sync/async cases are handled internally
    • call and @trace are equivalent, you can choose the one that fits you best
  • It's Thread-safe, Async-safe, Process-safe and Context-safe
    • You'll get accurate results in any scenario
  • Introduces minimal overhead and it's easy to deploy!
    • It's a pure python implementation based on contextvars and decorators. Your code runs as fast as if you were not profiling it
  • It's easy to pin-point performance problems:
    • Gives you the total execution time in seconds and %
    • Allows you to identify points in time where your async event loop got blocked
  • Made with love by nerds, for humans :heart:

Quick Introduction

Let's start with a very basic example:

import time
from dateutil.parser import parse


def example():
    time.sleep(2.0)
    your_business_logic('Sat Oct 11')


def your_business_logic(date: str):
    parse(date)
    time.sleep(1.0)


example()

Tracing its flow and gathering profiling information is a matter of decorating your functions:

--- a/examples/without_tracers.py
+++ b/examples/with_tracers.py
@@ -1,15 +1,18 @@
 import time
 from dateutil.parser import parse
+from tracers.function import trace


+@trace()
 def example():
     time.sleep(2.0)
     your_business_logic('Sat Oct 11')


+@trace()
 def your_business_logic(date: str):
     parse(date)
     time.sleep(1.0)


 example()

If you run it, all the functions you decorated will be traced and you'll have metrics of the execution flow:

🛈  Finished transaction: 3.00 seconds

     # Timestamp                Net              Total    Call Chain

     1     0.00s     2.00s [ 66.7%]     3.00s [100.0%]    ✓ example
     2     2.00s     1.00s [ 33.3%]     1.00s [ 33.3%]    ¦   ✓ your_business_logic

           Count                Net              Total    Function

               1     2.00s [ 66.7%]     3.00s [100.0%]    ✓ example
               1     1.00s [ 33.3%]     1.00s [ 33.3%]    ✓ your_business_logic

From the output you can conclude:

  • executing function example took a total of 3.0 seconds to complete
  • function example takes 66.7% of the execution time
  • function *example encloses 100% of your code time
  • function example called function: your_business_logic
  • function your_business_logic took 1.0 seconds out of the 3.0 seconds the function example needed to complete
  • function your_business_logic represents 33.3% of your execution time

Tracing code is not limited to your own code. You can trace any callable object including third party packages, Python's standard library, and almost anything

The level of detail is up to you!

--- a/examples/with_tracers.py
+++ b/examples/with_detailed_tracers.py
@@ -1,18 +1,18 @@
 import time
 from dateutil.parser import parse
-from tracers.function import trace
+from tracers.function import call, trace


 @trace()
 def example():
-    time.sleep(2.0)
+    call(time.sleep, 2.0)
     your_business_logic('Sat Oct 11')


 @trace()
 def your_business_logic(date: str):
-    parse(date)
-    time.sleep(1.0)
+    call(parse, date)
+    call(time.sleep, 1.0)


 example()

🛈  Finished transaction: 3.00 seconds

     # Timestamp                Net              Total    Call Chain

     1     0.00s     0.00s [  0.0%]     3.00s [100.0%]    ✓ example
     2     0.00s     2.00s [ 66.6%]     2.00s [ 66.6%]    ¦   ✓ time.sleep
     3     2.00s     0.00s [  0.0%]     1.00s [ 33.4%]    ¦   ✓ your_business_logic
     4     2.00s     0.00s [  0.0%]     0.00s [  0.0%]    ¦   ¦   ✓ dateutil.parser._parser.parse
     5     2.00s     1.00s [ 33.3%]     1.00s [ 33.3%]    ¦   ¦   ✓ time.sleep

           Count                Net              Total    Function

               2     3.00s [100.0%]     3.00s [100.0%]    ✓ time.sleep
               1     0.00s [  0.0%]     0.00s [  0.0%]    ✓ dateutil.parser._parser.parse
               1     0.00s [  0.0%]     1.00s [ 33.4%]    ✓ your_business_logic
               1     0.00s [  0.0%]     3.00s [100.0%]    ✓ example

Installation

We are hosted on PyPI: https://pypi.org/project/tracers

Just run: pip install tracers or use the package manager you like the most

Examples

Check them out in the examples folder

Metadata

Release files for tracers 21.8.6876

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tracers 21.8.6876
File Size Uploaded
tracers-21.8.6876.tar.gz 12.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tracers 21.8.6876
File Interpreter ABI Platform
tracers-21.8.6876-py3-none-any.whl Python 3 none any Details

Total release size: 24.3 kB

Release files / tracers-21.8.6876.tar.gz

Download URL tracers-21.8.6876.tar.gz
Size 12.3 kB
Tags Source
SHA-256 checksum
How to use checksums
4e63593715b13a9d8c9aa23b1f0d04f4696c6005544b4e40f335f9466f897cab
BLAKE2b-256 checksum
How to use checksums
dc0b63b60b15ba76dd93d2c286cc34324fbaf354e397bf3110a789eb507f1379
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.5 CPython/3.8.9 Linux/5.10.44

Release files / tracers-21.8.6876-py3-none-any.whl

Download URL tracers-21.8.6876-py3-none-any.whl
Size 12.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
162102069e463b12dc1991688a58a9def1790ba4029c3a72790ea54f73a14160
BLAKE2b-256 checksum
How to use checksums
4459632eefa787e2bcb59bb1ea5c1229e8d64e4672ef82e230ddf3afc1701fc3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.5 CPython/3.8.9 Linux/5.10.44

Release history Release notifications | RSS feed

This release

21.8.6876 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page