All Projects → orasik → monolog-middleware

orasik / monolog-middleware

Licence: MIT license
Monolog middleware for PSR-7 micro frameworks like Zend Expressive and Slim

Programming Languages

PHP
23972 projects - #3 most used programming language

Projects that are alternatives of or similar to monolog-middleware

doctrine-expressive-example
Example PHP REST API application built with Expressive using Doctrine ORM, complete with associations, pagination, and DB connectivity inside Docker containers. Used in #Beachcasts videos on YouTube.
Stars: ✭ 36 (+100%)
Mutual labels:  zend-expressive
ErrorHeroModule
💎 A Hero for your Zend Framework/Laminas, and Expressive/Mezzio application to log ( DB and Mail ) and handle php errors & exceptions during Mvc process/between request and response
Stars: ✭ 47 (+161.11%)
Mutual labels:  zend-expressive
zend-di-config
PSR-11 PHP-DI container configurator for Laminas, Mezzio, ZF, Expressive applications or any framework that needs a PSR-11 container
Stars: ✭ 19 (+5.56%)
Mutual labels:  zend-expressive
zend-problem-details
Provides Problem Details for HTTP APIs (RFC 7807) support for PSR-7 applications.
Stars: ✭ 50 (+177.78%)
Mutual labels:  zend-expressive
petstore
A simple skeleton to build api's based on the chubbyphp-framework, mezzio (former zend-expressive) or slim.
Stars: ✭ 34 (+88.89%)
Mutual labels:  zend-expressive
zombie-escape
🏃 Gamemode for Garry's Mod based on the popular Counter-Strike: Source server mod
Stars: ✭ 17 (-5.56%)
Mutual labels:  ze

Build Status Latest Stable Version Total Downloads License

Monolog Logger Middleware

Monolog Middleware to be used with PSR-7 middleware frameworks like Zend Expressive and Slim.

Now it does support Zend Expressive 3.*

To use with Zend Expressive 1.* please install version 1.1.4 To use with Zend Expressive 2.* please install version 2.0.0

loggables setting inspired by Guzzle Log Format. You can set any data in request/response/headers that you want to log from config file rather than in code to give more flexibility in logging more/less data based on your needs.

Installation

1) Install middleware using composer
composer require oras/monolog-middleware
2) Add configuration

Then in your Zend Expressive config/autoload/ directory, created a new config file call it: logger.local.php

As a starting point, you can have the following in the file:

use Monolog\Logger;

return [
    'monolog' =>
        [
            'logger_name' => 'MyLog',
            'loggables' => '[{host}] {request}/{response}', // optional and current one is default format that will be logged
            'handlers' =>
                [
                    'main'   =>
                        [
                            'type'   => 'stream',
                            'path'   => "data/main.log",
                            'level'  => Logger::DEBUG,
                            'bubble' => true,
                        ],
                ],
        ],
];

Please refer to Loggables list at end for all possible variables.

3) Add factory and middleware to dependencies.global.php file as follows:
'factories' => [

            \MonologMiddleware\MonologMiddleware::class => \MonologMiddleware\Factory\MonologMiddlewareFactory::class,
        ],
4) Now to start recording logs of request/response for a middleware, just put the following line after routing.

Example:

'routes' => [
        [
            'name' => 'home',
            'path' => '/',
            'middleware' => [
               App\Action\HomePageAction::class,
               \MonologMiddleware\MonologMiddleware::class,
               ],
            'allowed_methods' => ['GET'],
        ],
];

Now every time you call the route /, you'll get logs for request and response.

By default, MonologMiddleware will record logs in debug mode. If you want to handle different levels, just change level in config.

Requirements

  • PHP >= 7.1

Configuration examples

Full example of each implemented handler in Monolog Middleware. Please note that these might not be ALL handlers supported by Monolog, they are just the implemented in this middleware.

All lines are required unless stated.

