Development

/branches/2.0/src/Symfony/Bundle/DoctrineMongoDBBundle/Logger/DoctrineMongoDBLogger.php

You must first sign up to be able to contribute.

root/branches/2.0/src/Symfony/Bundle/DoctrineMongoDBBundle/Logger/DoctrineMongoDBLogger.php

Revision 32396, 10.5 kB (checked in by fabien, 2 years ago)

Merge branch 'master' of git://github.com/symfony/symfony

Line 
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace SymfonyWarning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0BundleWarning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0DoctrineMongoDBBundleWarning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0Logger;
13
14 use DoctrineWarning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0MongoDBWarning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0GridFSFile;
15 use SymfonyWarning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0ComponentWarning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0HttpKernelWarning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0LogWarning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0LoggerInterface;
16
17 /**
18  * Logger for the Doctrine MongoDB ODM.
19  *
20  * The {@link logQuery()} method is configured as the logger callable in the
21  * service container.
22  *
23  * @author Kris Wallsmith <kris.wallsmith@symfony.com>
24  */
25 class DoctrineMongoDBLogger
26 {
27     protected $logger;
28
29     protected $prefix;
30     protected $queries;
31
32     protected $processed;
33     protected $formattedQueries;
34     protected $nbRealQueries;
35
36     /**
37      * Constructor.
38      *
39      * @param LoggerInterface $logger The Symfony logger
40      * @param string          $prefix A prefix for messages sent to the Symfony logger
41      */
42     public function __construct(LoggerInterface $logger = null, $prefix = 'MongoDB query: ')
43     {
44         $this->logger = $logger;
45         $this->prefix = $prefix;
46         $this->queries = array();
47         $this->processed = false;
48     }
49
50     /**
51      * Logs a query.
52      *
53      * This method is configured as the logger callable in the service
54      * container.
55      *
56      * @param array $query A query log array from Doctrine
57      */
58     public function logQuery(array $query)
59     {
60         $this->queries[] = $query;
61         $this->processed = false;
62
63         if (null !== $this->logger) {
64             $this->logger->info($this->prefix.static::bsonEncode($query));
65         }
66     }
67
68     /**
69      * Returns the number of queries that have been logged.
70      *
71      * @return integer The number of queries logged
72      */
73     public function getNbQueries()
74     {
75         if (!$this->processed) {
76             $this->processQueries();
77         }
78
79         return $this->nbRealQueries;
80     }
81
82     /**
83      * Returns a human-readable array of queries logged.
84      *
85      * @return array An array of queries
86      */
87     public function getQueries()
88     {
89         if (!$this->processed) {
90             $this->processQueries();
91         }
92
93         return $this->formattedQueries;
94     }
95
96     /**
97      * Groups and formats query arrays.
98      *
99      * @param array $queries An array of query arrays
100      *
101      * @return array An array of human-readable queries
102      */
103     protected function processQueries()
104     {
105         $this->formattedQueries = array();
106         $this->nbRealQueries = 0;
107
108         $grouped = array();
109         $ordered = array();
110         foreach ($this->queries as $query) {
111             if (!isset($query['query']) || !isset($query['fields'])) {
112                 // no grouping necessary
113                 $ordered[] = array($query);
114                 continue;
115             }
116
117             $cursor = serialize($query['query']).serialize($query['fields']);
118
119             // append if issued from cursor (currently just "sort")
120             if (isset($query['sort'])) {
121                 unset($query['query'], $query['fields']);
122                 $grouped[$cursor][count($grouped[$cursor]) - 1][] = $query;
123             } else {
124                 $grouped[$cursor][] = array($query);
125                 $ordered[] =& $grouped[$cursor][count($grouped[$cursor]) - 1];
126             }
127         }
128
129         $i = 0;
130         $db = '';
131         $query = '';
132         foreach ($ordered as $logs) {
133             foreach ($logs as $log) {
134                 if (isset($log['db']) && $db != $log['db']) {
135                     // for readability
136                     $this->formattedQueries[$i++] = 'use '.$log['db'].';';
137                     $db = $log['db'];
138                 }
139
140                 if (isset($log['collection'])) {
141                     // flush the previous and start a new query
142                     if (!empty($query)) {
143                         if ('.' == $query[0]) {
144                             $query  = 'db'.$query;
145                         }
146
147                         $this->formattedQueries[$i++] = $query.';';
148                         ++$this->nbRealQueries;
149                     }
150
151                     $query = 'db.'.$log['collection'];
152                 }
153
154                 // format the method call
155                 if (isset($log['authenticate'])) {
156                     $query .= '.authenticate()';
157                 } elseif (isset($log['batchInsert'])) {
158                     $query .= '.batchInsert(**'.$log['num'].' item(s)**)';
159                 } elseif (isset($log['command'])) {
160                     $query .= '.command()';
161                 } elseif (isset($log['count'])) {
162                     $query .= '.count(';
163                     if ($log['query'] || $log['limit'] || $log['skip']) {
164                         $query .= static::bsonEncode($log['query']);
165                         if ($log['limit'] || $log['skip']) {
166                             $query .= ', '.static::bsonEncode($log['limit']);
167                             if ($log['skip']) {
168                                 $query .= ', '.static::bsonEncode($log['skip']);
169                             }
170                         }
171                     }
172                     $query .= ')';
173                 } elseif (isset($log['createCollection'])) {
174                     $query .= '.createCollection()';
175                 } elseif (isset($log['createDBRef'])) {
176                     $query .= '.createDBRef()';
177                 } elseif (isset($log['deleteIndex'])) {
178                     $query .= '.dropIndex('.static::bsonEncode($log['keys']).')';
179                 } elseif (isset($log['deleteIndexes'])) {
180                     $query .= '.dropIndexes()';
181                 } elseif (isset($log['drop'])) {
182                     $query .= '.drop()';
183                 } elseif (isset($log['dropDatabase'])) {
184                     $query .= '.dropDatabase()';
185                 } elseif (isset($log['ensureIndex'])) {
186                     $query .= '.ensureIndex('.static::bsonEncode($log['keys']).', '.static::bsonEncode($log['options']).')';
187                 } elseif (isset($log['execute'])) {
188                     $query .= '.execute()';
189                 } elseif (isset($log['find'])) {
190                     $query .= '.find(';
191                     if ($log['query'] || $log['fields']) {
192                         $query .= static::bsonEncode($log['query']);
193                         if ($log['fields']) {
194                             $query .= ', '.static::bsonEncode($log['fields']);
195                         }
196                     }
197                     $query .= ')';
198                 } elseif (isset($log['findOne'])) {
199                     $query .= '.findOne(';
200                     if ($log['query'] || $log['fields']) {
201                         $query .= static::bsonEncode($log['query']);
202                         if ($log['fields']) {
203                             $query .= ', '.static::bsonEncode($log['fields']);
204                         }
205                     }
206                     $query .= ')';
207                 } elseif (isset($log['getDBRef'])) {
208                     $query .= '.getDBRef()';
209                 } elseif (isset($log['group'])) {
210                     $query .= '.group('.static::bsonEncode(array(
211                         'keys'    => $log['keys'],
212                         'initial' => $log['initial'],
213                         'reduce'  => $log['reduce'],
214                     )).')';
215                 } elseif (isset($log['insert'])) {
216                     $query .= '.insert('.static::bsonEncode($log['document']).')';
217                 } elseif (isset($log['remove'])) {
218                     $query .= '.remove('.static::bsonEncode($log['query']).')';
219                 } elseif (isset($log['save'])) {
220                     $query .= '.save('.static::bsonEncode($log['document']).')';
221                 } elseif (isset($log['sort'])) {
222                     $query .= '.sort('.static::bsonEncode($log['sortFields']).')';
223                 } elseif (isset($log['update'])) {
224                     // todo: include $log['options']
225                     $query .= '.update('.static::bsonEncode($log['query']).', '.static::bsonEncode($log['newObj']).')';
226                 } elseif (isset($log['validate'])) {
227                     $query .= '.validate()';
228                 }
229             }
230         }
231
232         if (!empty($query)) {
233             if ('.' == $query[0]) {
234                 $query  = 'db'.$query;
235             }
236
237             $this->formattedQueries[$i++] = $query.';';
238             ++$this->nbRealQueries;
239         }
240     }
241
242     static protected function bsonEncode($query, $array = true)
243     {
244         $parts = array();
245
246         foreach ($query as $key => $value) {
247             if (!is_numeric($key)) {
248                 $array = false;
249             }
250
251             if (is_bool($value)) {
252                 $formatted = $value ? 'true' : 'false';
253             } elseif (is_numeric($value)) {
254                 $formatted = $value;
255             } elseif (is_scalar($value)) {
256                 $formatted = '"'.$value.'"';
257             } elseif (is_array($value)) {
258                 $formatted = static::bsonEncode($value);
259             } elseif ($value instanceof Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0MongoId) {
260                 $formatted = 'ObjectId("'.$value.'")';
261             } elseif ($value instanceof Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0MongoDate) {
262                 $formatted = 'new Date("'.date('r', $value->sec).'")';
263             } elseif ($value instanceof Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0DateTime) {
264                 $formatted = 'new Date("'.date('r', $value->getTimestamp()).'")';
265             } elseif ($value instanceof Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0MongoRegex) {
266                 $formatted = 'new RegExp("'.$value->regex.'", "'.$value->flags.'")';
267             } elseif ($value instanceof Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0MongoMinKey) {
268                 $formatted = 'new MinKey()';
269             } elseif ($value instanceof Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0MongoMaxKey) {
270                 $formatted = 'new MaxKey()';
271             } elseif ($value instanceof Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0MongoBinData) {
272                 $formatted = 'new BinData("'.$value->bin.'", "'.$value->type.'")';
273             } elseif ($value instanceof Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0MongoGridFSFile || $value instanceof GridFSFile) {
274                 $formatted = 'new MongoGridFSFile("'.$value->getFilename().'")';
275             } elseif ($value instanceof Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0stdClass) {
276                 $formatted = static::bsonEncode((array) $value);
277             } else {
278                 $formatted = (string) $value;
279             }
280
281             $parts['"'.$key.'"'] = $formatted;
282         }
283
284         if (0 == count($parts)) {
285             return $array ? '[ ]' : '{ }';
286         }
287
288         if ($array) {
289             return '[ '.implode(', ', $parts).' ]';
290         } else {
291             $mapper = function($key, $value)
292             {
293                 return $key.': '.$value;
294             };
295
296             return '{ '.implode(', ', array_map($mapper, array_keys($parts), array_values($parts))).' }';
297         }
298     }
299 }
300
Note: See TracBrowser for help on using the browser.