---
title: "Log writers"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:logging-writers@main"
source: "ApiOverview/Logging/Writers/Index.rst"
rendered: "2026-09-22T15:26:06+00:00"
---

# Log writers {#logging-writers}

The purpose of a log writer is (usually) to save all log records into a
persistent storage, like a log file, a database table, or to a remote syslog
server.

> [!NOTE]
> **See also**
>
> If you are looking for guidance on configuring logging for production
> environments — such as log rotation, file locations, retention, or
> integration with tools like Sentry — see the chapter
> [Logging considerations during production](https://docs.typo3.org/permalink/t3coreapi:production-logging@main).

Different log writers offer possibilities to log into different targets.
[Custom log writers](https://docs.typo3.org/permalink/t3coreapi:logging-writers-custom@main) can extend the functionality
shipped with TYPO3 Core.

****Table of Contents****

-   [Built-in log writers](https://docs.typo3.org/permalink/t3coreapi:built-in-log-writers@main)
-   [Custom log writers](https://docs.typo3.org/permalink/t3coreapi:custom-log-writers@main)
-   [Examples](https://docs.typo3.org/permalink/t3coreapi:examples@main)

## Built-in log writers {#logging-writers-builtin}

This section describes the log writers shipped with the TYPO3 Core.
Some writers have options to allow customization of the particular writer.
See the [configuration](https://docs.typo3.org/permalink/t3coreapi:logging-configuration-writer@main) section on how to
use these options.

### `DatabaseWriter` {#logging-writers-database}

`\TYPO3\CMS\Core\Log\Writer\DatabaseWriter` is a dedicated writer for the
`sys_log` table.

### `FileWriter` {#logging-writers-filewriter}

The file writer logs into a log file, one log record per line. If the log file
does not exist, it will be created (including parent directories, if needed).

Please make sure:

-   Your web server has write permissions to that path.
-   The path is below the root directory of your website (defined by
    [Environment::getPublicPath()](https://docs.typo3.org/permalink/t3coreapi:environment-public-path@main)).

The filename is appended with a hash, that depends on the
[encryption key](https://docs.typo3.org/permalink/t3coreapi:typo3confvars-sys-encryptionkey@main). If
[$GLOBALS\['TYPO3_CONF_VARS'\]\['SYS'\]\['generateApacheHtaccess'\]](https://docs.typo3.org/permalink/t3coreapi:typo3confvars-sys-generateapachehtaccess@main)
is set, an `.htaccess` file is added to the directory. It protects your
log files from being accessed from the web. If the `logFile` option is not
set, TYPO3 will use a filename containing a random hash, like
`typo3temp/logs/typo3_7ac500bce5.log`.

The following options are available:

#### logFile {#file-writer-logfile}

-   **logFile**

    -   *Type:* string
    -   *Mandatory:* no
    -   *Default:* `typo3temp/logs/typo3_<hash>.log` (for example, like `typo3temp/logs/typo3_7ac500bce5.log`)

    The path to the log file.

#### logFileInfix {#file-writer-logfileinfix}

-   **logFileInfix**

    -   *Type:* string
    -   *Mandatory:* no
    -   *Default:* (empty string)

    This option allows to set a different name for the log file that is created
    by the `FileWriter` without having to define a full path to the file.
    For example, the settings `'logFileInfix' => 'special'` results in
    `typo3_special_<hash>.log`.

The corresponding configuration might look like this for the example class
`\T3docs\Examples\Controller`:

**EXT:my_extension/ext_localconf.php**

```php
<?php

declare(strict_types=1);

use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Log\LogLevel;
use TYPO3\CMS\Core\Log\Writer\FileWriter;

defined('TYPO3') or die();

// Add example configuration for the logging API
$GLOBALS['TYPO3_CONF_VARS']['LOG']['T3docs']['Examples']['Controller']['writerConfiguration'] = [
  // configuration for ERROR level log entries
  LogLevel::ERROR => [
    // Add a FileWriter
    FileWriter::class => [
      // Configuration for the writer
      'logFile' => Environment::getVarPath() . '/log/typo3_examples.log',
    ],
  ],
];

```

### `RotatingFileWriter` {#logging-writers-rotatingfilewriter}

TYPO3 log files tend to grow over time if not manually cleaned on a regular
basis, potentially leading to full disks. Also, reading its contents may be
hard when several weeks of log entries are printed as a wall of text.

To circumvent such issues, established tools like [logrotate](https://linux.die.net/man/8/logrotate) are available for
a long time already. However, TYPO3 may be installed on a hosting environment
where "logrotate" is not available and cannot be installed by the customer.
To cover such cases, a simple log rotation approach is available, following the
"copy/truncate" approach: when rotating files, the currently opened log file is
copied (for example, to `typo3_<hash>.log.20230616094812`) and the original log
file is emptied.

Example of the `var/log/` folder with rotated log files:

**typo3_root$**

```console
$ ls -1 var/log
typo3_<hash>.log
typo3_<hash>.log.20230613065902
typo3_<hash>.log.20230614084723
typo3_<hash>.log.20230615084756
typo3_<hash>.log.20230616094812
```

The file writer `\TYPO3\CMS\Core\Log\Writer\RotatingFileWriter` extends the
[FileWriter](https://docs.typo3.org/permalink/t3coreapi:logging-writers-filewriter@main) class. The `RotatingFileWriter`
accepts all options of `FileWriter` in addition of the following:

#### interval {#rotating-file-writer-interval}

-   **interval**

    -   *Type:* `\TYPO3\CMS\Core\Log\Writer\Enum\Interval`, string
    -   *Mandatory:* no
    -   *Default:* `\TYPO3\CMS\Core\Log\Writer\Enum\Interval::DAILY`

    The interval defines how often logs should be rotated. Use one of the
    following options:

    -   `\TYPO3\CMS\Core\Log\Writer\Enum\Interval::DAILY` or `daily`
    -   `\TYPO3\CMS\Core\Log\Writer\Enum\Interval::WEEKLY` or `weekly`
    -   `\TYPO3\CMS\Core\Log\Writer\Enum\Interval::MONTHLY` or `monthly`
    -   `\TYPO3\CMS\Core\Log\Writer\Enum\Interval::YEARLY` or `yearly`

#### maxFiles {#rotating-file-writer-maxfiles}

-   **maxFiles**

    -   *Type:* integer
    -   *Mandatory:* non
    -   *Default:* `5`

    This option configured how many files should be retained (use `0` to
    never delete any file).

> [!NOTE]
> When configuring the `RotatingFileWriter` in
> `system/settings.php`, the string representations of the
> `Interval` cases must be used for the option `interval` option,
> as otherwise this might break the Install Tool.

The following example introduces log rotation for the "main" log file:

**config/system/additional.php | typo3conf/system/additional.php**

```php
<?php

declare(strict_types=1);

use Psr\Log\LogLevel;
use TYPO3\CMS\Core\Log\Writer\Enum\Interval;
use TYPO3\CMS\Core\Log\Writer\RotatingFileWriter;

$GLOBALS['TYPO3_CONF_VARS']['LOG']['writerConfiguration'][LogLevel::ERROR] = [
  RotatingFileWriter::class => [
    'interval' => Interval::DAILY,
    'maxFiles' => 5,
  ],
];

```

Another example introduces log rotation for the "deprecation" log file:

**config/system/additional.php | typo3conf/system/additional.php**

```php
<?php

declare(strict_types=1);

use Psr\Log\LogLevel;
use TYPO3\CMS\Core\Log\Writer\Enum\Interval;
use TYPO3\CMS\Core\Log\Writer\RotatingFileWriter;

$GLOBALS['TYPO3_CONF_VARS']['LOG']['TYPO3']['CMS']['deprecations']['writerConfiguration'][LogLevel::NOTICE] = [
  RotatingFileWriter::class => [
    'logFileInfix' => 'deprecations',
    'interval' => Interval::WEEKLY,
    'maxFiles' => 4,
    'disabled' => false,
  ],
];

```

### `PhpErrorLogWriter` {#logging-writers-php}

This writer logs into the PHP error log using [error_log()](https://www.php.net/manual/en/function.error-log.php)

### `SyslogWriter` {#logging-writers-syslog}

The syslog writer logs into the syslog (Unix only).

The following option is available:

-   **facility**

    -   *Type:* string
    -   *Mandatory:* no
    -   *Default:* `USER`

    The syslog [facility](https://en.wikipedia.org/wiki/Syslog#Facility) to log into.

## Custom log writers {#logging-writers-custom}

Custom log writers can be added through extensions. Every log writer has to
implement the interface [EXT:core/Classes/Log/Writer/WriterInterface.php (GitHub)](https://github.com/typo3/typo3/blob/main/typo3/sysext/core/Classes/Log/Writer/WriterInterface.php). It is
suggested to extend the abstract class [EXT:core/Classes/Log/Writer/AbstractWriter.php (GitHub)](https://github.com/typo3/typo3/blob/main/typo3/sysext/core/Classes/Log/Writer/AbstractWriter.php)
which allows you to use configuration options by adding the corresponding
properties and setter methods.

Please keep in mind that TYPO3 will silently continue operating, in case a log
writer is throwing an exception while executing the `writeLog()` method.
Only in the case that all registered writers fail, the log entry with additional
information will be added to the configured fallback logger (which defaults to
the [PhpErrorLog](https://docs.typo3.org/permalink/t3coreapi:logging-writers-php@main) writer).

### Usage in a custom class {#logging-writers-usage}

All log writers can be used in your own classes. If the service is configured to
use autowiring you can inject a logger into the `__construct()` method of
your class `\MyVendor\MyExtension\MyFolder\MyClass`) since TYPO3 v11 LTS.

**EXT:my_extension/Classes/MyClass.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension;

use Psr\Log\LoggerInterface;

final class MyClass
{
  public function __construct(
    private readonly LoggerInterface $logger,
  ) {}

  public function doSomething()
  {
    $this->logger->info('My class is executed.');

    $error = false;

    // ... something is done ...

    if ($error) {
      $this->logger->error('Error in class MyClass');
    }
  }
}

```

If autowiring is disabled, the service class however must implement the
interface `\Psr\Log\LoggerAwareInterface` and use the
`\Psr\Log\LoggerAwareTrait`.

**EXT:my_extension/Classes/MyClass.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension;

use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;

final class MyClass implements LoggerAwareInterface
{
  use LoggerAwareTrait;

  public function doSomething()
  {
    $this->logger->info('My class is executed.');

    $error = false;

    // ... something is done ...

    if ($error) {
      $this->logger->error('Error in class MyClass');
    }
  }
}

```

One or more log writers for this class are configured in the file
[`ext_localconf.php`](../../../ExtensionArchitecture/FileStructure/ExtLocalconf.md#file-extension-ext-localconf-php):

**EXT:my_extension/ext_localconf.php**

```php
<?php

declare(strict_types=1);

use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Log\LogLevel;
use TYPO3\CMS\Core\Log\Writer\FileWriter;

defined('TYPO3') or die();

// Add example configuration for the logging API
$GLOBALS['TYPO3_CONF_VARS']['LOG']['MyVendor']['MyExtension']['MyClass']['writerConfiguration'] = [
  // Configuration for ERROR level log entries
  LogLevel::ERROR => [
    // Add a FileWriter
    FileWriter::class => [
      // Configuration for the writer
      'logFile' => Environment::getVarPath() . '/log/my_extension.log',
    ],
  ],
];

```

## Examples {#logging-writers-examples}

Working examples of the usage of different Log writers can be found in the
extension [`t3docs/examples`](https://packagist.org/packages/t3docs/examples).
