> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Logging From PHP

export const VersionRequirements = ({versions = []}) => {
  if (!Array.isArray(versions) || versions.length === 0) {
    return null;
  }
  const boundaries = {
    upper: " or lower",
    exact: "",
    lower: " or higher"
  };
  const containerStyle = {
    marginTop: "0.5rem",
    marginBottom: "1.5rem"
  };
  const lineStyle = {
    display: "block",
    margin: "0 0 0.35rem 0",
    fontSize: "0.875rem",
    lineHeight: "1.4"
  };
  const pillBaseStyle = {
    display: "inline-block",
    padding: "0.1em 0.4em",
    borderRadius: "0.25rem",
    border: "1px solid",
    fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
    fontSize: "0.85em",
    fontWeight: 500
  };
  const pillColors = {
    "AppSignal for Elixir": {
      background: "#f3e8ff",
      borderColor: "#e9d5ff",
      color: "#9333ea"
    },
    "AppSignal for Front-end": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Go": {
      background: "#ccfbf1",
      borderColor: "#99f6e4",
      color: "#0d9488"
    },
    "AppSignal for JavaScript": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Node.js": {
      background: "#dcfce7",
      borderColor: "#bbf7d0",
      color: "#16a34a"
    },
    "AppSignal for Python": {
      background: "#dbeafe",
      borderColor: "#bfdbfe",
      color: "#2563eb"
    },
    "AppSignal for Ruby": {
      background: "#fee2e2",
      borderColor: "#fecaca",
      color: "#dc2626"
    },
    "AppSignal for Rust": {
      background: "#ffedd5",
      borderColor: "#fed7aa",
      color: "#ea580c"
    }
  };
  const defaultPillColor = {
    background: "#f4f4f5",
    borderColor: "#e4e4e7",
    color: "#52525b"
  };
  const getPillStyle = name => ({
    ...pillBaseStyle,
    ...pillColors[name] || defaultPillColor
  });
  const getBoundText = bound => {
    return boundaries[bound] || boundaries.lower;
  };
  return <div style={containerStyle}>
      {versions.map((v, i) => <p key={`${v.name}-${v.version}-${v.bound || "lower"}-${i}`} style={lineStyle}>
          This feature requires{" "}
          <code style={getPillStyle(v.name)}>{v.name}</code> version {v.version}
          {getBoundText(v.bound)}.
        </p>)}
    </div>;
};

<VersionRequirements
  versions={[
{ name: "AppSignal for PHP", version: "0.5.0" }
]}
/>

This documentation outlines how to configure logging with the AppSignal for PHP package.

## Configure logging

<Warning>
  🔐 Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) from logs and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> For **HIPAA-covered entities**, more information about signing a Business Associate Agreement (BAA) can be found in our [Business Add-Ons documentation](/support/business-add-ons).
</Warning>

You do not need to create a log source to send logs from the AppSignal for PHP integration. An "application" log source will be created automatically.

The AppSignal for PHP package uses OpenTelemetry's logging capabilities to send logs to AppSignal.

### Laravel

If you're using the Laravel framework, the AppSignal for PHP package automatically sends your logs to AppSignal. You do not need to configure Monolog directly.

### Symfony

If you're using the Symfony framework, the easiest way to send logs to AppSignal is by using the [`MonologBundle`](https://github.com/symfony/monolog-bundle).

Install the Monolog auto-instrumentation package.

```shell Shell theme={null}
composer require open-telemetry/opentelemetry-logger-monolog
```

Add a service definition for `'appsignal.monolog.handler'` that uses the `Appsignal\Integrations\Monolog\Handler` class.

```yml title="config/services.yaml" theme={null}
services:
  # ... other services

  appsignal.monolog.handler:
    class: Appsignal\Integrations\Monolog\Handler
    factory: ['Appsignal\Integrations\Monolog\Handler', "withLevel"]
    arguments: ["info"] # configure log level that will reach AppSignal
```

Add `appsignal.monolog.handler` to the Monolog handler stack.

```yml title="config/packages/monolog.yaml" theme={null}
monolog:
  handlers:
    # other handlers

    appsignal:
      type: service
      id: appsignal.monolog.handler
      channels: ["app", "event"] # configure which channels to send to AppSignal
```

### Monolog

