Browse Source

adding scoped logging

Rachman Chavik 14 years ago
parent
commit
6040d96710

+ 16 - 3
lib/Cake/Log/CakeLog.php

@@ -249,11 +249,14 @@ class CakeLog {
  *
  * `CakeLog::write('warning', 'Stuff is broken here');`
  *
- * @param string $type Type of message being written
+ * @param mixed $type Type of message being written. When value is an integer
+ *                    or a string matching the recognized levels, then it will
+ *                    be treated log levels. Otherwise it's treated as scope.
  * @param string $message Message content to log
+ * @param mixed $scope string or array
  * @return boolean Success
  */
-	public static function write($type, $message) {
+	public static function write($type, $message, $scope = array()) {
 		if (empty(self::$_Collection)) {
 			self::_init();
 		}
@@ -269,6 +272,9 @@ class CakeLog {
 		if (is_int($type) && isset($levels[$type])) {
 			$type = $levels[$type];
 		}
+		if (is_string($type) && empty($scope) && !in_array($type, $levels)) {
+			$scope = $type;
+		}
 		if (empty(self::$_streams)) {
 			self::_autoConfig();
 		}
@@ -276,7 +282,14 @@ class CakeLog {
 			$logger = self::$_Collection->{$streamName};
 			$config = $logger->config();
 			$types = $config['types'];
-			if (empty($types) || in_array($type, $types)) {
+			$scopes = $config['scopes'];
+			if (is_string($scope)) {
+				$inScope = in_array($scope, $scopes);
+			} else {
+				$intersect = array_intersect($scope, $scopes);
+				$inScope = !empty($intersect);
+			}
+			if (empty($types) || in_array($type, $types) || in_array($type, $scopes) && $inScope) {
 				$logger->write($type, $message);
 			}
 		}

+ 1 - 0
lib/Cake/Log/Engine/ConsoleLog.php

@@ -50,6 +50,7 @@ class ConsoleLog extends BaseLog {
 		$config = Set::merge(array(
 			'stream' => 'php://stderr',
 			'types' => null,
+			'scopes' => array(),
 			'outputAs' => ConsoleOutput::COLOR,
 			), $this->_config);
 		$config = $this->config($config);

+ 3 - 0
lib/Cake/Log/Engine/FileLog.php

@@ -49,6 +49,7 @@ class FileLog extends BaseLog {
 			'path' => LOGS,
 			'file' => null,
 			'types' => null,
+			'scopes' => array(),
 			), $this->_config);
 		$config = $this->config($config);
 		$this->_path = $config['path'];
@@ -74,6 +75,8 @@ class FileLog extends BaseLog {
 			$filename = $this->_path . 'error.log';
 		} elseif (in_array($type, $debugTypes)) {
 			$filename = $this->_path . 'debug.log';
+		} elseif (in_array($type, $this->_config['scopes'])) {
+			$filename = $this->_path . $this->_file;
 		} else {
 			$filename = $this->_path . $type . '.log';
 		}

+ 148 - 0
lib/Cake/Test/Case/Log/CakeLogTest.php

@@ -281,4 +281,152 @@ class CakeLogTest extends CakeTestCase {
 		CakeLog::disable('bogus_stream');
 	}
 
+	protected function _deleteLogs() {
+		@unlink(LOGS . 'shops.log');
+		@unlink(LOGS . 'error.log');
+		@unlink(LOGS . 'debug.log');
+	}
+
+/**
+ * test backward compatible scoped logging
+ */
+	public function testScopedLoggingBC() {
+		if (file_exists(LOGS . 'shops.log')) {
+			unlink(LOGS . 'shops.log');
+		}
+		if (file_exists(LOGS . 'error.log')) {
+			unlink(LOGS . 'error.log');
+		}
+		if (file_exists(LOGS . 'debug.log')) {
+			unlink(LOGS . 'debug.log');
+		}
+
+		CakeLog::config('debug', array(
+			'engine' => 'FileLog',
+			'types' => array('notice', 'info', 'debug'),
+			'file' => 'debug',
+		));
+		CakeLog::config('error', array(
+			'engine' => 'FileLog',
+			'types' => array('error', 'warning'),
+			'file' => 'error',
+		));
+		CakeLog::config('shops', array(
+			'engine' => 'FileLog',
+			'types' => array('info', 'notice', 'warning'),
+			'scopes' => array('transactions', 'orders'),
+			'file' => 'shops',
+			));
+
+		CakeLog::write('info', 'info message');
+		$this->assertFalse(file_exists(LOGS . 'error.log'));
+		$this->assertTrue(file_exists(LOGS . 'shops.log'));
+		$this->assertTrue(file_exists(LOGS . 'debug.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::write('transactions', 'transaction message');
+		$this->assertTrue(file_exists(LOGS . 'shops.log'));
+		$this->assertFalse(file_exists(LOGS . 'transactions.log'));
+		$this->assertFalse(file_exists(LOGS . 'error.log'));
+		$this->assertFalse(file_exists(LOGS . 'debug.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::write('error', 'error message');
+		$this->assertTrue(file_exists(LOGS . 'error.log'));
+		$this->assertFalse(file_exists(LOGS . 'debug.log'));
+		$this->assertFalse(file_exists(LOGS . 'shops.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::write('orders', 'order message');
+		$this->assertFalse(file_exists(LOGS . 'error.log'));
+		$this->assertFalse(file_exists(LOGS . 'debug.log'));
+		$this->assertFalse(file_exists(LOGS . 'orders.log'));
+		$this->assertTrue(file_exists(LOGS . 'shops.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::write('warning', 'warning message');
+		$this->assertTrue(file_exists(LOGS . 'error.log'));
+		$this->assertTrue(file_exists(LOGS . 'shops.log'));
+		$this->assertFalse(file_exists(LOGS . 'debug.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::drop('shops');
+	}
+
+/**
+ * test scoped logging
+ */
+	public function testScopedLogging() {
+		if (file_exists(LOGS . 'shops.log')) {
+			unlink(LOGS . 'shops.log');
+		}
+		if (file_exists(LOGS . 'error.log')) {
+			unlink(LOGS . 'error.log');
+		}
+		if (file_exists(LOGS . 'debug.log')) {
+			unlink(LOGS . 'debug.log');
+		}
+
+		CakeLog::config('debug', array(
+			'engine' => 'FileLog',
+			'types' => array('notice', 'info', 'debug'),
+			'file' => 'debug',
+		));
+		CakeLog::config('error', array(
+			'engine' => 'FileLog',
+			'types' => array('error', 'warning'),
+			'file' => 'error',
+		));
+		CakeLog::config('shops', array(
+			'engine' => 'FileLog',
+			'types' => array('info', 'notice', 'warning'),
+			'scopes' => array('transactions', 'orders'),
+			'file' => 'shops',
+			));
+
+		CakeLog::write('info', 'info message', 'transactions');
+		$this->assertFalse(file_exists(LOGS . 'error.log'));
+		$this->assertTrue(file_exists(LOGS . 'shops.log'));
+		$this->assertTrue(file_exists(LOGS . 'debug.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::write('transactions', 'transaction message', 'orders');
+		$this->assertTrue(file_exists(LOGS . 'shops.log'));
+		$this->assertFalse(file_exists(LOGS . 'transactions.log'));
+		$this->assertFalse(file_exists(LOGS . 'error.log'));
+		$this->assertFalse(file_exists(LOGS . 'debug.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::write('error', 'error message', 'orders');
+		$this->assertTrue(file_exists(LOGS . 'error.log'));
+		$this->assertFalse(file_exists(LOGS . 'debug.log'));
+		$this->assertFalse(file_exists(LOGS . 'shops.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::write('orders', 'order message', 'transactions');
+		$this->assertFalse(file_exists(LOGS . 'error.log'));
+		$this->assertFalse(file_exists(LOGS . 'debug.log'));
+		$this->assertFalse(file_exists(LOGS . 'orders.log'));
+		$this->assertTrue(file_exists(LOGS . 'shops.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::write('warning', 'warning message', 'orders');
+		$this->assertTrue(file_exists(LOGS . 'error.log'));
+		$this->assertTrue(file_exists(LOGS . 'shops.log'));
+		$this->assertFalse(file_exists(LOGS . 'debug.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::drop('shops');
+	}
+
 }