I'm writing a couple of laravel packages and I'm wondering if it is possible to have the package write to a specific log file but only for messages related to the package?
I tried making a logging.php file in the packages/myorg/mypackage/config (below) but it doesn't seem to do anything.
use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
return [
'default' => env('LOG_CHANNEL', 'stack'),
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/mypackage.log'),
'level' => env('LOG_LEVEL', 'debug'),
]
]
];
I am using "jeroen-g/laravel-packager" to set up the packages. It appears to manually load the mypackage.config in the ServiceProvider bootForConsole
protected function bootForConsole(): void
{
// Publishing the configuration file.
$this->publishes([
mypackage.'/../config/mypackage.php' => config_path('mypackage.php'),
], 'mypackage.config');
}
I'm not sure how to add custom logging to that though. I'm still learning Laravel and I'm not quite sure what or how the main applications config/logging.php is read so I'm not quite sure how to inject a custom version for an add-on package.
EDIT:
I found a post that suggested using the following in the ServiceManager boot() method:
$this->app->make('config')->set('logging.channels.mychannel', [
/* settings */
]);
I used the package config to set a 'logging' => [ 'channels' => [ 'mychannel' => [ /* settings */ ] ] ] and could then do the same thing as above with:
$this->app->make('config')->set('logging.channels.mychannel', config('mypackage.logging.channels.mychannel');
But that still required something in the code. The next best thing I have found thus far is to change my config/logging.php to config/logging.channels.php and include something like:
return [
'mychannel' => [
'driver' => 'single',
'path' => storage_path('logs/mypackage.log'),
'level' => env('LOG_LEVEL', 'debug'),
]
];
Then in the service provider register() method add:
$this->mergeConfigFrom(__DIR__ . '/../config/logging.channels.php', 'logging.channels');
I tried doing it from the original 'logging.php' with channels array nested in a 'logging' key, but array_merge doesn't appear to merge the nested elements so my channel never showed up in logging.channels.
I'm not sure if this is ideal, however. I'd still like to know if there is a 'better' or best practices way of adding custom package logging parameters and whether there is a need to publish it in any way (and how).
I am trying to see the traceLine on Yii2 debug bar like explains in (https://github.com/yiisoft/yii2-debug#open-files-in-ide), but I can't see it.
I have Yii2 2.0.28 and debug-bar 2.1.9 with php 7.2.19
For example: is there any way, inspecting any debug bar’s panel, to know which line of my code thrown a trace/profile action in the debug bar?
Or how can I see where is located any query I am seeing in the database panel?
My config:
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
'traceLine' => '{file}:{line}',
'allowedIPs' => ['*'],
'panels' => [
'db' => [
'class' => 'yii\debug\panels\DbPanel',
'defaultOrder' => [
'seq' => SORT_ASC
],
'defaultFilter' => [
'type' => 'SELECT'
]
],
],
];
There are two properties in configuration that affect how the files are displayed in logs in debug bar.
1) traceLine property of debug module. This property contains a template for displaying single line of trace.
In configuration it may look like this
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
'traceLine' => '{file}:{line}',
// ... other debug module configurations
]
2) traceLevel property of log component. This affect how many calls will be displayed in trace. The calls of framework's classes are not displayed in debug toolbar, only your files are displayed.
The configuration might look like this
'components' => [
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
// ... other log component configurations
],
// ... other components
],
In the example the traceLevel depends on YII_DEBUG constant. This is used to avoid performance issues in production environments. This is also how traceLevel is set in default yii2 application templates.
The YII_DEBUG constant is usually set in index.php file like this
defined('YII_DEBUG') or define('YII_DEBUG', true);
I'm setting up Laravel echo to broadcast events. But whenever I try to broadcast to a channel the channel name gets an automatic prefix: 'laravel_database_'
I've tried switching the return inside the Event to a regular 'Chanel' as following:
public function broadcastOn()
{
return new Channel('public');
}
but when I look into the laravel-echo-server logs I see it is still being broadcasted on: 'laravel_database_public'.
This way I would need to do the following in my JS:
Echo.channel('laravel_database_public').listen('MessageSent', ({message}) => {
console.log(message);
});
But ofcourse, I want to remove the prefix (or figure out why its there). Hopefully someone can clear this up for me. Thanks in advance.
This is configurable in config/database.php (and I believe even removable) under
'redis' => [
'options' => [
'prefix' => // change here.
]
]
The accepted answer does not work with laravel-echo-server.
The solution is rather to let the whole Redis Laravel config untouched and to run version ^1.6.0 of laravel-echo-server with the proper keyPrefix option in laravel-echo-server.json config file:
{
"databaseConfig": {
"redis": {
"keyPrefix": "laravel_database_"
}
}
}
Source
As at Laravel 7, the config/database.php looks like this
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'),
],
]
So it searches the .env file for your REDIS_PREFIX variable, if there's none, then it generates laravel_database_ or based on whatever you set APP_NAME to in your .env file.
All you have to do is set your REDIS_PREFIX. You can leave it empty so that there is no prefix at all.
I'm using Laravel 5.4 and spatie/laravel-backup v3 and flysystem-google-drive
"nao-pon/flysystem-google-drive": "~1.1"
https://github.com/spatie/laravel-backup
I am able to upload files using
Storage::disk('google')->put('FileName.txt', "hello world");
But with Spatie/laravel-backup package I'm getting the following error while using destination disk as 'google'.
Can you help me regarding this?
Filesystem:
'google' => [
'driver' => 'google',
'clientId' => env('GOOGLE_DRIVE_CLIENT_ID'),
'clientSecret' => env('GOOGLE_DRIVE_CLIENT_SECRET'),
'refreshToken' => env('GOOGLE_DRIVE_REFRESH_TOKEN'),
'folderId' => env('GOOGLE_DRIVE_FOLDER_ID'),
],
This Is Common Bug When Dealing With Laravel-backup And flysystem-google-drive What I Did To Solve This Problem In Production .
Go To Your .env File :
Change APP_URL=http://localhost To APP_URL= http://YourDomainName
Go To Your /config/backup.php
Change The Line
'name' => config('app.name'),
//To
'name' => env('GOOGLE_DRIVE_FOLDER_ID'),
Now You Should Receive Your Backup
I was getting error "message": "File not found: 6666666Jo8AWLW-LI-XSR5n4z_7KVfNer."
The reason is in the name of the folder that was generated by Google Drive.
Because when I created a new folder, it had a new name "888888RrZx-wXq91XVWd9ZsfrK8X6-yZ" - everything worked.
I think the problem was because of the underscore in GOOGLE_DRIVE_FOLDER_ID.
only pass null name in backup.php
'name' => config('GOOGLE_DRIVE_FOLDER_ID' , ''),
like this will be resolved
'backup' => [
/*
* The name of this application. You can use this name to monitor
* the backups.
*/
'name' => config('GOOGLE_DRIVE_FOLDER_ID' , ''),
'source' => [
How can I hide my passwords and other sensitive environment variables on-screen in Laravel's whoops output?
Sometimes other people are looking at my development work. I don't want them to see these secrets if an exception is thrown, but I also don't want to have to keep toggling debug on and off, or spin up a dedicated site just for a quick preview.
As of Laravel 5.5.13, you can censor variables by listing them under the key debug_blacklist in config/app.php. When an exception is thrown, whoops will mask these values with asterisks * for each character.
For example, given this config/app.php
return [
// ...
'debug_blacklist' => [
'_ENV' => [
'APP_KEY',
'DB_PASSWORD',
'REDIS_PASSWORD',
'MAIL_PASSWORD',
'PUSHER_APP_KEY',
'PUSHER_APP_SECRET',
],
'_SERVER' => [
'APP_KEY',
'DB_PASSWORD',
'REDIS_PASSWORD',
'MAIL_PASSWORD',
'PUSHER_APP_KEY',
'PUSHER_APP_SECRET',
],
'_POST' => [
'password',
],
],
];
Results in this output:
First of all, love the solution by Jeff above.
2nd, if like me you wanna hide all the env variables while still use whoops, here is a solution:
'debug_blacklist' => [
'_COOKIE' => array_keys($_COOKIE),
'_SERVER' => array_keys($_SERVER),
'_ENV' => array_keys($_ENV),
],
Output:
EDIT:
Legend has it that since laravel 7x you would need debug_hide key instead
Thanks Jeff and Raheel for helping out, but I just found a little gotcha:
Even if I clear out all environment keys from _ENV, the same keys are STILL exposed through the _SERVER variables listed.
Adding the code below in config/app.php would hide all environment variables from the whoops page:
'debug_blacklist' => [
'_SERVER' => array_keys($_ENV),
'_ENV' => array_keys($_ENV),
],
I've made a package to solve this problem.
Just install it using
composer require glaivepro/hidevara
Most of the server and all the env variables will be removed. Any password-like fields in $_POST will have their values hidden.
You can also customize it in either blacklist or whitelist approach to show/obfuscate/remove fields however you like.
The solution by #jeff + #raheel is great!!! On a project recently we found we sometimes wanted to whitelist a property or two, so building on the above, you can whitelist specific properties you want to debug with something like:
'debug_blacklist' => [
'_COOKIE' => array_diff(array_keys($_COOKIE), array()),
'_SERVER' => array_diff(array_keys($_SERVER), array('APP_URL', 'QUERY_STRING')),
'_ENV' => array_diff(array_keys($_ENV), array()),
],
If you want to allow that list to be configured via .env, you can do something like:
'debug_blacklist' => [
'_COOKIE' => array_diff(
array_keys($_COOKIE),
explode(",", env('DEBUG_COOKIE_WHITELIST', ""))
),
'_SERVER' => array_diff(
array_keys($_SERVER),
explode(",", env('DEBUG_SERVER_WHITELIST', ""))
),
'_ENV' => array_diff(
array_keys($_ENV),
explode(",", env('DEBUG_ENV_WHITELIST', ""))
),
],
Then in your .env, do something like:
DEBUG_SERVER_WHITELIST="APP_URL,QUERY_STRING"
Cheers!
Usually for local development, we should set the APP_DEBUG environment variable to true. So that we can have better insights of the debugging error and warnings.
But in the production environment, this value should always be false. If the value is set to true in production, you risk exposing sensitive env passwords to your application’s end users.
As of Laravel 5.5.x also provides a solution for it.
You just need to add the debug_blacklist option in your config/app.php configuration file. After adding this option, Laravel will blacklist all the keys mentioned in debug_blacklist option with asterisk.
You can use it with two ways:
Method 1 – Blacklist selective ENV keys and passwords
return [
// ...
'debug_blacklist' => [
'_ENV' => [
'APP_KEY',
'DB_PASSWORD',
],
'_SERVER' => [
'APP_KEY',
'DB_PASSWORD',
],
'_POST' => [
'password',
],
],
];
Method 2 – Blacklist all the ENV keys and passwords
return [
// ...
'debug_blacklist' => [
'_COOKIE' => array_keys($_COOKIE),
'_SERVER' => array_keys($_SERVER),
'_ENV' => array_keys($_ENV),
],
]
Reference Taken From : https://techjeni.com/how-to-secure-and-hide-env-passwords-from-laravel-debug-output/
Laravel 5.6 not works for my.
but this works:
$envKeys = [];
$serverKeys = [];
$cookieKeys = [];
foreach ( $_ENV as $key => $value ) { if(is_string($value)) $envKeys[] = $key; }
foreach ( $_SERVER as $key => $value ) { if(is_string($value)) $serverKeys[] = $key; }
foreach ( $_COOKIE as $key => $value ) { if(is_string($value)) $cookieKeys[] = $key; }
return [
// ...
'debug_blacklist' => [
'_COOKIE' => $cookieKeys,
'_SERVER' => $serverKeys,
'_ENV' => $envKeys,
],
];
I would be grateful for a better solution.
Just Change
APP_DEBUG=true
To:
APP_DEBUG=false
In the .env file.
For Laravel 5.6-5.8:
'debug_blacklist' => [
'_COOKIE' => array_keys(array_filter($_COOKIE, function($value) {return is_string($value);})),
'_SERVER' => array_keys(array_filter($_SERVER, function($value) {return is_string($value);})),
'_ENV' => array_keys(array_filter($_ENV, function($value) {return is_string($value);})),
],
I am also facing this issue in production environment, Laravel 5.7
https://laravel.com/docs/5.7/configuration
Here 3 ways we can reslove this issue.
config/app.php file add below line of code
TIPS #1: Block List for all variable
'debug_blacklist' => [
'_COOKIE' => array_keys($_COOKIE),
'_SERVER' => array_keys($_SERVER),
'_ENV' => array_keys($_ENV),
],
TIPS #2: Block List for specific varaibles (Best Practice)
return [
// ...
'_ENV' => [
'APP_KEY',
'DB_PASSWORD',
'REDIS_PASSWORD',
'MAIL_PASSWORD',
'PUSHER_APP_KEY',
'PUSHER_APP_SECRET',
'AWS_APP_SECRET',
'S3_BUCKET_SECRET',
'SOCKET_APP_SECRET',
'TWILIO_APP_SECRET',
],
'_SERVER' => [
'APP_KEY',
'DB_PASSWORD',
],
'_POST' => [
'password',
],
]
TIPS #3: Debug variable
APP_DEBUG=true to APP_DEBUG=false
NOTE:
Production enviroment keep always Debug False
There's a lot of great answers here (credits to #Jeff and #Raheel and #Benjamin and everyone else), but I would like to have a bit more flexible and universal solution. I extended this snippet intended for the config/app.php file even further:
$debug_blacklist=array();
if(env("DEBUG_VAR_LISTING")!==null)
foreach(explode(",", env("DEBUG_VAR_LISTING", "")) as $i){
global ${"_{$i}"};
if(env("DEBUG_VAR_BLACKLIST_{$i}")!==null)
$debug_blacklist["_{$i}"]=explode(",", env("DEBUG_VAR_BLACKLIST_{$i}", ""));
elseif(env("DEBUG_VAR_WHITELIST_{$i}")!==null)
$debug_blacklist["_{$i}"]=array_diff(
array_keys(${"_{$i}"}),
explode(",", env("DEBUG_VAR_WHITELIST_{$i}", ""))
);
}
return [
'debug_blacklist' => $debug_blacklist,
];
Then you can blacklist and whitelist directly in .env and only if and what you need.
So if you don't really need anything from $_ENV you can block all variables and for example just passwords in $_POST, but show APP_URL and QUERY_STRING from $_SERVER:
DEBUG_VAR_LISTING="SERVER,ENV,POST,COOKIE"
DEBUG_VAR_WHITELIST_SERVER="APP_URL,QUERY_STRING"
DEBUG_VAR_WHITELIST_ENV=""
DEBUG_VAR_BLACKLIST_POST="password"
I struggled with this too for a bit on a dev machine. my solution was to edit vendor/filp/whoops/src/Whoops/Handler/PrettyPageHandler.php and add in:
public function sanitizePrivate($data, $badwords){
foreach ($data as $key=>$value) {
foreach ($badwords as $keyword) {
// dd($key);
if (strpos(strtolower($key), $keyword) !== FALSE) {
$data[$key] = "***************";
}
}
}
return $data;
}
This converts all the incoming data to lowercase and then searches for partial matches so you don't have to specify every variation of password variable names. Then in the handle() function, define terms you want to exclude.
$badwords = array("password", "pwd", "secret", "key", "token", "salt", "mail");
$_SERVER=$this->sanitizePrivate($_SERVER, $badwords);
$_ENV=$this->sanitizePrivate($_ENV, $badwords);