Stream
$streamHandler = [
'main'   =>
    [
        'type'   => 'stream',
        'path'   => 'data/main.log',
        'level'  => Logger::DEBUG,
        'bubble' => true, // optional
    ],
];
Loggly
$logglyHandler = [
'loggly'   =>
    [
        'type'   => 'loggly',
        'token'   => 'your-loggly-token',
        'level'  => Logger::DEBUG,
        'bubble' => true, //optional
    ],
];
Slack
$slackHandler = [
'slack'   =>
    [
        'type'       => 'slack',
        'token'      => 'your-slack-token',
        'channel'    => '#your-slack-channel',
        'level'      => Logger::DEBUG,
        'icon_emoji' => '::ghost::', // optional
        'bubble'     => true, // optional
    ],
];
Pushover
$pushOverHandler = [
'pushover'   =>
    [
        'type'    => 'pushover',
        'token'   => 'your-pushover-token',
        'user'    => 'pushover user',
        'level'   => Logger::ERROR,
        'title'   => 'Log title', // optional
        'bubble'  => true, // optional
    ],
];
Native Email handler
$nativeEmailHandler = [
'native_email'   =>
    [
        'type'             => 'native_email',
        'level'            => Logger::CRITICAL,
        'from_email'       => '[email protected]',
        'to_email'         => '[email protected]',
        'subject'          => 'Email subject', // optional
        'max_column_width' => 70, //optional
        'bubble'           => true, // optional
    ],
];
Browser Console handler
$browserConsoleHandler = [
'browser_console'   =>
    [
        'type'    => 'browser_console',
        'level'   => Logger::DEBUG,
    ],
];
Redis handler
$redisHandler = [
'redis'   =>
    [
        'type'          => 'redis',
        'level'         => Logger::DEBUG,
        'redis_client'  => new \Redis(),
        'key'           => 'monolog',
    ],
];
FirePHP handler
$redisHandler = [
'firephp'   =>
    [
        'type'          => 'firephp',
        'level'         => Logger::DEBUG,
    ],
];
NewRelic handler
$redisHandler = [
'new_relic'   =>
    [
        'type'          => 'new_relic',
        'level'         => Logger::DEBUG,
        'app_name'      => 'Monolog', // optional
    ],
];

Loggables list

To log request/response body you can use {req_body} and {res_body} respectively in format setting.

Full list of logs variables with description:

Variable Substitution
{request} Full HTTP request message
{response} Full HTTP response message
{ts} Timestamp
{host} Host of the request
{method} Method of the request
{url} URL of the request
{host} Host of the request
{protocol} Request protocol
{version} Protocol version
{resource} Resource of the request (path + query + fragment)
{port} Port of the request
{hostname} Hostname of the machine that sent the request
{code} Status code of the response (if available)
{phrase} Reason phrase of the response (if available)
{curl_error} Curl error message (if available)
{curl_code} Curl error code (if available)
{curl_stderr} Curl standard error (if available)
{connect_time} Time in seconds it took to establish the connection (if available)
{total_time} Total transaction time in seconds for last transfer (if available)
{req_header_*} Replace * with the lowercased name of a request header to add to the message
{res_header_*} Replace * with the lowercased name of a response header to add to the message
{req_body} Request body
{res_body} Response body

Extending Middleware

To extend the middleware to log your own format, or specific data like cookies, server params .. etc. You can do that easily using the following steps:

  1. Create a factory class. I have named it MyMonologMiddlewareFactory which will call a MyMonologMiddleware class which will be your customised middleware to log.
class MyMonologMiddlewareFactory
{

    /**
     * @param ContainerInterface $serviceContainer
     * @return MonologMiddleware
     * @throws MonologConfigException
     */
    public function __invoke(ContainerInterface $serviceContainer)
    {
        $config = $serviceContainer->get('config');
        if (null === $config) {
            throw new MonologConfigException("Can not find monolog configuration in your config. Make sure to have monolog configuration array in your config");
        }

        $helper = new MonologConfigurationExtension($config['monolog']);
        $logHandlers = $helper->getLogHandlers();
        $loggerName = (isset($config['monolog']['logger_name']) ? $config['monolog']['logger_name'] : 'monolog');
        /**
         * @var Logger
         */
        $monologLogger = new Logger($loggerName);
        $monologLogger->setHandlers($logHandlers);

        return new MyMonologMiddleware($monologLogger);
    }
}
  1. Create Middleware class
class MonologMiddleware implements MiddlewareInterface
{
    /**
     * @var Logger
     */
    protected $logger;

    /**
     * MonologMiddleware constructor.
     * @param Logger $logger
     */
    public function __construct(Logger $logger)
    {
        $this->logger = $logger;
    }


    /**
     * @param ServerRequestInterface $request
     * @param ResponseInterface $response
     * @param callable $next
     * @return mixed
     */
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
    {
        // Here you set logger level, message or any data that you'd like from your request or response.
        // For example, I am going to log cookie params

        $this->logger->addInfo(Logger::INFO, implode(", ", $request->getCookieParams());
        return $next($request, $response);
    }

}
  1. Add your factory and middleware to global dependency file. Assuming you have your middleware and factory in the same directory, the config will be:
    'factories' => [
            MyMonologMiddleware::class => MyMonologMiddlewareFactory::class,
    ],

That's it ... you're ready to use your own customised logger.

Monolog Middleware was written during my commute time. Written with passion on SouthWest Trains. Please mind the gap!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].