Post Details

How to add logging to an abstract class in php

Working on a class library I´d like to add logging to a number of classes. I use Psr\Log\LoggingInterface to give the classes access to a logger object. But how do I set the logger in all classes in a decent way. There is a dependency to the logger as it is being used everywhere in the classes

I can use

Constructor

Add the logger to the constructor with

public function __constructor (
  readonly \Psr\Log\LoggingInterface $logger = new \Psr\Log\NullLoger()
);

Setlogger

Use a public setLogger()

public function setLogger( \Psr\Log\LoggingInterface $logger ): self
{
  $this->logger = $logger;
  return $this;
}
private \Psr\Log\LoggingInterface $logger;
public function __constructor()
{
  ...
  // Make sure a logger is set
  $this->logger = new \Psr\Log\NullLogger();
  ...
}

What would be the best way to do this? Is there a better way.


  • rj
    rj

    One way to achieve this is by using Dependency Injection to inject the logger into the classes that need it. Here's an example of how you can do this:

    1. Define an interface for your logger:
    <?php
    
    namespace YourNamespace;
    
    use Psr\Log\LoggerInterface;
    
    interface LoggerAwareInterface
    {
        public function setLogger(LoggerInterface $logger);
    }
    

    Implement this interface in the classes that need logging:

    <?php
    
    namespace YourNamespace;
    
    use Psr\Log\LoggerInterface;
    
    class MyClass implements LoggerAwareInterface
    {
        protected $logger;
    
        public function setLogger(LoggerInterface $logger)
        {
            $this->logger = $logger;
        }
    
        // Your class methods here...
    }
    

    When instantiating your classes, inject the logger:

    <?php
    
    use Psr\Log\LoggerInterface;
    
    class YourClassFactory
    {
        protected $logger;
    
        public function __construct(LoggerInterface $logger)
        {
            $this->logger = $logger;
        }
    
        public function createClassWithLogger()
        {
            $class = new MyClass();
            if ($class instanceof LoggerAwareInterface) {
                $class->setLogger($this->logger);
            }
            return $class;
        }
    }
    

    Finally, you can use a factory to instantiate your classes and inject the logger:

    <?php
    
    use Psr\Log\LoggerInterface;
    
    class YourLibrary
    {
        protected $logger;
    
        public function __construct(LoggerInterface $logger)
        {
            $this->logger = $logger;
        }
    
        public function createClassInstance()
        {
            $factory = new YourClassFactory($this->logger);
            return $factory->createClassWithLogger();
        }
    }
    

Leave A Reply


User name*