Skip to content

Instantly share code, notes, and snippets.

@qumberrizvi
Last active July 14, 2020 06:28
Show Gist options
  • Save qumberrizvi/f43933521a3d1aec11d4bf10d49675b2 to your computer and use it in GitHub Desktop.
Save qumberrizvi/f43933521a3d1aec11d4bf10d49675b2 to your computer and use it in GitHub Desktop.
Log events / exceptions to CloudWatch and local filesystem in your Laravel / Lumen app.
<?php
//File location: App\Exceptions\
namespace App\Exceptions;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Validation\ValidationException;
use Laravel\Lumen\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use App\Traits\Logit as Log;
class Handler extends ExceptionHandler
{
use Log;
/**
* A list of the exception types that should not be reported.
*
* @var array
*/
protected $dontReport = [
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
ValidationException::class,
];
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
Log::debug($exception, ['error' => $exception]); //This is where you Log the message.
parent::report($exception); //Using this will APP_ENV=local will cause each exception to be logged twice on the local log file.
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*/
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
}
<?php
//File location: App\Traits\
namespace App\Traits;
use Aws\CloudWatchLogs\CloudWatchLogsClient;
use Maxbanton\Cwh\Handler\CloudWatch;
use Monolog\Logger;
use Monolog\Formatter\JsonFormatter;
use Log;
/*
Required dependencies/packages:
Run:
composer require aws/aws-sdk-php-laravel:~3.4
composer require maxbanton/cwh:^1.0
Or put this in your composer.json in require:{}:
"aws/aws-sdk-php-laravel": "~3.4",
"maxbanton/cwh": "^1.0"
then run composer update.
Put this file in app/Traits directory of your Laravel/Lumen Codebase.
*/
trait Logit {
//Configuration to Log events on CloudWatch
static function configure()
{
$sdkParams = [
'region' => env('CLOUDWATCH_LOG_REGION'),
'version' => 'latest',
'credentials' => [
'key' => env('CLOUDWATCH_LOG_KEY'),
'secret' => env('CLOUDWATCH_LOG_SECRET')
]
];
$client = new CloudWatchLogsClient($sdkParams);
$groupName = env('CLOUDWATCH_LOG_GROUP_NAME');
$streamName = env('CLOUDWATCH_LOG_STREAM_NAME');
$retentionDays = env('CLOUDWATCH_LOG_RETENTION_DAYS');
$handler = new CloudWatch($client, $groupName, $streamName, $retentionDays, 10000);
$handler->setFormatter(new JsonFormatter());
$log = new Logger(env('CLOUDWATCH_CHANNER_NAME'));
$log->pushHandler($handler);
return $log;
}
static function debug(...$message) {
if (env('APP_ENV') == 'local') {
//If env('APP_ENV') is set to local, event will get logged on your local filesystem.
Log::debug(...$message);
} else {
//If env('APP_ENV') is NOT set to local, event will get logged on CloudWatch.
$log = Self::configure();
$log->debug(...$message);
}
return response()->json(['status' => 'success']);
}
static function info(...$message) {
if (env('APP_ENV') == 'local') {
Log::info(...$message);
} else {
$log = Self::configure();
$log->info(...$message);
}
return response()->json(['status' => 'success']);
}
static function notice(...$message) {
if (env('APP_ENV') == 'local') {
Log::notice(...$message);
} else {
$log = Self::configure();
$log->notice(...$message);
}
return response()->json(['status' => 'success']);
}
static function warning(...$message) {
if (env('APP_ENV') == 'local') {
Log::warning(...$message);
} else {
$log = Self::configure();
$log->warning(...$message);
}
return response()->json(['status' => 'success']);
}
static function error(...$message) {
if (env('APP_ENV') == 'local') {
Log::error(...$message);
} else {
$log = Self::configure();
$log->error(...$message);
}
return response()->json(['status' => 'success']);
}
static function critical(...$message) {
if (env('APP_ENV') == 'local') {
Log::critical($message);
} else {
$log = Self::configure();
$log->critical(...$message);
}
return response()->json(['status' => 'success']);
}
static function alert(...$message) {
if (env('APP_ENV') == 'local') {
Log::alert(...$message);
} else {
$log = Self::configure();
$log->alert(...$message);
}
return response()->json(['status' => 'success']);
}
static function emergency(...$message) {
if (env('APP_ENV') == 'local') {
Log::emergency(...$message);
} else {
$log = Self::configure();
$log->emergency(...$message);
}
return response()->json(['status' => 'success']);
}
}
<?php
//File location: App\Http\Controllers\
namespace App\Http\Controllers;
use App\Traits\Logit; //Required
class TheExampleController extends Controller
{
use Logit; //Required
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
//
}
public function log()
{
/*
Additionally, the follwing variables MUST exist in your .env file:
APP_ENV=local,test,dev,prod,etc : If set to local, logs will get stored locally, otherwise on CloudWatch
CLOUDWATCH_LOG_REGION=us-west-2, etc.
CLOUDWATCH_LOG_KEY=
CLOUDWATCH_LOG_SECRET=
CLOUDWATCH_LOG_GROUP_NAME=Name_of_the_log_group_goes_here
CLOUDWATCH_LOG_STREAM_NAME=Name_of_the_stream_goes_here
CLOUDWATCH_CHANNER_NAME=Channel_name_goes_here : Whatever name you choose here will be reflected in the bodies of the logs on CloudWatch
CLOUDWATCH_LOG_RETENTION_DAYS:14 : Days util when you want to keep the logs.
8 different logging levels available are:
Logit::debug('Message');
Logit::info('Message');
Logit::notice($error);
Logit::warning($error);
Logit::error($error);
Logit::critical($error);
Logit::alert($error);
Logit::emergency($error);
*/
Logit::debug('Test log', ['foo' => 'bar']); //Pass context as an array, if you have to.
return response()->json('Logged', 200);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment