The official Treblle SDK for Symfony. Seamlessly integrate Treblle to manage communication with your dashboard, send errors, and secure sensitive data.
Treblle with Symfony
Requirements
| Dependency | Version |
|---|---|
| PHP | 8.2, 8.3, 8.4 |
| Symfony | 6.4, 7.x, 8.x |
| ext-curl | any |
| ext-json | any |
| ext-zlib | any |
Note
Async mode (optional): requires symfony/messenger with a Redis or AMQP transport.
Installation
composer require treblle/treblle-symfonyTip
Symfony Flex users: the setup steps below happen automatically on install.
Setup
1. Register the bundle
Add the bundle to config/bundles.php:
return [
// ...
Treblle\Symfony\TreblleBundle::class => ['all' => true],
];2. Configure the SDK
Create config/packages/treblle.yaml:
treblle:
sdk_token: "%env(TREBLLE_SDK_TOKEN)%"
api_key: "%env(TREBLLE_API_KEY)%"3. Set your credentials
Add to your .env:
TREBLLE_SDK_TOKEN=your-sdk-token-from-treblle-dashboard
TREBLLE_API_KEY=your-api-key-from-treblle-dashboardBoth values are available in your Treblle Dashboard .
Configuration Reference
All options with their defaults:
treblle:
sdk_token: "" # Required - SDK Token from Treblle Dashboard
api_key: "" # Required - API Key from Treblle Dashboard
enabled: true # Set to false to disable Treblle (e.g. in dev/test)
async: false # Dispatch via Symfony Messenger (requires Redis or AMQP transport)
masked_keywords: # Fields to mask - set to [] to disable masking entirely
- password
- pwd
- secret
- password_confirmation
- passwordConfirmation
- cc
- card_number
- cardNumber
- ccv
- ssn
- credit_score
- creditScore
excluded_paths: [] # Paths to skip (exact or wildcard)
ingress_url: "https://ingress.treblle.com" # Ingress endpoint
metadata: {} # Key/Value metadata added to every requestsdk_token
Your SDK Token from the Treblle Dashboard. Sent as the x-api-key header on every request to the ingress.
api_key
Your project’s API Key from the Treblle Dashboard. Identifies which project this data belongs to.
enabled
Controls whether Treblle is active. Defaults to true. Set to false to disable in specific environments without removing your credentials.
The recommended approach is an environment-specific config file:
# config/packages/dev/treblle.yaml
treblle:
enabled: false# config/packages/test/treblle.yaml
treblle:
enabled: falseYou can also drive it from an environment variable:
treblle:
enabled: "%env(bool:TREBLLE_ENABLED)%"masked_keywords
The list of field names to mask in request bodies, response bodies, request headers, and response headers. Masking replaces each character of the value with *, preserving the original length, and is applied recursively to nested objects and arrays.
Adding fields to the default list:
treblle:
masked_keywords:
- password
- pwd
- secret
- password_confirmation
- passwordConfirmation
- cc
- card_number
- cardNumber
- ccv
- ssn
- credit_score
- creditScore
- authorization
- x-api-key
- access_tokenDisabling masking entirely:
treblle:
masked_keywords: []excluded_paths
Paths that should not be tracked by Treblle. Supports exact paths and wildcard patterns. Paths are matched against the request path without the leading /.
treblle:
excluded_paths:
- health # exact: /health
- health/check # exact: /health/check
- admin/* # wildcard: /admin/anything
- internal/* # wildcard: /internal/anythingingress_url
Override the default ingress endpoint. Useful for EU-hosted or self-hosted Treblle deployments:
treblle:
ingress_url: "https://ingress-eu.treblle.com"metadata
Key/Value metadata attached to every request. Useful for environment tags, region, tier, or any data you always want visible and searchable in Treblle.
treblle:
metadata:
env: production
region: us-east-1
tier: enterpriseTip
user-id is a reserved keyword. When present in metadata, Treblle uses it to enable Customer Tracking — linking requests to individual users so you can filter, search, and analyse traffic per customer in the dashboard.
async
When true, the SDK dispatches payloads as Symfony Messenger messages instead of sending them inline. This moves the HTTP call to a background worker, freeing your application immediately.
By default, the SDK sends data in the kernel.terminate event — after the HTTP response has already been delivered to your client. For most applications this is sufficient. Enable async: true if you run at high request volume or your hosting environment does not use PHP-FPM.
Setup:
- Install Symfony Messenger:
composer require symfony/messenger- Configure a transport in
config/packages/messenger.yaml:
Redis:
framework:
messenger:
transports:
treblle:
dsn: "%env(REDIS_URL)%"
options:
stream: treblle_payloads
routing:
'Treblle\Symfony\Messenger\SendTrebllePayload': treblleAMQP (RabbitMQ):
framework:
messenger:
transports:
treblle:
dsn: "%env(RABBITMQ_URL)%"
options:
exchange:
name: treblle
routing:
'Treblle\Symfony\Messenger\SendTrebllePayload': treblle- Enable async in your Treblle config:
treblle:
async: true- Start the Messenger worker:
php bin/console messenger:consume treblle --time-limit=3600Note
Run the worker as a supervised process (Supervisor, systemd, etc.) so it restarts automatically. If async: true is set but symfony/messenger is not installed, the SDK silently falls back to synchronous sending — no errors, no data loss.
Per-request metadata
Inject MetadataRegistry into any controller or service and call add() with an associative array. Values are merged with the globally defined metadata for that request only and cleared automatically after the response is sent.
use Treblle\Symfony\Metadata\MetadataRegistry;
final class OrderController extends AbstractController
{
public function __construct(private readonly MetadataRegistry $treblle) {}
#[Route('/orders', methods: ['POST'])]
public function create(Request $request): JsonResponse
{
$this->treblle->add([
'user-id' => $this->getUser()?->getId(),
'plan' => 'enterprise',
'tenant' => 'acme-corp',
]);
// ... handle request
}
}Multiple calls within the same request are merged together:
$this->treblle->add(['user-id' => 42]);
$this->treblle->add(['plan' => 'pro']);
// payload contains: { user-id: 42, plan: "pro" }Runtime values take precedence over any static keys defined under treblle.metadata in your config.
SDK Log Events
The SDK logs through Symfony’s standard logging system using a dedicated treblle Monolog channel. Log visibility is controlled entirely by your existing monolog.yaml configuration.
| Level | Message |
|---|---|
debug | Payload sent (with HTTP status code) |
debug | Skipped paths, disabled state, async dispatch |
warning | Missing sdk_token or api_key configuration |
warning | cURL errors or non-2xx responses from the ingress |
The treblle channel appears automatically in the Symfony Web Profiler under the Logs tab. No configuration is needed.
Routing logs to a dedicated file:
monolog:
handlers:
treblle:
type: stream
path: "%kernel.logs_dir%/treblle.log"
level: debug
channels: [treblle]Silencing Treblle logs in production:
# config/packages/prod/monolog.yaml
monolog:
handlers:
main:
type: fingers_crossed
channels: ['!treblle']Migrating from v3 to v4
1. Update the package
composer require treblle/treblle-symfony:^4.02. Update your config file
The following keys changed in config/packages/treblle.yaml:
| v3 key | v4 key | Notes |
|---|---|---|
masked_fields | masked_keywords | Renamed |
url | ingress_url | Renamed |
ignored_environments | (removed) | Use enabled instead |
debug | (removed) | Use Monolog treblle channel instead |
excluded_headers | excluded_paths | Different concept — now excludes by path, not header name |
Before (v3):
treblle:
api_key: "%env(TREBLLE_API_KEY)%"
sdk_token: "%env(TREBLLE_SDK_TOKEN)%"
debug: false
ignored_environments: dev,test,testing
masked_fields:
- password
- secret
excluded_headers:
- Authorization
url: "https://custom.treblle.com"After (v4):
treblle:
api_key: "%env(TREBLLE_API_KEY)%"
sdk_token: "%env(TREBLLE_SDK_TOKEN)%"
masked_keywords:
- password
- secret
excluded_paths:
- admin/*
ingress_url: "https://custom.treblle.com"3. Replace ignored_environments with enabled
v4 has no ignored_environments option. Instead, disable Treblle per environment using Symfony’s standard config override mechanism:
# config/packages/dev/treblle.yaml
treblle:
enabled: false# config/packages/test/treblle.yaml
treblle:
enabled: false4. Remove the debug key
The debug flag no longer exists. Log output is controlled through your monolog.yaml configuration via the treblle channel.
5. Review excluded_headers vs excluded_paths
excluded_headers (v3) excluded specific header names from being tracked. excluded_paths (v4) excludes entire request paths. Use masked_keywords if you need to hide sensitive header values.
6. Clear your cache
php bin/console cache:clear