All Projects → dmitry-ivanov → Laravel Console Logger

dmitry-ivanov / Laravel Console Logger

Licence: mit
Logging and Notifications for Laravel Console Commands.

Projects that are alternatives of or similar to Laravel Console Logger

Laravel Desktop Notifier
💻 Send notifications to your desktop from your Laravel Artisan Commands. An JoliNotif wrapper for Laravel.
Stars: ✭ 333 (+321.52%)
Mutual labels:  console, laravel, notifications
Project
⭐️ Antares Project Application Skeleton. This is the very first place you should start. It allows you to create a brand new awesome project in easy few steps.
Stars: ✭ 84 (+6.33%)
Mutual labels:  laravel, notifications, logger
Laravel Log
Simple API to write logs for Laravel.
Stars: ✭ 19 (-75.95%)
Mutual labels:  laravel, laravel-package, logger
Sneaker
An easy way to send emails whenever an exception occurs on server.
Stars: ✭ 223 (+182.28%)
Mutual labels:  error-handling, laravel, laravel-package
Snooze
A package to simplify automating future notifications and reminders in Laravel
Stars: ✭ 515 (+551.9%)
Mutual labels:  laravel, laravel-package, notifications
Laravel Notify
Flexible Flash notifications for Laravel
Stars: ✭ 787 (+896.2%)
Mutual labels:  laravel, laravel-package, notifications
Laravel Database Logger
Log database query sql in Laravel Application, support Guard,Auth to multiple file record
Stars: ✭ 31 (-60.76%)
Mutual labels:  laravel, laravel-package, logger
Laravel Opcache
Laravel Package for OPcache
Stars: ✭ 1,116 (+1312.66%)
Mutual labels:  laravel, laravel-package
Laravel Email Verification
Laravel package to handle user verification using an activation mail
Stars: ✭ 63 (-20.25%)
Mutual labels:  laravel, laravel-package
Laravel Api Health
Monitor first and third-party services and get notified when something goes wrong!
Stars: ✭ 65 (-17.72%)
Mutual labels:  laravel, laravel-package
Laravel Remember Uploads
Laravel Middleware and helper for remembering file uploads during validation redirects
Stars: ✭ 67 (-15.19%)
Mutual labels:  laravel, laravel-package
Notifier
NO LIBRARIES socket per page bridge for your Laravel application. (CLIENT PART INCLUDED)
Stars: ✭ 57 (-27.85%)
Mutual labels:  laravel, notifications
Shopping Cart
An easy-to-use shopping cart for Laravel
Stars: ✭ 57 (-27.85%)
Mutual labels:  laravel, laravel-package
Laravel Schedulable
Schedule and unschedule eloquent models elegantly without cron jobs
Stars: ✭ 78 (-1.27%)
Mutual labels:  laravel, laravel-package
Response Xml
The missing XML support for Laravel's Response class.
Stars: ✭ 56 (-29.11%)
Mutual labels:  laravel, laravel-package
Backup
MySQL Database backup package for Laravel
Stars: ✭ 66 (-16.46%)
Mutual labels:  laravel, laravel-package
Laravel Fcm
🌐 A Laravel package to send Push Notifications to one or many devices of the user.
Stars: ✭ 56 (-29.11%)
Mutual labels:  laravel, notifications
Signale
Highly configurable logging utility
Stars: ✭ 8,575 (+10754.43%)
Mutual labels:  console, logger
Eloquent Approval
Approval process for Laravel Eloquent models
Stars: ✭ 79 (+0%)
Mutual labels:  laravel, laravel-package
Fast Excel
🦉 Fast Excel import/export for Laravel
Stars: ✭ 1,183 (+1397.47%)
Mutual labels:  laravel, laravel-package

Logging and Notifications for Laravel Console Commands

Laravel Console Logger

Become a Patron

StyleCI Build Status Coverage Status

Packagist Version Packagist Stars Packagist Downloads Packagist License

Logging and Notifications for Laravel Console Commands.

Laravel Console Logger
8.x 8.x
7.x 7.x
6.x 6.x
5.8.* 5.8.*
5.7.* 5.7.*
5.6.* 5.6.*
5.5.* 5.5.*
5.4.* 5.4.*
5.3.* 5.3.*
5.2.* 5.2.*
5.1.* 5.1.*

Laravel Console Logger - Demo

Table of contents

