Skip to main content
Use the @trail decorator to audit any function in your codebase — not just framework calls.

Setup

from provenlog import trail

@trail(name="process_payment")
def process_payment(amount: float, currency: str):
    # Your code here
    return {"status": "completed", "transaction_id": "txn_123"}
When process_payment is called, ProvenLog automatically logs:
  • action_type — always CUSTOM
  • action_name — the name you provide (defaults to the function name)
  • action_input — the function arguments
  • action_output — the return value (wrapped as {"return": ...})
  • action_statussuccess or error (based on whether the function raises)
  • duration_ms — how long the function took

Parameters

@trail(
    client=None,                   # ProvenLogClient instance (uses default if omitted)
    name="process_payment",        # Action name (default: function.__name__)
    agent_id=None,                 # Override client's default agent_id
    metadata=None,                 # Extra metadata merged into each event
)

Error handling

If the decorated function raises an exception, ProvenLog logs the event with:
  • action_status set to "error"
  • error_message set to the exception string
The exception is then re-raised — ProvenLog never swallows errors.

Async support

The decorator works with both sync and async functions:
@trail(name="async_fetch")
async def fetch_data(url: str):
    # async code here
    return {"data": "..."}

Prerequisites

The @trail decorator requires a ProvenLogClient to be active. When using auto-instrumentation (plog run or import provenlog.auto), a client is created automatically and registered as the default. For explicit setup, create a client before calling any decorated functions:
from provenlog import ProvenLogClient, trail

client = ProvenLogClient(agent_id="my-agent")

@trail(name="my_action")
def my_action():
    return "done"

my_action()  # Logged via the active client
client.close()
You can also pass a client explicitly:
@trail(client=my_client, name="my_action")
def my_action():
    return "done"