I'm getting Yii2
Error (#8)
An internal server error occurred.
but it can not be found in logs.
Neither in .access .error files for this apache vhost nor in apache logs
This happens on remote server and I can't reproduce it locally. Is there any other way to see what the error is aside from changing error_reporting on remote server?
Make sure that you have specified a log target in your configuration and the log component is loaded during bootstrapping.
Example:
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
],
];
Also, check your exportInterval and flushInterval setting.
From the documentation:
Log messages are maintained in an array by the logger object. To limit the memory consumption by this array, the logger will flush the recorded messages to the log targets each time the array accumulates a certain number of log messages. You can customize this number by configuring the flushInterval property of the log component:
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'flushInterval' => 100, // default is 1000
'targets' => [...],
],
],
];
When the logger object flushes log messages to log targets, they do not get exported immediately. Instead, the message exporting only occurs when a log target accumulates certain number of the filtered messages. You can customize this number by configuring the exportInterval property of individual log targets, like the following,
[
'class' => 'yii\log\FileTarget',
'exportInterval' => 100, // default is 1000
]
Because of the flushing and exporting level setting, by default when you call Yii::trace() or any other logging method, you will NOT see the log message immediately in the log targets. This could be a problem for some long-running console applications. To make each log message appear immediately in the log targets, you should set both flushInterval and exportInterval to be 1, as shown below:
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'flushInterval' => 1,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'exportInterval' => 1,
],
],
],
],
];
Note: Frequent message flushing and exporting will degrade the performance of your application.
Related
I am trying to log a webhook response to a custom log file custom.log which is saved on config/logs/custom.log path. I can easily log the webhook to the debug.log file in the same directory by
Log::debug('my desired logs)
How can I log the same log in the custom.log file. Thank you
// Configure logs/custom.log to receive all levels, but only
// those with `custom` scope.
Log::config('custom', [
'className' => 'File',
'path' => LOGS,
'levels' => [],
'scopes' => ['custom'],
'file' => 'custom.log',
]);
Log::debug('this gets written only to custom.log', ['scope' => ['custom']]);
I'm tightening up the logging for our Yii2 application and are struggling with getting the Logger to actually write messages to a log file when dealing with specific categories.
Our project consists of the following Yii2 'Applications' : console, common, frontend, backend and the logging for each of these components work fine for Exceptions generated by Yii and general PHP Exceptions. However when I add some info messages for a specific category in the console part (which I execute by running commands via SHH) the directory that the file should be in is created but the file itself is not. I see that the newly specified log messages are inside the correct 'FileTarget' when I do a var_dump of it.
I've set the flushInterval of the 'log' component to 1 and the exportInterval of the logTarget to 1 to make sure that the messages are to be written to the targets directly. I'm aware that this should be set to a larger value at some point, but for now I want to make sure that the logs are actually being saved. Changing the interval values doesn't seem to have any effect.
A workaround I came up with is to manually call target->export() for the specific FileTarget. This is how I currently make sure logs are being written:
In the Controller where I want to log message I do
Yii::info('Report created succesfully.', 'reports-create');
UtilitiesController::forceLogExport('reports-create');
The forceLogExport method does this:
public function forceLogExport($categoryName = ''){
$logger = \Yii::getLogger();
foreach($logger->dispatcher->targets as $target){
if(!empty($categoryName)){
foreach($target->categories as $category){
if($category == $categoryName){
$target->export();
}
}
}
}
$logger->flush(true);
}
This does actually write the logs to the .log file, however there seem to be duplicate entries in the log now and it feels just plain wrong to call an export after every message.
As I read in the docs the actual writing of logs only happens when either these intervals are met OR when the application ends. I could imagine the application not ending properly so I tried forcing this by calling Yii:$app->end() directly after logging the message, but the file stays empty.
Since the problem is neither the application not ending (I can see that it does end) nor the interval being met (I see at least one message in the target and the interval is set to 1) I'm kind of at my wit's end why the logs are not exported. If anyone could perhaps elaborate any further on when/where Yii calls the ->export() method itself that would be a big help.
EDIT: added the console/config/main.php settings. Slightly changed my story, initially I wrote that 'the log file was being created but the messages were not being written in it.' but in fact only the directory that should contain the files was created, not the log file itself.
<?php
return [
'id' => 'console',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'console\controllers',
'components' => [
'user' => [
'class' => 'yii\web\User',
'identityClass' => 'app\models\User',
//'enableAutoLogin' => true,
],
'session' => [ // for use session in console application
'class' => 'yii\web\Session'
],
'log' => [
'flushInterval' => 1,
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error','info', 'warning'],
'categories' => ['reports-schedule'],
'exportInterval' => 1,
'logVars' => [null],
'logFile' => '#app/../logs/console/'. date('Y') . '/' . date('m') . '/reports-schedule/' . 'reports-schedule_' . date('d-m-Y') . '.log'
],
[
'class' => 'yii\log\FileTarget',
'levels' => ['error','info', 'warning'],
'categories' => ['reports-create'],
'exportInterval' => 1,
'logVars' => [null],
'logFile' => '#app/../logs/console/'. date('Y') . '/' . date('m') . '/reports-create/' . 'reports-create_' . date('d-m-Y') . '.log'
],
// and 6 other similarly structured targets
[...],
[...],
[...],
[...],
[...],
[...],
],
]
];
UPDATE: it seems like I'll have to stick to manually calling ->export() on the desired log target. The problem I had with duplicate log entries (same message, same timestamp) being written was due to the fact that I had set the exportInterval property to 1 for the target (which I initially did to make sure the messages were exported at all). I suppose the logger stores messages until the value of exportInterval is met and then expect those messages to be written to the targets. I fixed duplicate entries from being written by removed the exportInterval property so Yii takes the default value (1000). For my case this would be sufficient since I wouldn't run into those numbers but for anyone reading this please consider your use case and check if you would run into anything close to that in a single cycle.
I had a similar issue at some point and I think this should be sufficient enough for your case.
Yii::$app->log->targets['reports-schedule']->logFile = $logPath;
Yii::info($message, $category);
Yii::getLogger()->flush();
This way you can specify a dynamic log path inside your schedule target and after flush the logger continues as it should.
I have the following config for logs:
'log' => [
'traceLevel' => getenv('YII_DEBUG') ? getenv('YII_TRACELEVEL') : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'except' => ['yii\db*'],
'levels' => ['profile', 'trace', 'info', 'warning', 'error'],
'logFile' => '#app/log/app.log',
'logVars' => [],
'maxFileSize' => 1024 * 20,
],
],
],
but when I call all the different level logs I can't seem to get traces to output to my app.log.
here's where we enter my code just as an example of how I'm calling the logs:
public function actionCreate() {
\Yii::trace("trace");
\Yii::info("info");
\Yii::warning("warning");
\Yii::error("error");
return;
and the output I find in app.log:
2016-10-24 19:15:58 [127.0.0.1][-][-][info][application] info
2016-10-24 19:15:58 [127.0.0.1][-][-][warning][application] warning
2016-10-24 19:15:58 [127.0.0.1][-][-][error][application] error
I've played around with adding/removing the levels from the level list, as well as outputting to codemix\streamlog\Targets php://stdout and php://stderr, and everything but trace level logs appear to work as you'd expect from the config. It looks like I'm doing it right according to the documentation found in the Definitive Yii2 guide.
Maybe I'm missing something in my target? I saw someone had a similar problem here but they were simply missing the trace in their targets levels list and haven't responded on whether they solved their problem or not. I'd really appreciate any advice you can offer.
Do you have YII_DEBUG defined in yourApp/web/index.php?
defined('YII_DEBUG') or define('YII_DEBUG', true);
Your code
'traceLevel' => getenv('YII_DEBUG') ? getenv('YII_TRACELEVEL') : 0,
is saying, that if YII_DEBUG is not defined, traceLevel would be 0. According to documentation, traceLevel public property is defined like this:
How much call stack information (file name and line number) should be
logged for each message. If it is greater than 0, at most that number
of call stacks will be logged. Note that only application call stacks
are counted.
Either set YII_DEBUG in yourApp/web/index.php, or change traceLevel property.
Is it possible to use two or more caching storage in yii2 framework? I already setup a Memcache for my web app but I wanted also to use a FileCache since I will be dealing with a large chunk of data.
hope someone can help. Thanks!
You can set any cache. Just set it at config file.
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'memCache' => [
'class' => 'MEMCACHE CLASS HERE',
],
.... ANY cache you want ...
]
You can register multiple cache application components. The component named cache is used by default by many cache-dependent classes (e.g. yii\web\UrlManager).
Official link
'components' => [
'cache' => [
'class' => 'yii\caching\MemCache',
],
'fileCache' => [
'class' => 'yii\caching\FileCache',
]
]
In Yii 1.x you have the CWebLogRoute class to log all your queries and stuff in your browser. Is this option already available for Yii 2.0? I only see the FileTarget, DbTarget and EmailTarget classes in the framework.
The correct answer:
return [
'bootstrap' => ['debug'],
'modules' => [
'debug' => 'yii\debug\Module',
// ...
],
];
It's called debugger now in Yii 2.0. To enable it, put this in your configuration:
'preload' => ['debug'],
'modules' => [
'debug' => 'yii\debug\Module'
],