[Monolog](https://github.com/Seldaek/monolog) is the most popular logging library for PHP. You can use Monolog directly to send logs to AppSignal.

Install the Monolog auto-instrumentation package.

```shell Shell theme={null}
composer require open-telemetry/opentelemetry-logger-monolog
```

Then add `Appsignal\Integrations\Monolog\Handler` to Monolog's handler stack.

```php PHP theme={null}
use Appsignal\Integrations\Monolog\Handler;
use Monolog\Logger;

$logger = new Logger('app');
$logger->pushHandler(Handler::withLevel('info'));

$logger->info('My log message');
```

### Stand-alone usage

You can also send logs with the stand-alone logger using the `log` helper method from the `Appsignal` base class. This method doesn't require configuration.

```php PHP theme={null}
use Appsignal\Appsignal;
use Appsignal\Severity;

// Log a message
Appsignal::log(
	message: 'Log message line',
	severity: Severity::INFO,
	loggerName: 'my-app',
	attributes: [
		'customer_id' => $customer->id,
	],
);
```

Configure Monolog with the OpenTelemetry handler to send logs to AppSignal:

```php PHP theme={null}
use Appsignal\Integrations\Monolog\Handler;
use Monolog\Logger;

// Create Monolog logger with the AppSignal handler
$logger = new Logger('app', [Handler::withLevel('info')]);

```

## Sending logs

### Monolog

Using Monolog, you can define the severity level of your logs:

```php PHP theme={null}
$logger->warning("Something's gone terribly wrong here");
$logger->info('User action completed successfully');
$logger->error('Database connection failed');

// using Laravel's Log facade
Log::warning("Something's gone terribly wrong here");
Log::info('User action completed successfully');
Log::error('Database connection failed');
```

You can define custom attributes to send log information that can be used when filtering and querying logs:

```php PHP theme={null}
$logger->info('Generating invoice for customer', ['customer_id' => $customer->id]);

// using Laravel's Log facade
Log::info('Generating invoice for customer', ['customer_id' => $customer->id]);
```

### Stand-alone logger

Using the stand-alone logger, you can define the severity level of your logs:

```php PHP theme={null}
use Appsignal\Appsignal;
use Appsignal\Severity;

// Different severity levels
Appsignal::log(
	message: "Something's gone terribly wrong here",
	severity: Severity::WARN,
);

Appsignal::log(
	message: 'User action completed successfully',
	severity: Severity::INFO,
);

Appsignal::log(
	message: 'Database connection failed',
	severity: Severity::ERROR,
);
```

You can define custom attributes to send log information that can be used when filtering and querying logs:

```php PHP theme={null}
use Appsignal\Appsignal;
use Appsignal\Severity;

function processInvoice($customer) {
	Appsignal::log(
		message: 'Generating invoice for customer',
		severity: Severity::INFO,
		attributes: ['customer_id' => $customer->id],
	);
}
```

## Filtering logs

You can query and filter on message contents and attribute values from within the [Log Management](/logging/log-management) tool.

Once configured, the desired attributes will be sent to AppSignal as log tags, and be queryable in the AppSignal logging interface.

### Structured logging

AppSignal supports structured logging out of the box. You can send structured data as log attributes:

```php PHP theme={null}
use Appsignal\Appsignal;
use Appsignal\Severity;

Appsignal::log(
	message: 'User action completed',
	severity: Severity::INFO,
    attributes: [
		'user_id' => $userId,
		'action' => 'purchase',
		'product_id' => $productId,
		'amount' => $amount,
		'currency' => 'USD'
	],
);

// or using Monolog
$logger->info('Generating invoice for customer', ['customer_id' => $customer->id]);

// or using Laravel's Log facade
Log::info('Generating invoice for customer', ['customer_id' => $customer->id]);
```

<Note>
  You can also configure AppSignal for PHP to ignore specific log lines using [the `ignore_logs` option](/php/configuration#option-ignore_logs). See [our Ignore Logs guide](/guides/filter-data/ignore-logs) to learn more.
</Note>

## Need help?

After configuring your PHP application to send logs, logs should appear in AppSignal. If you are unsure about this step or AppSignal is not receiving any logs, you can always [reach out](mailto:support@appsignal.com) for assistance. We'll help get you back on track!
