Browse Source

Logging and profiling at Mongo improved.

tags/2.0.0-beta
Klimov Paul 11 years ago
parent
commit
99b6ae27b3
  1. 4
      extensions/mongo/Collection.php
  2. 66
      extensions/mongo/Database.php
  3. 4
      extensions/mongo/Query.php
  4. 11
      tests/unit/extensions/mongo/DatabaseTest.php

4
extensions/mongo/Collection.php

@ -426,11 +426,11 @@ class Collection extends Object
*/ */
public function aggregate($pipeline, $pipelineOperator = []) public function aggregate($pipeline, $pipelineOperator = [])
{ {
$token = 'Aggregating from ' . $this->getFullName(); $args = func_get_args();
$token = $this->composeLogToken('aggregate', $args);
Yii::info($token, __METHOD__); Yii::info($token, __METHOD__);
try { try {
Yii::beginProfile($token, __METHOD__); Yii::beginProfile($token, __METHOD__);
$args = func_get_args();
$result = call_user_func_array([$this->mongoCollection, 'aggregate'], $args); $result = call_user_func_array([$this->mongoCollection, 'aggregate'], $args);
$this->tryResultError($result); $this->tryResultError($result);
Yii::endProfile($token, __METHOD__); Yii::endProfile($token, __METHOD__);

66
extensions/mongo/Database.php

@ -9,10 +9,13 @@ namespace yii\mongo;
use yii\base\Object; use yii\base\Object;
use Yii; use Yii;
use yii\helpers\Json;
/** /**
* Database represents the Mongo database information. * Database represents the Mongo database information.
* *
* @property string $name name of this database. This property is read-only.
*
* @author Paul Klimov <klimov.paul@gmail.com> * @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0 * @since 2.0
*/ */
@ -32,6 +35,14 @@ class Database extends Object
private $_fileCollections = []; private $_fileCollections = [];
/** /**
* @return string name of this database.
*/
public function getName()
{
return $this->mongoDb->__toString();
}
/**
* Returns the Mongo collection with the given name. * Returns the Mongo collection with the given name.
* @param string $name collection name * @param string $name collection name
* @param boolean $refresh whether to reload the collection instance even if it is found in the cache. * @param boolean $refresh whether to reload the collection instance even if it is found in the cache.
@ -93,10 +104,21 @@ class Database extends Object
* @param string $name name of the collection * @param string $name name of the collection
* @param array $options collection options in format: "name" => "value" * @param array $options collection options in format: "name" => "value"
* @return \MongoCollection new mongo collection instance. * @return \MongoCollection new mongo collection instance.
* @throws Exception on failure.
*/ */
public function createCollection($name, $options = []) public function createCollection($name, $options = [])
{ {
return $this->mongoDb->createCollection($name, $options); $token = $this->getName() . '.create(' . $name . ', ' . Json::encode($options) . ')';
Yii::info($token, __METHOD__);
try {
Yii::beginProfile($token, __METHOD__);
$result = $this->mongoDb->createCollection($name, $options);
Yii::endProfile($token, __METHOD__);
return $result;
} catch (\Exception $e) {
Yii::endProfile($token, __METHOD__);
throw new Exception($e->getMessage(), (int)$e->getCode(), $e);
}
} }
/** /**
@ -104,9 +126,47 @@ class Database extends Object
* @param array $command command specification. * @param array $command command specification.
* @param array $options options in format: "name" => "value" * @param array $options options in format: "name" => "value"
* @return array database response. * @return array database response.
* @throws Exception on failure.
*/ */
public function execute($command, $options = []) public function executeCommand($command, $options = [])
{ {
return $this->mongoDb->command($command, $options); $token = $this->getName() . '.$cmd(' . Json::encode($command) . ', ' . Json::encode($options) . ')';
Yii::info($token, __METHOD__);
try {
Yii::beginProfile($token, __METHOD__);
$result = $this->mongoDb->command($command, $options);
$this->tryResultError($result);
Yii::endProfile($token, __METHOD__);
return $result;
} catch (\Exception $e) {
Yii::endProfile($token, __METHOD__);
throw new Exception($e->getMessage(), (int)$e->getCode(), $e);
}
}
/**
* Checks if command execution result ended with an error.
* @param mixed $result raw command execution result.
* @throws Exception if an error occurred.
*/
protected function tryResultError($result)
{
if (is_array($result)) {
if (!empty($result['errmsg'])) {
$errorMessage = $result['errmsg'];
} elseif (!empty($result['err'])) {
$errorMessage = $result['err'];
}
if (isset($errorMessage)) {
if (array_key_exists('ok', $result)) {
$errorCode = (int)$result['ok'];
} else {
$errorCode = 0;
}
throw new Exception($errorMessage, $errorCode);
}
} elseif (!$result) {
throw new Exception('Unknown error, use "w=1" option to enable error tracking');
}
} }
} }

4
extensions/mongo/Query.php

@ -131,7 +131,7 @@ class Query extends Component implements QueryInterface
*/ */
protected function fetchRows($cursor, $all = true, $indexBy = null) protected function fetchRows($cursor, $all = true, $indexBy = null)
{ {
$token = 'Querying: ' . Json::encode($cursor->info()); $token = 'find(' . Json::encode($cursor->info()) . ')';
Yii::info($token, __METHOD__); Yii::info($token, __METHOD__);
try { try {
Yii::beginProfile($token, __METHOD__); Yii::beginProfile($token, __METHOD__);
@ -213,7 +213,7 @@ class Query extends Component implements QueryInterface
public function count($q = '*', $db = null) public function count($q = '*', $db = null)
{ {
$cursor = $this->buildCursor($db); $cursor = $this->buildCursor($db);
$token = 'Counting: ' . Json::encode($cursor->info()); $token = 'find.count(' . Json::encode($cursor->info()) . ')';
Yii::info($token, __METHOD__); Yii::info($token, __METHOD__);
try { try {
Yii::beginProfile($token, __METHOD__); Yii::beginProfile($token, __METHOD__);

11
tests/unit/extensions/mongo/DatabaseTest.php

@ -49,15 +49,22 @@ class DatabaseTest extends MongoTestCase
$this->assertFalse($collection === $collectionRefreshed); $this->assertFalse($collection === $collectionRefreshed);
} }
public function testCommand() public function testExecuteCommand()
{ {
$database = $connection = $this->getConnection()->getDatabase(); $database = $connection = $this->getConnection()->getDatabase();
$result = $database->execute([ $result = $database->executeCommand([
'distinct' => 'customer', 'distinct' => 'customer',
'key' => 'name' 'key' => 'name'
]); ]);
$this->assertTrue(array_key_exists('ok', $result)); $this->assertTrue(array_key_exists('ok', $result));
$this->assertTrue(array_key_exists('values', $result)); $this->assertTrue(array_key_exists('values', $result));
} }
public function testCreateCollection()
{
$database = $connection = $this->getConnection()->getDatabase();
$collection = $database->createCollection('customer');
$this->assertTrue($collection instanceof \MongoCollection);
}
} }
Loading…
Cancel
Save