Telemetry#

Added in version 0.1.2: Set the _PLOOMBER_TELEMETRY_DEBUG environment variable (any value) to override the PostHog key. Events will be logged to the “Debugging” project.

ploomber-core implements a Telemetry class that we use to understand usage and improve our products:

from ploomber_core.telemetry import Telemetry

Initialize it with the API key, name of the package, and version. Here’s an example:

Added in version 0.2.20: Telemetry.from_package

telemetry = Telemetry.from_package(package_name="ploomber-core")

Note

Telemetry.from_package is the simplest way to initialize the telemetry object, you might use the constructor directly if you want to customize the configuration.

To log call functions:

@telemetry.log_call()
def add(x, y):
    return x + y


add(1, 41)
Deploy Flask apps for free on Ploomber Cloud! Learn more: https://ploomber.io/s/signup
42

Log method calls:

class MyClass:
    @telemetry.log_call()
    def add(self, x, y):
        return x, y


obj = MyClass()
obj.add(x=1, y=2)
(1, 2)

Note

Event names are normalized by replacing underscores (_) with hyphens (-).

For more details, see the API Reference.

Unit testing#

To unit test decorated functions, call the function and check __wrapped__._telemetry_success attribute. If it exists, it means the function has been decorated with @log_call(), you can use it to verify what’s logged:

@telemetry.log_call(log_args=True, ignore_args=("y",))
def divide(x, y):
    return x / y


_ = divide(2, 4)
from unittest.mock import ANY

assert divide.__wrapped__._telemetry_success == {
    "action": "ploomber-core-divide-success",
    "total_runtime": ANY,
    "metadata": {
        "argv": ANY,
        "args": {"x": 2},
    },
}

__wrapped__._telemetry_success will keep the latest logged data, so you must call it at least one; otherwise, it’ll be None.

Configuring telemetry in a package#

Usually, our packages contains a src/{package-name}/_telemetry.py module that exposes a telemetry object with the key, package_name, and version already initialized. If there isn’t one, create it.

Then, you can add telemetry to any module by importing the telemetry object.

from some_package._telemetry import telemetry

@telemetry.log_call()
def some_function():
    pass