Google Cloud Trace Bundle
softspring/google-cloud-trace-bundle adds Google Cloud Trace spans to the main runtime layers of a Symfony application.
The bundle is designed for projects that already run behind distributed tracing infrastructure and receive a traceparent header. When that context is available, the bundle creates spans for the request flow and sends them to Google Cloud Trace at the end of the request.
This is mainly an integration component. Its value is not a user-facing feature. Its value is making performance and request flow easier to inspect in production.
What It Solves
Without this bundle, trace data usually has to be added by hand in controllers and services.
With this bundle, you get tracing around common Symfony layers with almost no application code:
- request handling in the kernel
- kernel termination
- dispatched events
- Twig template rendering
- Symfony HttpCache execution
- Doctrine DBAL query activity and related low-level DBAL operations
That gives you a fast way to answer practical questions such as:
- where is this request spending time?
- is the slowdown in Twig, events, or database access?
- is HttpCache involved?
- which route or response characteristics are attached to the traced request?
Installation
composer require softspring/google-cloud-trace-bundle:^6.0
Register the bundle in your application if needed.
Quick Start
The normal setup is:
- install the bundle
- enable the bundle in your Symfony application
- make sure your application receives a valid
traceparentheader from upstream infrastructure - use the kernel trait if you want the kernel itself to own the top-level server span and trace submission
There is no custom bundle configuration to add in the common case.
Important Requirement: Trace Context
The bundle only creates spans when an incoming trace context exists.
In practice, that means the request must include a traceparent header. If that header is missing, the tracing helper returns null spans and the decorators behave as no-ops.
This is important for adoption:
- if your local environment does not send
traceparent, the bundle will look inactive - if your reverse proxy or platform strips that header, no trace will be created
- if your application already receives distributed tracing context from Google Cloud infrastructure, the bundle can attach its spans to that request flow
What Gets Traced Automatically
The bundle hooks into the container at compile time and instruments the services that are present in the application.
Kernel Handling
The HTTP kernel is decorated to trace:
- the request path itself
kernel.handlekernel.terminate
This gives you the main application flow for each traced request.
Event Dispatching
The Symfony event dispatcher is decorated so each dispatched event can create its own span.
This is useful when your application or Symfony itself relies heavily on events. It helps reveal whether request time is spent in event-driven workflows instead of controllers alone.
Twig Rendering
If Twig is enabled, the bundle replaces the Twig environment class with a traced one.
That means calls to render() create a span named after the template being rendered.
This is useful when:
- pages render many nested templates
- email or back office pages are Twig-heavy
- you want to see whether rendering is part of a slow request
HttpCache
If Symfony HttpCache is enabled, the bundle replaces the HttpCache class with a traced one.
This helps when you need visibility into:
- cache request handling
- cache termination
- the difference between application time and HttpCache time
Doctrine DBAL
If Doctrine is present, the bundle instruments DBAL activity.
It supports two styles depending on the DBAL version in use:
- middleware-based tracing on newer DBAL versions
- SQL logger decoration on older DBAL versions
This gives you spans for common DBAL work such as:
- queries
exec
The exact low-level coverage depends on the DBAL integration style available in the application.
Using The Kernel Trait
The package also ships a TraceKernelTrait.
Use it when you want your kernel to:
- create a top-level server span during boot
- stop that span on terminate
- send the collected trace at the end of the request
This is the simplest integration point when you control the kernel and want request-level tracing without wiring custom services yourself.
Typical use:
use Softspring\GoogleCloudTraceBundle\TraceKernelTrait;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
class Kernel extends BaseKernel
{
use MicroKernelTrait;
use TraceKernelTrait;
}
Use this carefully if your kernel already customizes boot() or terminate(), because the trait becomes part of that lifecycle.
Creating Custom Spans
The bundle is not limited to automatic tracing.
You can also use the Tracer helper directly in your own code when you want business-level spans around work that matters to your application.
Typical cases:
- wrapping an external API call
- tracing a pricing or billing calculation
- measuring a document generation step
- tracing a domain workflow that is more useful than a low-level event name
Basic pattern:
use Softspring\GoogleCloudTraceBundle\Trace\Tracer;
$span = Tracer::createSpan('billing.generate_invoice');
Tracer::start($span);
// do work
Tracer::stop($span);
This is especially useful when the automatic layers are not enough and you need spans that match your domain language.
What Attributes Are Added
When request or response information is available, the tracer adds attributes such as:
- request URL and method
- request scheme
- Symfony route name
- response status code
- response protocol version
- response content length
- selected cache-related response values such as TTL and cache control directives
This makes the trace more useful when comparing behavior across routes or responses.
Good Use Cases
This component is a good fit when:
- your application already runs in Google Cloud
- distributed trace context reaches PHP requests
- you want quick visibility into Symfony runtime layers
- you need more observability without manually instrumenting every feature
It is especially useful in projects that combine:
- heavy Twig rendering
- event-driven architecture
- Doctrine-heavy request flow
- Symfony HttpCache
Extension And Integration Notes
The bundle is intentionally light on configuration. Most extension happens through integration choices:
- decide whether to use the kernel trait
- add your own custom spans around domain workflows
- keep or replace tracing around the services that matter most in your application
If you need more control over naming, filtering, or span strategy, the usual approach is to build that around Tracer in your own application layer.
Troubleshooting
I installed the bundle but no traces appear
The first thing to check is whether the request includes traceparent.
Without that header, the tracer stays inactive by design.
Twig or Doctrine are not traced
The bundle only instruments the related subsystem when it is present in the container. If Twig, Doctrine, or HttpCache are not enabled in the application, there is nothing to decorate.
My application needs domain-level trace names
Use Tracer directly in your own services. The automatic spans are a baseline, not a replacement for all application-specific instrumentation.
Current Limits
The main limits to keep in mind are:
- tracing depends on incoming trace context
- there is no rich configuration layer for filtering or renaming spans
- the bundle focuses on request lifecycle instrumentation, not full background worker tracing
- automatic tracing gives infrastructure visibility first; domain-level spans still need to be added by the application when needed
Summary
Choose this bundle when you want Google Cloud Trace visibility across the main Symfony runtime layers with very little setup.
Its main value is practical observability: faster debugging of slow requests, clearer understanding of where time is spent, and a simple base for adding your own application-level spans.