6

I've recently read up on PSR-3 and am interested in learning about the best way(s) of approaching a logger implementation across a web application or website. I understand how a logger is defined and how they can be implemented per PSR-3, but what about accessing/referencing them across the application for various logging needs such as caught exceptions, notable events, etc.?

These three options came to mind. Are there any more? Which is the best approach?

  1. Global object - $logger->debug('foo')
  2. Global static instance - Logger::debug('foo')
  3. via some kind of method - $app->getLogger()->debug('foo')
  4. ...etc...

One of my considerations is keeping the code needed for referencing the logger at a minimum. For example, option 3 above seems like it would get rather tedious to retrieve the logger like that for every appropriate caught exception, notable event, etc., throughout the application.

  • What about a LoggerFactory.getLogger()? – Laiv Oct 28 '16 at 20:16
  • 1
    In my C# applications, I prefer a static logger. But it contains an instance of a logger which gets set during the configuration of the application, and all calls to the static logger get delegated to that instance. Thus I can replace the actual logger with a simple change in the configuration. I don't know about the concepts used in php, but I guess that this is technically also possible there. – Bernhard Hiller Oct 31 '16 at 8:55
3

I personally like to use Dependency Injection. Here is some example:

class MyClass
{
   public function __constructor(\Psr\Log\LoggerInterface $logger)
   {
       $this->logger = $logger;
   }

   public function someMethod()
   {
      $this->logger->warning('some warning');
   }
}

The only thing that you must do is configure the dependency injection container to use your concrete logger class that implements PSR3.

  • 1
    What about application-wide usage, i.e., looking at the scope of the entire application? Do you use this dependency injection within each and every class you instantiate throughout your application so that there is no external (outside the class) logging? – reformed Feb 1 '17 at 15:59
  • 1
    I inject the logger in each of the classes that should log something. The other classes remain untouched. I don't log all the things that happen in the application, only what I'm interested at some moment. – Constantin Galbenu Feb 1 '17 at 16:04
  • Also, when you instantiate MyClass, how do you reference the logger in order to pass it into the constructor? Do you use one of the 3 options mentioned in the question, or use a different approach? e.g., $myClass = new MyClass(<<reference>>); – reformed Feb 1 '17 at 16:04
  • i.e., is it a global reference, static instance, retrieved by some method, etc. – reformed Feb 1 '17 at 16:06
  • 1
    Anyway, I see your question as being larger: how do you manage your dependencies, generally speaking? You have 3 options: 1.you manage them yourself, using nested new calls (OMG!), 2.you use a Service Locator or static method calls (BLEAH!) or 3. you use Dependency Injection (my preferred) – Constantin Galbenu Feb 1 '17 at 16:13
-2

I would write an interface called ILogger and ILoggerFactory, the implementation of ILoggerFactory will be a factory class returning concrete implementation of ILogger encapsulating custom logging framework you would want to use (for e.g NLog or Log4Net). This way all your projects need is reference to ILogger and ILoggerFactory and the Custom logging factory can be injected.

  • 1
    question is about PHP, .Net has nothing to do with this – gnat Feb 1 '17 at 19:21
  • Sorry, never realized that.. – amassani Feb 1 '17 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.