Usage

  1. Install the package via Composer:

    composer require illuminated/console-logger
    
  2. Use Illuminated\Console\Loggable trait:

    use Illuminated\Console\Loggable;
    
    class ExampleCommand extends Command
    {
        use Loggable;
    
        public function handle()
        {
            $this->logInfo('Hello World!');
        }
    
        // ...
    }
    
  3. Run the command and check your logs:

    [2020-05-11 17:19:21]: [INFO]: Command `App\Console\Commands\ExampleCommand` initialized.
    [2020-05-11 17:19:21]: [INFO]: Host: `MyHost.local` (`10.0.1.1`).
    [2020-05-11 17:19:21]: [INFO]: Database host: `MyHost.local`, port: `3306`, ip: ``.
    [2020-05-11 17:19:21]: [INFO]: Database date: `2020-05-11 17:19:21`.
    [2020-05-11 17:19:21]: [INFO]: Hello World!
    [2020-05-11 17:19:21]: [INFO]: Execution time: 0.009 sec.
    [2020-05-11 17:19:21]: [INFO]: Memory peak usage: 8 MB.
    

Available methods

The Loggable trait provides these PSR-3 methods:

  • logDebug()
  • logInfo()
  • logNotice()
  • logWarning()
  • logError()
  • logCritical()
  • logAlert()
  • logEmergency()

Use them in your console commands to log required information.

Channels

Log messages could be handled in multiple different ways.

It might be writing data into the log file, storing it in the database, sending an email, etc.

File channel

File channel simply writes log messages into the log file.

Each of the commands would have a separate folder within the storage/logs dir.

For example, foo-bar command logs would be stored in the storage/logs/foo-bar folder.

You can customize the storage folder, and the max number of stored log files by overriding proper methods:

class ExampleCommand extends Command
{
    use Loggable;

    protected function getLogPath()
    {
        return storage_path('logs/custom-folder/date.log');
    }

    protected function getLogMaxFiles()
    {
        return 45;
    }

    // ...
}

Notification channels

If you want to be notified about errors in your console commands - use notification channels.

Notification channels are optional and disabled by default. Each of them could be enabled and configured as needed.

By default, you'll get notifications with a level higher than NOTICE (see PSR-3 log levels). It means that you'll get NOTICE, WARNING, ERROR, CRITICAL, ALERT, and EMERGENCY notifications, by default.

Of course, you can customize that, as well as other channel-specific details.

Email channel

The email channel provides notifications via email.

Set the recipients, and email notifications are ready to go!

class ExampleCommand extends Command
{
    use Loggable;

    protected function getEmailNotificationsRecipients()
    {
        return [
            ['address' => '[email protected]', 'name' => 'John Doe'],
            ['address' => '[email protected]', 'name' => 'Jane Smith'],
        ];
    }

    // ...
}

There's a bunch of methods related to the email channel.

By overriding those methods, you can change the subject, from address, notification level, etc.

Deduplication is another useful feature worth mentioning. Sometimes the same error might occur many times in a row. For example, you're using an external web service that is down. Or imagine that the database server goes down. You'll get a lot of similar emails in those cases. Deduplication is the right solution for that.

You can enable it and adjust the time in seconds, for which deduplication works:

class ExampleCommand extends Command
{
    use Loggable;

    protected function useEmailNotificationsDeduplication()
    {
        return true;
    }

    protected function getEmailNotificationsDeduplicationTime()
    {
        return 90;
    }

    // ...
}

Database channel

The database channel provides a way to save notifications in the database.

The easiest way to start using it:

class ExampleCommand extends Command
{
    use Loggable;

    protected function useDatabaseNotifications()
    {
        return true;
    }

    // ...
}

Notifications would be stored in the iclogger_notifications table, which would be automatically created if it doesn't exist yet.

Of course, you can customize the table name, and even the saving logic, by overriding proper methods:

class ExampleCommand extends Command
{
    use Loggable;

    protected function useDatabaseNotifications()
    {
        return true;
    }

    protected function getDatabaseNotificationsTable()
    {
        return 'custom_notifications';
    }

    protected function getDatabaseNotificationsCallback()
    {
        return function (array $record) {
            CustomNotification::create([
                'level' => $record['level'],
                'level_name' => $record['level_name'],
                'message' => $record['message'],
                'context' => get_dump($record['context']),
                'custom_field' => 'Foo Bar Baz!',
            ]);
        };
    }

