Code

c8631ce2e0302cb3f93caf21c3d9525043868349
[gosa.git] / gosa-core / include / class_stats.inc
1 <?php
3 class stats 
4 {
5     
6     static protected $lastCpuLoad = "";
7     static protected $lastCpuLoadTimestamp = 0;
9     static protected $tableName = "stats";
10     static protected $tableFile = "/var/spool/gosa/stats";
12     static protected $lastHandle = NULL;
13     static protected $statsEnabled = FALSE;
15     static function getDatabaseHandle()
16     {
17         // Try to return last valid handle.
18         if(stats::$lastHandle != NULL && is_resource(stats::$lastHandle)){
19             return(stats::$lastHandle);
20         }
22         // Check if Logging is enabled
23         global $config;
24         if(!is_object($config) || ! $config instanceOf config){
25             return(NULL);
26         }
27     
28         // Get statsFile property 
29         stats::$tableFile    = $config->get_cfg_value('core', 'statsDatabaseFile');
30         stats::$statsEnabled = $config->boolValueIsTrue('core', 'statsDatabaseEnabled');
31         if(!stats::$statsEnabled){
32             return;
33         }
35         // Check for SQLite extension
36         if(!stats::checkSQLiteExtension()){
37             return(NULL);
38         }
40         // Check if we are able to read/write the given database file.
41         if(!is_writeable(stats::$tableFile) && !is_writeable(dirname(stats::$tableFile))){
42             return(NULL);
43         }
45         // Try to create database, if it exists just open it.
46         $handle = sqlite_popen(stats::$tableFile, 0666, $error);
47         if($handle){
48             stats::createDatabaseOnDemand($handle);
49         }
50         stats::$lastHandle = $handle;
51         return($handle);
52     }
54     /*! \brief      |
55      *  @param      |
56      *  @return     |
57      */  
58     static function checkSQLiteExtension()
59     {
60         return(function_exists('sqlite_popen'));
61     }
64     /*! \brief      |
65      *  @param      |
66      *  @return     |
67      */  
68     static function dropTable($handle)
69     {
70         $TABLE_NAME = stats::$tableName;
71         $query = "DROP TABLE '{$TABLE_NAME}'";
72         $ret = sqlite_query($query, $handle);
73         stats::$lastHandle = NULL;
74         stats::getDatabaseHandle();
75     }
78     /*! \brief      |
79      *  @param      |
80      *  @return     |
81      */  
82     static function get_memory_usage()
83     {
84         return(memory_get_usage());
85     }
88     /*! \brief      |
89      *  @param      |
90      *  @return     |
91      */  
92     static function get_cpu_load()
93     {
94         $cur = time();
95         if(empty(stats::$lastCpuLoad) || (($cur - stats::$lastCpuLoadTimestamp) >=2 )){
96             list($one, $five, $ten) =preg_split("/ /",shell_exec('cat /proc/loadavg'));
97             stats::$lastCpuLoad = $one;
98             stats::$lastCpuLoadTimestamp = $cur;
99         }
100         return(stats::$lastCpuLoad);
101     }
104     /*! \brief      |
105      *  @param      |
106      *  @return     |
107      */  
108     static function createDatabaseOnDemand($handle)
109     {
110         $TABLE_NAME = stats::$tableName;
112         // List Tables an check if there is already everything we need,
113         //  if not create it.
114         $query = "SELECT name FROM sqlite_master WHERE type='table' and name='{$TABLE_NAME}'";
115         $ret = sqlite_query($query, $handle);
116         if(!count(sqlite_fetch_all($ret))){
117             $query = "
118                 CREATE TABLE {$TABLE_NAME} (
119                         ID              INTEGER PRIMARY KEY,
120                         ACTID           INTEGER,
121                         TYPE            TEXT,
122                         PLUGIN          TEXT,
123                         CATEGORY        TEXT,
124                         ACTION          TEXT,
125                         UUID            TEXT,
126                         TIMESTAMP       INTEGER,
127                         MTIMESTAMP      REAL,
128                         DURATION        REAL,
129                         RENDER_TIME     REAL,
130                         AMOUNT          INTEGER,
131                         MEMORY_USAGE    INTEGER,
132                         CPU_LOAD        FLOAT,
133                         INFO            BLOB
134                         )";
135             $ret = sqlite_query($query, $handle);
136         }
137     }
140     /*! \brief      |
141      *  @param      |
142      *  @return     |
143      */  
144     static function log($type, $plugin, $category, $action, $amount = 1, $duration = 0, $info ='')
145     {
146         global $config;
147         global $clicks;
148         global $overallRenderTimer;
150         // Get database handle, if it is invalid (NULL) return without creating stats
151         $res = stats::getDatabaseHandle();
152 #        stats::dropTable($res);
153         if(!$res) return;
155         // Ensure that 'clicks' and 'overallRenderTimer' are present and set correctly, 
156         //  if not simply create them with dummy values... 
157         //   -- 'clicks' is a counter wich is set in main.php -> Number of page reloads 
158         //   -- 'overallRenderTimer' is set in main.php -> timestamp of rendering start.
159         if(!isset($clicks) || empty($clicks)) $clicks = 0;
160         if(!isset($overallRenderTimer)){
161             $renderTime = 0;
162         }else{
163             $renderTime = microtime(TRUE) - $overallRenderTimer;
165             // Now set the overallRenderTimer to the current timestamp - else 
166             //  we will not be able to sum up the render time in a single SQL statement.
167             $overallRenderTimer = microtime(TRUE);
168         }
170         // Enforce floating point values ...damn this sucks.
171         $duration   += 0.000001;
172         $renderTime += 0.000001;
174         $duration   = sprintf("%0.6f",$duration);
175         $renderTime = sprintf("%0.6f",$renderTime);
177         $duration   = preg_replace("/\./",",",$duration);
178         $renderTime = preg_replace("/\./",",",$renderTime);
180         // Prepare values to be useable within a database
181         $uuid = $config->getGOsaUUID();
182         $type           = sqlite_escape_string($type);
183         $plugin         = sqlite_escape_string($plugin);
184         $action         = sqlite_escape_string($action);
185         $timestamp      = time();
186         $mtimestamp     = microtime(TRUE);
187         $amount         = sqlite_escape_string($amount);
188         $duration       = sqlite_escape_string($duration);
189         $renderTime     = sqlite_escape_string($renderTime);
190         $info           = sqlite_escape_string($info);
191         $clicks         = sqlite_escape_string($clicks);
192         $memory_usage   = sqlite_escape_string(stats::get_memory_usage());
193         $cpu_load       = sqlite_escape_string(sprintf("%0.6f",stats::get_cpu_load()));
195         // Clean up category, which usally comes from acl_category and may still contain 
196         //  some special chars like /
197         $tmp = array();
198         foreach($category as $cat){
199             $tmp[] = trim($cat, '\/,; ');
200         }
201         $category = sqlite_escape_string(implode($tmp, ', '));
202    
203         // Create insert statement.
204         $TABLE_NAME = stats::$tableName;
205         $query = "
206             INSERT INTO {$TABLE_NAME}
207                 (ACTID, TYPE, PLUGIN, CATEGORY, ACTION, UUID, MTIMESTAMP, TIMESTAMP, 
208                  AMOUNT, DURATION, RENDER_TIME, MEMORY_USAGE, CPU_LOAD, INFO) 
209             VALUES 
210                 ('{$clicks}','{$type}','{$plugin}','{$category}','{$action}','{$uuid}',
211                     '{$mtimestamp}','{$timestamp}','{$amount}','{$duration}','{$renderTime}',
212                     '{$memory_usage}','{$cpu_load}','{$info}')";
213         sqlite_query($query, $res);
214     }
215    
216  
217     /*! \brief      |
218      *  @param      |
219      *  @return     |
220      */  
221     static function show()
222     {
223         $res = stats::getDatabaseHandle();
224 #       stats::dropTable($res);
225         if(!$res) return;        
227         $TABLE_NAME = stats::$tableName;
228         $query = "SELECT * FROM {$TABLE_NAME} ORDER BY MTIMESTAMP";
229         $query = "SELECT PLUGIN, ACTION, MAX(DURATION) as 'DURATION' FROM {$TABLE_NAME} WHERE ACTION='modify' GROUP BY PLUGIN,ACTION ";
230         $query = "SELECT * FROM {$TABLE_NAME} ORDER BY ID DESC LIMIT 30";
231         $query = "SELECT * FROM {$TABLE_NAME} WHERE plugin != 'LDAP' ORDER BY ID DESC LIMIT 30";
232         $ret = sqlite_query($query, $res);
233         echo "<pre>";
235         $colSize = 16;
237         $title = FALSE;
238         foreach(sqlite_fetch_all($ret) as $entry){
239             if(!$title){
240                 foreach($entry as $key => $str) {
241                     if(is_numeric($key)) continue;
242                     echo str_pad($key,$colSize,' ')."|";
243                 }
244                 echo "\n";
245                 foreach($entry as $key => $str) {
246                     if(is_numeric($key)) continue;
247                     echo str_pad('',$colSize,'-')."-";
248                 }
249                 echo "\n";
250                 $title = TRUE;
251             }
252  
253             foreach($entry as $key => $str){
254                 if(is_numeric($key)) continue;
255                 if($key == "DURATION" || $key == "MTIMESTAMP" || $key == "CPU_LOAD"){
256                     $str = sprintf("%0.4f", preg_replace("/,/",".",$str));
257                     echo str_pad($str,$colSize,' ', STR_PAD_LEFT)."|"; 
258                 }else{
259                     echo str_pad($str,$colSize,' ')."|"; 
260                 }
261             }
262             echo "\n";
263         }
264         echo sqlite_error_string($ret);
266         echo "\n------ \n";
267         echo "Time spent per plugin-category \n";
268         echo "------ \n";
270         $query = "
271             SELECT SUM(DURATION) AS DUR, CATEGORY 
272             FROM {$TABLE_NAME}
273             WHERE plugin != 'LDAP' 
274             GROUP BY CATEGORY 
275             ORDER BY DUR DESC LIMIT 10";
276         $ret = sqlite_query($query, $res);
278         $colSize = 16;
279         $title = FALSE;
280         foreach(sqlite_fetch_all($ret) as $entry){
281             foreach($entry as $key => $str){
282                 if(is_numeric($key)) continue;
283                 echo str_pad($str,$colSize,' ')."|"; 
284             }
285             echo "\n";
286         }
289         echo sqlite_error_string($ret);
291         echo "\n------ \n";
292         echo "Time spent per plugin \n";
293         echo "------ \n";
295         $query = "
296             SELECT SUM(DURATION) AS DUR, PLUGIN, UUID 
297             FROM {$TABLE_NAME}
298             WHERE plugin != 'LDAP' 
299             GROUP BY PLUGIN, UUID 
300             ORDER BY DUR DESC LIMIT 10";
301         $ret = sqlite_query($query, $res);
303         $colSize = 16;
304         $title = FALSE;
305         foreach(sqlite_fetch_all($ret) as $entry){
306             foreach($entry as $key => $str){
307                 if(is_numeric($key)) continue;
308                 echo str_pad($str,$colSize,' ')."|"; 
309             }
310             echo "\n";
311         }
312         echo sqlite_error_string($ret);
314  # * Anzahl von Objekttypen
315  # * Anzahl der Löschungen pro Objekttyp
316  # * Anzahl der Erzeugungen pro Objekttyp
317  # * Anzahl der Bearbeitungen pro Objekttyp
318  # * Anzahl der Verschiebungen pro Objekttyp
319  # * Anzahl der Mehrfachbearbeitungen pro Objekttyp
320  # * Antwortzeiten pro aktion
321  # * Anzahl der Passwortänderungen
322  # * Anzahl der unterschiedlichen Anmeldungen
325         echo "\n------ \n";
326         echo "Actions done per plugin \n";
327         echo "------ \n";
329         $query = "
330             SELECT COUNT(ACTION) as CNT, ACTION, PLUGIN 
331             FROM {$TABLE_NAME}
332             WHERE   TYPE = 'plugin'
333              AND    PLUGIN != 'LDAP'
334             GROUP BY ACTION,PLUGIN 
335             ORDER BY CNT DESC LIMIT 30";
336         $ret = sqlite_query($query, $res);
338         $colSize = 16;
339         $title = FALSE;
340         foreach(sqlite_fetch_all($ret) as $entry){
341             foreach($entry as $key => $str){
342                 if(is_numeric($key)) continue;
343                 echo str_pad($str,$colSize,' ')."|"; 
344             }
345             echo "\n";
346         }
347         echo sqlite_error_string($ret);
349         echo "\n------ \n";
350         echo "'create' actions done per plugin  (5 most)\n";
351         echo "------ \n";
353         $query = "
354             SELECT COUNT(ACTION) as CNT, ACTION, PLUGIN 
355             FROM {$TABLE_NAME}
356             WHERE   TYPE = 'plugin'
357              AND    PLUGIN != 'LDAP'
358              AND    ACTION = 'create'
359             GROUP BY ACTION,PLUGIN 
360             ORDER BY CNT DESC LIMIT 5";
361         $ret = sqlite_query($query, $res);
363         $colSize = 16;
364         $title = FALSE;
365         foreach(sqlite_fetch_all($ret) as $entry){
366             foreach($entry as $key => $str){
367                 if(is_numeric($key)) continue;
368                 echo str_pad($str,$colSize,' ')."|"; 
369             }
370             echo "\n";
371         }
372         echo sqlite_error_string($ret);
374         echo "\n------ \n";
375         echo "'move' actions done per plugin  (5 most)\n";
376         echo "------ \n";
378         $query = "
379             SELECT COUNT(ACTION) as CNT, ACTION, PLUGIN 
380             FROM {$TABLE_NAME}
381             WHERE   TYPE = 'plugin'
382              AND    PLUGIN != 'LDAP'
383              AND    ACTION = 'move'
384             GROUP BY ACTION,PLUGIN 
385             ORDER BY CNT DESC LIMIT 5";
386         $ret = sqlite_query($query, $res);
388         $colSize = 16;
389         $title = FALSE;
390         foreach(sqlite_fetch_all($ret) as $entry){
391             foreach($entry as $key => $str){
392                 if(is_numeric($key)) continue;
393                 echo str_pad($str,$colSize,' ')."|"; 
394             }
395             echo "\n";
396         }
397         echo sqlite_error_string($ret);
399         echo "\n------ \n";
400         echo "'view' actions done per plugin  (5 most)\n";
401         echo "------ \n";
403         $query = "
404             SELECT COUNT(ACTION) as CNT, ACTION, PLUGIN 
405             FROM {$TABLE_NAME}
406             WHERE   TYPE = 'plugin'
407              AND    PLUGIN != 'LDAP'
408              AND    ACTION = 'view'
409             GROUP BY ACTION,PLUGIN 
410             ORDER BY CNT DESC LIMIT 5";
411         $ret = sqlite_query($query, $res);
413         $colSize = 16;
414         $title = FALSE;
415         foreach(sqlite_fetch_all($ret) as $entry){
416             foreach($entry as $key => $str){
417                 if(is_numeric($key)) continue;
418                 echo str_pad($str,$colSize,' ')."|"; 
419             }
420             echo "\n";
421         }
422         echo sqlite_error_string($ret);
424         echo "\n------ \n";
425         echo "'open' actions done per plugin  (5 most)\n";
426         echo "------ \n";
428         $query = "
429             SELECT COUNT(ACTION) as CNT, ACTION, PLUGIN, UUID 
430             FROM {$TABLE_NAME}
431             WHERE   TYPE = 'plugin'
432              AND    PLUGIN != 'LDAP'
433              AND    ACTION = 'open'
434             GROUP BY ACTION,PLUGIN, UUID
435             ORDER BY CNT DESC LIMIT 5";
436         $ret = sqlite_query($query, $res);
438         $colSize = 16;
439         $title = FALSE;
440         foreach(sqlite_fetch_all($ret) as $entry){
441             foreach($entry as $key => $str){
442                 if(is_numeric($key)) continue;
443                 echo str_pad($str,$colSize,' ')."|"; 
444             }
445             echo "\n";
446         }
447         echo sqlite_error_string($ret);
449         echo "\n------ \n";
450         echo "Time per session\n";
451         echo "------ \n";
453         $query = "
454             SELECT SUM(DURATION) as DUR, UUID
455             FROM {$TABLE_NAME}
456             GROUP BY UUID
457             ORDER BY DUR DESC LIMIT 10";
458         $ret = sqlite_query($query, $res);
460         $colSize = 16;
461         $title = FALSE;
462         foreach(sqlite_fetch_all($ret) as $entry){
463             foreach($entry as $key => $str){
464                 if(is_numeric($key)) continue;
465                 echo str_pad($str,$colSize,' ')."|"; 
466             }
467             echo "\n";
468         }
469         echo sqlite_error_string($ret);
471         echo "\n------ \n";
472         echo "Most used password hashes\n";
473         echo "------ \n";
475         $query = "
476             SELECT DISTINCT(INFO), COUNT(INFO) as CNT
477             FROM {$TABLE_NAME}
478             WHERE ACTION = 'change_password'
479             GROUP BY INFO
480             ORDER BY INFO DESC LIMIT 10";
481         $ret = sqlite_query($query, $res);
483         $colSize = 16;
484         $title = FALSE;
485         foreach(sqlite_fetch_all($ret) as $entry){
486             foreach($entry as $key => $str){
487                 if(is_numeric($key)) continue;
488                 echo str_pad($str,$colSize,' ')."|"; 
489             }
490             echo "\n";
491         }
492         echo sqlite_error_string($ret);
494         echo "\n------ \n";
495         echo "Actions at all\n";
496         echo "------ \n";
498         $query = "
499             SELECT DISTINCT(ACTION), COUNT(ACTION)  AS CNT
500             FROM {$TABLE_NAME}
501             GROUP BY ACTION
502             ORDER BY CNT DESC LIMIT 10";
503         $ret = sqlite_query($query, $res);
505         $colSize = 16;
506         $title = FALSE;
507         foreach(sqlite_fetch_all($ret) as $entry){
508             foreach($entry as $key => $str){
509                 if(is_numeric($key)) continue;
510                 echo str_pad($str,$colSize,' ')."|"; 
511             }
512             echo "\n";
513         }
514         echo sqlite_error_string($ret);
516         echo "\n------ \n";
517         echo "Time spent per action\n";
518         echo "------ \n";
520         $query = "
521             SELECT DISTINCT(ACTION), SUM(DURATION) AS DUR
522             FROM {$TABLE_NAME}
523             GROUP BY ACTION
524             ORDER BY DUR DESC LIMIT 10";
525         $ret = sqlite_query($query, $res);
527         $colSize = 16;
528         $title = FALSE;
529         foreach(sqlite_fetch_all($ret) as $entry){
530             foreach($entry as $key => $str){
531                 if(is_numeric($key)) continue;
532                 echo str_pad($str,$colSize,' ')."|"; 
533             }
534             echo "\n";
535         }
536         echo sqlite_error_string($ret);
538         echo "\n------ \n";
539         echo "Average time per action\n";
540         echo "------ \n";
542         $query = "
543             SELECT DISTINCT(ACTION), AVG(DURATION) AS DUR
544             FROM {$TABLE_NAME}
545             GROUP BY ACTION
546             ORDER BY DUR DESC LIMIT 10";
547         $ret = sqlite_query($query, $res);
549         $colSize = 16;
550         $title = FALSE;
551         foreach(sqlite_fetch_all($ret) as $entry){
552             foreach($entry as $key => $str){
553                 if(is_numeric($key)) continue;
554                 echo str_pad($str,$colSize,' ')."|"; 
555             }
556             echo "\n";
557         }
558         echo sqlite_error_string($ret);
561         echo "\n------ \n";
562         echo "Rendertime per plugin\n";
563         echo "------ \n";
565         $query = "
566             SELECT PLUGIN, RENDER_TIME * 1000000 AS RM
567             FROM {$TABLE_NAME}
568             GROUP BY PLUGIN
569             ";
570         $ret = sqlite_query($query, $res);
572         $colSize = 16;
573         $title = FALSE;
574         foreach(sqlite_fetch_all($ret) as $entry){
575             foreach($entry as $key => $str){
576                 if(is_numeric($key)) continue;
577                 echo str_pad($str,$colSize,' ')."|"; 
578             }
579             echo "\n";
580         }
581         echo sqlite_error_string($ret);
583         echo "</pre>";
584     }
588 ?>