# How to access Logger inside routes with Slim skeleton

**URL:** <https://discourse.slimframework.com/t/how-to-access-logger-inside-routes-with-slim-skeleton/5391>\
**Category:** Questions\
**Created:** [October 1, 2022, 2:25pm UTC](https://discourse.slimframework.com/t/how-to-access-logger-inside-routes-with-slim-skeleton/5391 "2022-10-01T14:25:09Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![guyw](https://avatars.discourse-cdn.com/v4/letter/g/5f9b8f/32.png) [@guyw](https://discourse.slimframework.com/u/guyw)\
**Post date:** [October 1, 2022, 2:25pm UTC](https://discourse.slimframework.com/t/how-to-access-logger-inside-routes-with-slim-skeleton/5391/1 "2022-10-01T14:25:09Z")

</div>

Hi,  
I’m enjoying using Slim. I opted to take the advice to plunge straight in and use the skeleton.  
Because I don’t know how things are connected together in the `Container`, I’m having difficulty knowing how to access classes that have been injected elsewhere.

For e.g., I’m writing a simple action that takes place in routes:

```auto
routes.php
...

    $app->get('/gallery', function (Request $request, Response $response) {

        $gallery = array_filter(glob( __DIR__. '/../public/gallery_images/thumbs/*'), 'is_file');

        $view = Twig::fromRequest($request);
        return $view->render($response, "gallery.twig", [
            'gallery' => $gallery,
        ]);
    })->setName('gallery');

```

How do I access the Logger that has already been injected into the DI Container within that route?  
I’ve tried:

```auto
$this->logger->debug("Message here")

ERROR: Undefined property: DI\\Container::$logger

```

and

```auto
$logger = $this->get('logger')

"No entry or class found for 'logger'"

```

but no success.  
The `settings.php` file is, apart from the `name` change and setting the log values to `true` is as it was from installation:

```auto
use App\Application\Settings\Settings;
use App\Application\Settings\SettingsInterface;
use DI\ContainerBuilder;
use Monolog\Logger;

return function (ContainerBuilder $containerBuilder) {

    // Global Settings Object
    $containerBuilder->addDefinitions([
        SettingsInterface::class => function () {
            return new Settings([
                'displayErrorDetails' => true, // Should be set to false in production
                'logError' => true,
                'logErrorDetails' => true,
                'logger' => [
                    'name' => 'my_app',
                    'path' => isset($_ENV['docker']) ? 'php://stdout' : __DIR__. '/../logs/app.log',
                    'level' => Logger::DEBUG,
                ],
            ]);
        }
    ]);
};

```

Can anyone help?

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [October 1, 2022, 5:32pm UTC](https://discourse.slimframework.com/t/how-to-access-logger-inside-routes-with-slim-skeleton/5391/2 "2022-10-01T17:32:56Z")

</div>

You can do it by @Odan [Slim 4 - Logging](https://odan.github.io/2020/05/25/slim4-logging.html), or prepare your own set of loggers (simple extensions) as a package or just classes declared within your project. Personally I prefer the second way (package with EventLogger, HttpLogger, ExceptionLogger, …) so my exaple follows its idea.

_src/Logger/HttpClientLogger.php_

```php
<?php

declare(strict_types=1);

namespace App\Logger;

use Monolog\Logger;

class HttpClientLogger extends Logger
{
}

```

_src/config/dependencies/packages.php_

```php
<?php

declare(strict_types=1);

use Slim\App;
use Slim\Factory\AppFactory;
use Psr\Container\ContainerInterface;
use Paneric\Logger\HttpClientLogger;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;

return [
...

    App::class => static function (ContainerInterface $container) {
        return AppFactory::createFromContainer($container);
    },

    HttpClientLogger::class => static function (
        ContainerInterface $container
    ): HttpClientLogger {
        $logger = new HttpClientLogger('http_client_logger');
        $streamHandler = new StreamHandler('./../var/log/http-client-logger.log', Level::Debug);
        $streamHandler->setFormatter(
            new LineFormatter(null, null, false, true)
        );
        $logger->pushHandler($streamHandler);
        return $logger;
    },
...
];

```

_src/bootstrap/bootstrap.php_

```php
<?php

declare(strict_types=1);

use DI\ContainerBuilder;

...
$builder = new ContainerBuilder();
$builder->useAutowiring(true);
$builder->useAnnotations(false);
$definitions = require './../src/config/dependencies/packages.php';
$builder->addDefinitions($definitions);
$container = $builder->build();

$slim = $container->get(App::class);
$slim->run();
...

```

The last file **src/bootstrap/bootstrap.php** you just need to:

```php
require './../src/bootstrap/bootstrap.php' 

```

in your front controller `index.php`.

This way your logger is accesible within your routes declarations by simple:

```php
$logger = $this->get(HttpClientLogger::class);

```

or injected to any class constructor if you need to:

```php
public function __construct(private HttpClientLogger $logger)
{
}

```

---

<div class="post-metadata">

**Author:** ![guyw](https://avatars.discourse-cdn.com/v4/letter/g/5f9b8f/32.png) [@guyw](https://discourse.slimframework.com/u/guyw)\
**Post date:** [October 2, 2022, 1:25pm UTC](https://discourse.slimframework.com/t/how-to-access-logger-inside-routes-with-slim-skeleton/5391/3 "2022-10-02T13:25:32Z")

</div>

Thanks for your reply!  
Unfortunately, I found it more confusing than helpful.

The Skeleton is already instantiating the Monolog Logger class so adding it again in a more convoluted file structure seems overly complicated.

> [@tj\_gumis](#):
>
> You can do it by @Odan [Slim 4 - Logging](https://odan.github.io/2020/05/25/slim4-logging.html)

The article in the link has sadly been removed.

How do I access the already instantiated Logger class from with a route within the given framework of the Skeleton?

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [October 2, 2022, 2:45pm UTC](https://discourse.slimframework.com/t/how-to-access-logger-inside-routes-with-slim-skeleton/5391/4 "2022-10-02T14:45:19Z")

</div>

You can slightly modify your `ErrorMiddleware` instantiation in your container definitions:

_config/container.php_

```php
return [
...
    ErrorMiddleware::class => function (ContainerInterface $container) {
        $settings = $container->get('settings')['error'];
        $app = $container->get(App::class);

        $logger = $container->get(LoggerFactory::class)
            ->addFileHandler('error.log')
            ->createLogger();

        $errorMiddleware = new ErrorMiddleware(
            $app->getCallableResolver(),
            $app->getResponseFactory(),
            (bool)$settings['display_error_details'],
            (bool)$settings['log_errors'],
            (bool)$settings['log_error_details'],
            $logger
        );

        $container->set('error_logger', $logger); // <--- HERE

        $errorMiddleware->setDefaultErrorHandler($container->get(DefaultErrorHandler::class));

        return $errorMiddleware;
    },
];
...

```

but at the same time keep in mind that (as far as I remember) instances added this way:

1. don’t take part in container compilation process;
2. are accessible only after their creation, so:

- logger created in `ErrorMiddleware` definition will be accesible within your route definition (look at the order of middlewares loop)
- logger created in `SomeController` definition (or any other object instantiated as a reason of a call to some action) won’t exist yet.

Summarizing, if you need a total flexibility, you need to:

1. Remove `LoggerFactory` completely from skeleton
2. Create your loggers the way I presented in my previous post.
3. Change the `ErrorMiddleware` definition:

_config/container.php_

```php
return [
...
    ErrorMiddleware::class => function (ContainerInterface $container) {
        $settings = $container->get('settings')['error'];
        $app = $container->get(App::class);

        $errorMiddleware = new ErrorMiddleware(
            $app->getCallableResolver(),
            $app->getResponseFactory(),
            (bool)$settings['display_error_details'],
            (bool)$settings['log_errors'],
            (bool)$settings['log_error_details'],
            $container->get(ErrorLogger::class) // <-- LOGGER CREATED AS ABOVE
        );

        $errorMiddleware->setDefaultErrorHandler($container->get(DefaultErrorHandler::class));

        return $errorMiddleware;
    },
];
...

```

---

<div class="post-metadata">

**Author:** ![guyw](https://avatars.discourse-cdn.com/v4/letter/g/5f9b8f/32.png) [@guyw](https://discourse.slimframework.com/u/guyw)\
**Post date:** [October 3, 2022, 9:19am UTC](https://discourse.slimframework.com/t/how-to-access-logger-inside-routes-with-slim-skeleton/5391/5 "2022-10-03T09:19:46Z")

</div>

Again, thanks for your response @tj_gumis.

It’s pretty much gone over my head. I feel encouraged read the Slim docs from the ground up to understand what’s going on.