    // ...
}

Error handling

Another cool feature that is enabled by default - is error handling.

The package automatically logs everything for you: severe problems - exceptions and fatal errors, and even small things, such as PHP notices and warnings.

Add notifications to that, and you'll immediately know when something goes wrong in your console commands!

Exceptions with context

Sometimes it's useful to pass an additional context of the thrown exception.

Use the Illuminated\Console\Exceptions\RuntimeException for that:

use Illuminated\Console\Exceptions\RuntimeException;

class ExampleCommand extends Command
{
    use Loggable;

    public function handle()
    {
        throw new RuntimeException('Whoops! We have a problem!', [
            'some' => 123,
            'extra' => true,
            'context' => null,
        ]);
    }

    // ...
}
[2020-05-11 17:19:21]: [ERROR]: Whoops! We have a problem!
array:5 [
    "code" => 0
    "message" => "Whoops! We have a problem!"
    "file" => "/Applications/MAMP/htdocs/icl-test/app/Console/Commands/ExampleCommand.php"
    "line" => 22
    "context" => array:3 [
        "some" => 123
        "extra" => true
        "context" => null
    ]
]

Guzzle 6+ integration

If you're using Guzzle, you might want to have a full log of your HTTP interactions.

The iclogger_guzzle_middleware() function provides a pre-configured Guzzle Middleware for that:

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;

// Create a log middleware
$logMiddleware = iclogger_guzzle_middleware($logger);

// Add it to the HandlerStack
$handler = HandlerStack::create();
$handler->push($logMiddleware);

// Use the created handler in your Guzzle Client
$client = new Client([
    'handler' => $handler,
    'base_uri' => 'https://example.com',
]);

// Now, all your HTTP requests and responses would be logged automatically!
// $client->get('/foo');

If you're using JSON, you might want to get auto decoding for your request params and response bodies:

$logMiddleware = iclogger_guzzle_middleware($logger, 'json');

Also, you can disable logging of specific request params and/or response bodies, based on your custom logic:

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

// Disable logging of request params for the `/foo` endpoint
$shouldLogRequestParams = function (RequestInterface $request) {
    return ! str_ends_with($request->getUri(), '/foo');
};

// Disable logging of response bodies greater than 100 KB
$shouldLogResponseBody = function (RequestInterface $request, ResponseInterface $response) {
    return $response->getHeaderLine('Content-Length') < 102400;
};

$logMiddleware = iclogger_guzzle_middleware($logger, 'json', $shouldLogRequestParams, $shouldLogResponseBody);

Powered by Monolog

This package uses the powerful Monolog Logger.

You can access the underlying instance of Monolog by:

  • Using the command's icLogger() method:

    class ExampleCommand extends Command
    {
        use Loggable;
    
        public function handle()
        {
            $logger = $this->icLogger();
        }
    
        // ...
    }
    
  • Or via the Laravel's Service Container:

    $logger = app('log.iclogger');
    

Troubleshooting

Trait included, but nothing happens?

Loggable trait overrides the initialize() method:

trait Loggable
{
    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        $this->initializeLogging();

        parent::initialize($input, $output);
    }

    // ...
}

If your command overrides the initialize() method too, you have to call the initializeLogging() method by yourself:

class ExampleCommand extends Command
{
    use Loggable;

    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        // You have to call it first
        $this->initializeLogging();

        // Then goes your custom code
        $this->foo = $this->argument('foo');
        $this->bar = $this->argument('bar');
        $this->baz = $this->argument('baz');
    }

    // ...
}

Several traits conflict?

If you're using another illuminated/console-% package, you'll get the "traits conflict" error.

For example, if you're building a loggable command, which doesn't allow overlapping:

class ExampleCommand extends Command
{
    use Loggable;
    use WithoutOverlapping;

    // ...
}

You'll get the traits conflict, because both of those traits are overriding the initialize() method:

If two traits insert a method with the same name, a fatal error is produced, if the conflict is not explicitly resolved.

To fix that - override the initialize() method and resolve the conflict:

class ExampleCommand extends Command
{
    use Loggable;
    use WithoutOverlapping;

    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        // Initialize conflicting traits
        $this->initializeMutex();
        $this->initializeLogging();
    }

    // ...
}

Sponsors

Laravel Idea

License

Laravel Console Logger is open-sourced software licensed under the MIT license.

Support on Patreon

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