---
title: Correlating PHP Logs and Traces
description: Connect your PHP logs and traces to correlate them in Datadog.
breadcrumbs: >-
  Docs > APM > Correlate APM Data with Other Telemetry > Correlate Logs and
  Traces > Correlating PHP Logs and Traces
---

# Correlating PHP Logs and Traces

## Automatic injection{% #automatic-injection %}

Starting in version `1.12.0`, the PHP tracer automatically injects trace correlation identifiers into application logs. To enable automatic injection for older tracer versions, set the environment variable `DD_LOGS_INJECTION` (INI setting `datadog.logs_injection`) to `true`.

The PHP tracer supports PSR-3 compliant loggers, such as [Monolog](https://github.com/Seldaek/monolog) or [Laminas Log](https://github.com/laminas/laminas-log).

{% alert level="danger" %}
**Note**: Set up your logging library to produce logs in JSON format so that:
- You don't need [custom parsing rules](https://docs.datadoghq.com/logs/log_configuration/parsing).
- Stack traces are properly wrapped into the log event.

{% /alert %}

### Configure injection in logs{% #configure-injection-in-logs %}

If you haven't done so already, configure the PHP tracer with `DD_ENV`, `DD_SERVICE`, and `DD_VERSION`. This provides the best experience for adding `env`, `service`, and `version` to your logs (see [Unified Service Tagging](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging) for more details).

The PHP tracer provides various ways to configure the injection of trace correlation identifiers into your logs:

- Add all trace correlation identifiers to the log context
- Use placeholders in your message

#### Option 1: Add all trace correlation identifiers to the log context{% #add-all-trace-correlation-identifiers-to-the-log-context %}

The default behavior of the PHP tracer is to add all trace correlation identifiers to the log context.

For example, if you are using the [Monolog](https://github.com/Seldaek/monolog) library in a Laravel application as follows:

```php
use Illuminate\Support\Facades\Log;
# ...
Log::debug('Hello, World!');
```

The PHP tracer adds the available trace correlation identifiers to the log context, in JSON format. The logged message above could be transformed into:

```
[2022-12-09 16:02:42] production.DEBUG: Hello, World! {"dd.trace_id":"1234567890abcdef","dd.span_id":"1234567890abcdef","dd.service":"laravel","dd.version":"8.0.0","dd.env":"production","status":"debug"}
```

**Note**: If there is a placeholder in your message or if a trace ID is already present in the message, the PHP tracer does **not** add the trace correlation identifiers to the log context.

#### Option 2: Use placeholders in your message{% #use-placeholders-in-your-message %}

You can use placeholders in your message to select which trace correlation identifiers are automatically injected into your logs. The PHP tracer supports the following placeholders:

- `%dd.trace_id%`: the trace ID
- `%dd.span_id%`: the span ID
- `%dd.service%`: the service name
- `%dd.version%`: the service version
- `%dd.env%`: the service environment

Placeholders are case-sensitive and must be enclosed in `%` characters.

For example, if you are using the [Monolog](https://github.com/Seldaek/monolog) library in a Laravel application, you can configure the injection into a log message as follows:

```php
use Illuminate\Support\Facades\Log;
# ...
Log::info('Hello, World! [%dd.trace_id% %dd.span_id% %status%]');
```

The PHP tracer replaces the placeholders with the corresponding values. For example, the logged message above is transformed into:

```
[2022-12-09 16:02:42] production.INFO: Hello, World! [dd.trace_id="1234567890abcdef" dd.span_id="1234567890abcdef" status="info"]
```

**Note**: The brackets are mandatory if you plan on using the default parsing rules provided in the PHP [log pipeline](https://docs.datadoghq.com/logs/log_configuration/pipelines). If you are using a custom parsing rule, you can omit the brackets if needed.

## Manual injection{% #manual-injection %}

{% alert level="danger" %}
**Note:** The function `\DDTrace\current_context()` has been introduced in version [0.61.0](https://github.com/DataDog/dd-trace-php/releases/tag/0.61.0) and returns decimal trace identifiers.
{% /alert %}

To connect your logs and traces together, your logs must contain the `dd.trace_id` and `dd.span_id` attributes that respectively contain your trace ID and your span ID.

If you are not using a [Datadog Log Integration](https://docs.datadoghq.com/logs/log_collection/php/) to parse your logs, custom log parsing rules need to ensure that `dd.trace_id` and `dd.span_id` are being parsed as strings and remapped thanks to the [Trace Remapper](https://docs.datadoghq.com/logs/log_configuration/processors/#trace-remapper). More information can be found in [Correlated Logs Not Showing Up in the Trace ID Panel](https://docs.datadoghq.com/tracing/troubleshooting/correlated-logs-not-showing-up-in-the-trace-id-panel/?tab=custom).

For instance, you would append those two attributes to your logs with:

```php
  <?php
  $append = sprintf(
      ' [dd.trace_id=%s dd.span_id=%s]',
      \DDTrace\logs_correlation_trace_id(),
      \dd_trace_peek_span_id()
  );
  my_error_logger('Error message.' . $append);
?>
```

If the logger implements the [**monolog/monolog** library](https://github.com/Seldaek/monolog), use `Logger::pushProcessor()` to automatically append the identifiers to all log messages. For monolog v1, add the following configuration:

```php
<?php
  $logger->pushProcessor(function ($record) {
      $record['message'] .= sprintf(
          ' [dd.trace_id=%s dd.span_id=%s]',
          \DDTrace\logs_correlation_trace_id(),
          \dd_trace_peek_span_id()
      );
      return $record;
  });
?>
```

For monolog v2, add the following configuration:

```php
<?php
  $logger->pushProcessor(function ($record) {
      return $record->with(message: $record['message'] . sprintf(
          ' [dd.trace_id=%s dd.span_id=%s]',
          \DDTrace\logs_correlation_trace_id(),
          \dd_trace_peek_span_id()
      ));
    });
  ?>
```

If your application uses JSON logs format, you can add a first-level key `dd` that contains the `trace_id` and `span_id`, instead of appending `trace_id` and `span_id` to the log message:

```php
<?php
  $logger->pushProcessor(function ($record) use ($context) {
      $record['dd'] = [
          'trace_id' => \DDTrace\logs_correlation_trace_id(),
          'span_id'  => \dd_trace_peek_span_id()
      ];

      return $record;
  });
?>
```

For monolog v3, add the following configuration:

```php
<?php
  $logger->pushProcessor(function ($record) {
        $record->extra['dd'] = [
            'trace_id' => \DDTrace\logs_correlation_trace_id(),
            'span_id'  => \dd_trace_peek_span_id()
        ];
        return $record;
    });
?>
```

If you are ingesting your logs as JSON, go to [Preprocessing for JSON logs](https://app.datadoghq.com/logs/pipelines/remapping) and add `extra.dd.trace_id` to the **Trace Id Attributes** field.

## Further Reading{% #further-reading %}

- [Manually instrument your application to create traces.](https://docs.datadoghq.com/tracing/trace_collection/custom_instrumentation)
- [Explore your services, resources, and traces](https://docs.datadoghq.com/tracing/glossary/)
- [Correlate request logs with traces automatically](https://www.datadoghq.com/blog/request-log-correlation/)
- [Ease troubleshooting with cross product correlation.](https://docs.datadoghq.com/logs/guide/ease-troubleshooting-with-cross-product-correlation/)
