---
title: "Log writers"
manual: "TYPO3 Explained"
version: "11.5"
permalink: "https://docs.typo3.org/permalink/t3coreapi:logging-writers@11.5"
source: "ApiOverview/Logging/Writers/Index.rst"
rendered: "2026-10-21T15:30:00+00:00"
---

> [!WARNING]
> **Attention**
>
> TYPO3 v11 has reached end-of-life as of October 31th 2024 and
> is no longer being maintained. Use the version switcher on the top
> left of this page to select documentation for a supported version of TYPO3.
>
> Need more time before upgrading?
> You can purchase Extended Long Term Support (ELTS) for TYPO3 v11 here:
> [TYPO3 ELTS](https://typo3.com/services/extended-support-elts).

# 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.

Different log writers offer possibilities to log into different targets.
[Custom log writers](https://docs.typo3.org/permalink/t3coreapi:logging-writers-custom@11.5) 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@11.5)
-   [Custom log writers](https://docs.typo3.org/permalink/t3coreapi:custom-log-writers@11.5)
-   [Examples](https://docs.typo3.org/permalink/t3coreapi:examples@11.5)

## 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@11.5) section on how to
use these options.

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

The database writer logs into a database table. This table has to reside
in the database used by TYPO3 and is **not** automatically created.

The following option is available:

-   **logTable**

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

    The database table to write to.

    > [!WARNING]
    > The **Admin Tools > Log** module is not adapted to the records
    > written by the `DatabaseWriter` into the `sys_log` table. If
    > you write such records there, you will not be able to see them using
    > that module.

    > [!TIP]
    > There is the third-party extension [EXT:logs](https://extensions.typo3.org/extension/logs) available for viewing
    > such records in the TYPO3 backend.

    Example of a `CREATE TABLE` statement for `logTable`:

    **EXT:my_extension/ext_tables.sql**

    ```sql
    #
    # Table structure for table 'tx_examples_log'
    #
    # The KEY on request_id is optional
    #
    CREATE TABLE tx_examples_log (
        request_id varchar(13) DEFAULT '' NOT NULL,
        time_micro double(16,4) NOT NULL default '0.0000',
        component varchar(255) DEFAULT '' NOT NULL,
        level tinyint(1) unsigned DEFAULT '0' NOT NULL,
        message text,
        data text,

        KEY request (request_id)
    );
    ```

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

    **EXT:my_extension/ext_localconf.php**

    ```php
    use TYPO3\CMS\Core\Log\LogLevel;
    use TYPO3\CMS\Core\Log\Writer\DatabaseWriter;

    $GLOBALS['TYPO3_CONF_VARS']['LOG']['T3docs']['Examples']['Controller']['writerConfiguration'] = [
        LogLevel::DEBUG => [
            DatabaseWriter::class => [
                'logTable' => 'tx_examples_log',
            ],
        ],
    ];
    ```

> [!WARNING]
> If you are using a MariaDB Galera Cluster you should definitely add a
> primary key field to the database definition, since it is required by
> Galera (this can be a normal `uid` autoincrement field as known from
> other tables):
> [MariaDB Galera Cluster - Known Limitations](https://mariadb.com/kb/en/mariadb/mariadb-galera-cluster-known-limitations/).

### 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@11.5)).

The filename is appended with a hash, that depends on the
[encryption key](https://docs.typo3.org/permalink/t3coreapi:typo3confvars-sys-encryptionkey@11.5). If
[$GLOBALS\['TYPO3_CONF_VARS'\]\['SYS'\]\['generateApacheHtaccess'\]](https://docs.typo3.org/permalink/t3coreapi:typo3confvars-sys-generateapachehtaccess@11.5)
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**

    -   *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**

    -   *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
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Log\LogLevel;
use TYPO3\CMS\Core\Log\Writer\FileWriter;

// 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',
        ],
    ],
];
```

### 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/11.5/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/11.5/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@11.5) 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
{
    private LoggerInterface $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $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`:

**EXT:my_extension/ext_localconf.php**

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

// 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 [EXT:examples](https://extensions.typo3.org/extension/examples).
