public function testMaskSetting() { if (DS === '\\') { $this->markTestSkipped('File permission testing does not work on Windows.'); } $path = TMP . 'tests' . DS; $this->_deleteLogs($path); $log = new FileLog(array('path' => $path, 'mask' => 0666)); $log->log('warning', 'Test warning one'); $result = substr(sprintf('%o', fileperms($path . 'error.log')), -4); $expected = '0666'; $this->assertEquals($expected, $result); unlink($path . 'error.log'); $log = new FileLog(array('path' => $path, 'mask' => 0644)); $log->log('warning', 'Test warning two'); $result = substr(sprintf('%o', fileperms($path . 'error.log')), -4); $expected = '0644'; $this->assertEquals($expected, $result); unlink($path . 'error.log'); $log = new FileLog(array('path' => $path, 'mask' => 0640)); $log->log('warning', 'Test warning three'); $result = substr(sprintf('%o', fileperms($path . 'error.log')), -4); $expected = '0640'; $this->assertEquals($expected, $result); unlink($path . 'error.log'); }
/** * Implements writing to log files. * * Each time that is called, it writes the normal log (using the * `FileLog::log` method) and a serialized copy of the log. * For example, if the log is `error.log`, the serialized log will be * `error_serialized.log`. * @param string $level The severity level of the message being written. * See Cake\Log\Log::$_levels for list of possible levels. * @param string $message The message you want to log. * @param array $context Additional information about the logged message * @return bool success of write * @uses _getLogAsArray() */ public function log($level, $message, array $context = []) { //First of all, it normally writes log parent::log($level, $message, $context); //Now, it writes the serialized log $message = $this->_format(trim($message), $context); $filename = $this->_getFilename($level); //It sets a new filename, adding the `_serialized` suffix //For example, if the log is `error.log`, the serialized log will be `error_serialized.log` $filename = sprintf('%s_serialized.log', pathinfo($filename, PATHINFO_FILENAME)); if (!empty($this->_size)) { $this->_rotateFile($filename); } $pathname = $this->_path . $filename; $mask = $this->_config['mask']; //Gets the content of the existing logs and unserializes if (is_readable($pathname)) { $logs = unserialize(file_get_contents($pathname)); } if (empty($logs) || !is_array($logs)) { $logs = []; } //Adds the current log at the beginning array_unshift($logs, (object) $this->_getLogAsArray($level, $message)); //Serializes logs $output = serialize($logs); if (empty($mask)) { return file_put_contents($pathname, $output); } $exists = file_exists($pathname); $result = file_put_contents($pathname, $output); static $selfError = false; if (!$selfError && !$exists && !chmod($pathname, (int) $mask)) { $selfError = true; trigger_error(vsprintf('Could not apply permission mask "%s" on log file "%s"', [$mask, $pathname]), E_USER_WARNING); $selfError = false; } return $result; }