1<?php 2/*========================================================================= 3 4 Program: CDash - Cross-Platform Dashboard System 5 Module: $Id$ 6 Language: PHP 7 Date: $Date$ 8 Version: $Revision$ 9 10 Copyright (c) 2002 Kitware, Inc. All rights reserved. 11 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. 12 13 This software is distributed WITHOUT ANY WARRANTY; without even 14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 15 PURPOSE. See the above copyright notices for more information. 16 17=========================================================================*/ 18require_once("cdash/defines.php"); 19require_once("cdash/pdocore.php"); 20require_once("models/errorlog.php"); 21 22 23function cdash_unlink($filename) 24{ 25 $success = unlink($filename); 26 27// $try_count = 1; 28// 29// while(file_exists($filename) && $try_count < 60) 30// { 31// usleep(1000000); // == 1000 ms, == 1.0 seconds 32// 33// $success = unlink($filename); 34// $try_count++; 35// } 36 37 if (file_exists($filename)) 38 { 39 throw new Exception("file still exists after unlink: $filename"); 40 } 41 42 if (!$success) 43 { 44 throw new Exception("unlink returned non-success: $success for $filename"); 45 } 46 47 return $success; 48} 49 50 51/** Add information to the log file */ 52function add_log($text, $function, $type=LOG_INFO, $projectid=0, $buildid=0, 53 $resourcetype=0, $resourceid=0) 54{ 55 global $CDASH_LOG_FILE; 56 global $CDASH_LOG_FILE_MAXSIZE_MB; 57 global $CDASH_LOG_LEVEL; 58 59 // Check if we are within the log level 60 if($type!= LOG_TESTING && $type>$CDASH_LOG_LEVEL) 61 { 62 return; 63 } 64 65 $logFile = $CDASH_LOG_FILE; 66 if($buildid == 0 && isset($GLOBALS['PHP_ERROR_BUILD_ID'])) //use the global build id as a default if it's set 67 { 68 $buildid = $GLOBALS['PHP_ERROR_BUILD_ID']; 69 } 70 71 if(!file_exists(dirname($logFile))) 72 { 73 $paths = explode(PATH_SEPARATOR, get_include_path()); 74 // Search the include path for the log file 75 foreach($paths as $path) 76 { 77 if(file_exists(dirname("$path/$CDASH_LOG_FILE"))) 78 { 79 $logFile = "$path/$CDASH_LOG_FILE"; 80 break; 81 } 82 } 83 } 84 85 if(strlen($text)==0) 86 { 87 return; 88 } 89 90 // If the size of the log file is bigger than 10 times the allocated memory 91 // we rotate 92 $maxlogsize = $CDASH_LOG_FILE_MAXSIZE_MB*1024*1024/10.0; 93 if(file_exists($logFile) && filesize($logFile)>$maxlogsize) 94 { 95 $tmplogfile = $logFile.".tmp"; 96 if(!file_exists($tmplogfile)) 97 { 98 rename($logFile,$tmplogfile); // This should be quick so we can keep logging 99 100 for($i=9;$i>=0;$i--) 101 { 102 // If we don't have compression we just rename the files 103 if(!function_exists("gzwrite")) 104 { 105 $currentfile = $logFile.".".$i.".txt"; 106 $j = $i+1; 107 $newfile = $logFile.".".$j.".txt"; 108 if(file_exists($newfile)) 109 { 110 cdash_unlink($newfile); 111 } 112 if(file_exists($currentfile)) 113 { 114 rename($currentfile,$newfile); 115 } 116 } 117 else 118 { 119 $currentfile = $logFile.".".$i.".gz"; 120 $j = $i+1; 121 $newfile = $logFile.".".$j.".gz"; 122 if(file_exists($newfile)) 123 { 124 cdash_unlink($newfile); 125 } 126 if(file_exists($currentfile)) 127 { 128 $gz = gzopen($newfile,'wb'); 129 $f = fopen($currentfile,'rb'); 130 while($f && !feof($f)) 131 { 132 gzwrite($gz, fread($f, 8192)); 133 } 134 fclose($f); 135 unset($f); 136 gzclose($gz); 137 unset($gz); 138 } 139 } 140 } 141 142 // Move the current backup 143 if(!function_exists("gzwrite")) 144 { 145 rename($tmplogfile,$logFile.'.0.txt'); 146 } 147 else 148 { 149 $gz = gzopen($logFile.'.0.gz','wb'); 150 $f = fopen($tmplogfile,'rb'); 151 while($f && !feof($f)) 152 { 153 gzwrite($gz, fread($f, 8192)); 154 } 155 fclose($f); 156 unset($f); 157 gzclose($gz); 158 unset($gz); 159 cdash_unlink($tmplogfile); 160 } 161 } // end tmp file doesn't exist 162 } // end log rotation 163 164 $error = ""; 165 if($type != LOG_TESTING) 166 { 167 $error = "[".date(FMT_DATETIME)."]"; 168 } 169 170 // This is parsed by the testing 171 switch($type) 172 { 173 case LOG_INFO: $error.="[INFO]"; break; 174 case LOG_WARNING: $error.="[WARNING]"; break; 175 case LOG_ERR: $error.="[ERROR]"; break; 176 case LOG_TESTING: $error.="[TESTING]";break; 177 } 178 $error .= "[pid=".getmypid()."]"; 179 $error .= "(".$function."): ".$text."\n"; 180 181 $log_pre_exists = file_exists($logFile); 182 183 $logged = error_log($error, 3, $logFile); 184 185 // If there was a problem logging to cdash.log, echo and send it to 186 // PHP's system log: 187 // 188 if (!$logged) 189 { 190 echo "warning: problem logging error to $logFile\n"; 191 echo " $error\n"; 192 echo "\n"; 193 echo "attempting to send to PHP's system log now\n"; 194 echo "\n"; 195 196 error_log($error, 0); 197 } 198 199 // If we just created the logFile, then give it group write permissions 200 // so that command-line invocations of CDash functions can also write to 201 // the same log file. 202 // 203 if (!$log_pre_exists && $logged && file_exists($logFile)) 204 { 205 chmod($logFile, 0664); 206 } 207 208 // Insert in the database 209 if($type == LOG_WARNING || $type==LOG_ERR) 210 { 211 $ErrorLog = new ErrorLog; 212 $ErrorLog->ProjectId = $projectid; 213 $ErrorLog->BuildId = $buildid; 214 switch($type) 215 { 216 // case LOG_INFO: $ErrorLog->Type = 6; break; 217 case LOG_WARNING: $ErrorLog->Type = 5; break; 218 case LOG_ERR: $ErrorLog->Type = 4; break; 219 } 220 $ErrorLog->Description = "(".$function."): ".$text; 221 $ErrorLog->ResourceType = $resourcetype; 222 $ErrorLog->ResourceId = $resourceid; 223 224 $ErrorLog->Insert(); 225 } 226} 227 228 229function begin_timer($context) 230{ 231 global $cdash_timer_stack; 232 if (!isset($cdash_timer_stack)) 233 { 234 $cdash_timer_stack = array(); 235 } 236 237 $timer_entry = array(); 238 $timer_entry[] = $context; 239 $timer_entry[] = microtime_float(); 240 241 $cdash_timer_stack[] = $timer_entry; 242} 243 244 245function end_timer($context, $threshold = -0.001) 246{ 247 global $cdash_timer_stack; 248 if (!isset($cdash_timer_stack)) 249 { 250 trigger_error( 251 'end_timer called before begin_timer', 252 E_USER_WARNING); 253 } 254 255 $end_time = microtime_float(); 256 257 $n = count($cdash_timer_stack)-1; 258 $timer_entry = $cdash_timer_stack[$n]; 259 $begin_context = $timer_entry[0]; 260 $begin_time = $timer_entry[1]; 261 262 if ($context != $begin_context) 263 { 264 trigger_error( 265 'end_timer called with different context than begin_timer', 266 E_USER_WARNING); 267 } 268 269 array_pop($cdash_timer_stack); 270 271 $text = ''; 272 for($i = 0; $i < $n; ++$i) 273 { 274 $text .= ' '; 275 } 276 277 $delta = $end_time - $begin_time; 278 279 $text .= $context . ', ' . round($delta, 3) . ' seconds'; 280 281 if ($delta > $threshold) 282 { 283 add_log($text, "end_timer"); 284 } 285} 286?> 287