1<?php 2// common code used by the poller, the manual-run from the Cacti UI, and from the command-line manual-run. 3// this is the easiest way to keep it all consistent! 4 5function weathermap_memory_check($note="MEM") 6{ 7 if(function_exists("memory_get_usage")) 8 { 9 $mem_used = nice_bandwidth(memory_get_usage()); 10 $mem_allowed = ini_get("memory_limit"); 11 debug("$note: memory_get_usage() says ".$mem_used."Bytes used. Limit is ".$mem_allowed."\n"); 12 } 13} 14 15function weathermap_cron_part($value,$checkstring) 16{ 17 // XXX - this should really handle a few more crontab niceties like */5 or 3,5-9 but this will do for now 18 if($checkstring == '*') return(true); 19 if($checkstring == sprintf("%s",$value) ) return(true); 20 21 if( preg_match("/\*\/(\d+)/",$checkstring, $matches)) 22 { 23 $mod = $matches[1]; 24 if( ($value % $mod ) == 0) return true; 25 } 26 27 return (false); 28} 29 30function weathermap_check_cron($time,$string) 31{ 32 if($string == '') return(true); 33 if($string == '*') return(true); 34 35 $lt = localtime($time, true); 36 list($minute,$hour,$wday,$day,$month) = preg_split('/\s+/',$string); 37 38 $matched = true; 39 40 $matched = $matched && weathermap_cron_part($lt['tm_min'],$minute); 41 $matched = $matched && weathermap_cron_part($lt['tm_hour'],$hour); 42 $matched = $matched && weathermap_cron_part($lt['tm_wday'],$wday); 43 $matched = $matched && weathermap_cron_part($lt['tm_mday'],$day); 44 $matched = $matched && weathermap_cron_part($lt['tm_mon']+1,$month); 45 46 return($matched); 47} 48 49function weathermap_run_maps($mydir) { 50 global $config; 51 global $weathermap_debugging, $WEATHERMAP_VERSION; 52 global $weathermap_map; 53 global $weathermap_warncount; 54 global $weathermap_poller_start_time; 55 56 include_once($mydir.DIRECTORY_SEPARATOR."HTML_ImageMap.class.php"); 57 include_once($mydir.DIRECTORY_SEPARATOR."Weathermap.class.php"); 58 59 $total_warnings = 0; 60 61 $start_time = time(); 62 if($weathermap_poller_start_time==0) $weathermap_poller_start_time = $start_time; 63 64 $outdir = $mydir.DIRECTORY_SEPARATOR.'output'; 65 $confdir = $mydir.DIRECTORY_SEPARATOR.'configs'; 66 67 $mapcount = 0; 68 69 // take our debugging cue from the poller - turn on Poller debugging to get weathermap debugging 70 if (read_config_option("log_verbosity") >= POLLER_VERBOSITY_DEBUG) 71 { 72 $weathermap_debugging = TRUE; 73 $mode_message = "DEBUG mode is on"; 74 } 75 else 76 { 77 $mode_message = "Normal logging mode. Turn on DEBUG in Cacti for more information"; 78 } 79 $quietlogging = read_config_option("weathermap_quiet_logging"); 80 // moved this outside the module_checks, so there should always be something in the logs! 81 if($quietlogging==0) cacti_log("Weathermap $WEATHERMAP_VERSION starting - $mode_message\n",true,"WEATHERMAP"); 82 83 if(module_checks()) 84 { 85 weathermap_memory_check("MEM Initial"); 86 // move to the weathermap folder so all those relatives paths don't *have* to be absolute 87 $orig_cwd = getcwd(); 88 chdir($mydir); 89 90 db_execute("replace into settings values('weathermap_last_start_time','".mysql_escape_string(time())."')"); 91 92 // first, see if the output directory even exists 93 if(is_dir($outdir)) 94 { 95 // next, make sure that we stand a chance of writing files 96 //// $testfile = realpath($outdir."weathermap.permissions.test"); 97 $testfile = $outdir.DIRECTORY_SEPARATOR."weathermap.permissions.test"; 98 $testfd = fopen($testfile, 'w'); 99 if($testfd) 100 { 101 fclose($testfd); 102 unlink($testfile); 103 104 $queryrows = db_fetch_assoc("select m.*, g.name as groupname from weathermap_maps m,weathermap_groups g where m.group_id=g.id and active='on' order by sortorder,id"); 105 106 if( is_array($queryrows) ) 107 { 108 debug("Iterating all maps."); 109 110 $imageformat = strtolower(read_config_option("weathermap_output_format")); 111 $rrdtool_path = read_config_option("path_rrdtool"); 112 113 foreach ($queryrows as $map) { 114 // reset the warning counter 115 $weathermap_warncount=0; 116 // this is what will prefix log entries for this map 117 $weathermap_map = "[Map ".$map['id']."] ".$map['configfile']; 118 119 debug("FIRST TOUCH\n"); 120 121 if(weathermap_check_cron($weathermap_poller_start_time,$map['schedule'])) 122 { 123 $mapfile = $confdir.DIRECTORY_SEPARATOR.$map['configfile']; 124 $htmlfile = $outdir.DIRECTORY_SEPARATOR.$map['filehash'].".html"; 125 $imagefile = $outdir.DIRECTORY_SEPARATOR.$map['filehash'].".".$imageformat; 126 $thumbimagefile = $outdir.DIRECTORY_SEPARATOR.$map['filehash'].".thumb.".$imageformat; 127 128 if(file_exists($mapfile)) 129 { 130 if($quietlogging==0) warn("Map: $mapfile -> $htmlfile & $imagefile\n",TRUE); 131 db_execute("replace into settings values('weathermap_last_started_file','".mysql_escape_string($weathermap_map)."')"); 132 $map_start = time(); 133 weathermap_memory_check("MEM starting $mapcount"); 134 $wmap = new Weathermap; 135 $wmap->context = "cacti"; 136 137 // we can grab the rrdtool path from Cacti's config, in this case 138 $wmap->rrdtool = $rrdtool_path; 139 140 $wmap->ReadConfig($mapfile); 141 142 $wmap->add_hint("mapgroup",$map['groupname']); 143 $wmap->add_hint("mapgroupextra",($map['group_id'] ==1 ? "" : $map['groupname'] )); 144 145 # in the order of precedence - global extras, group extras, and finally map extras 146 $queries = array(); 147 $queries[] = "select * from weathermap_settings where mapid=0 and groupid=0"; 148 $queries[] = "select * from weathermap_settings where mapid=0 and groupid=".intval($map['group_id']); 149 $queries[] = "select * from weathermap_settings where mapid=".intval($map['id']); 150 151 foreach ($queries as $sql) 152 { 153 $settingrows = db_fetch_assoc($sql); 154 if( is_array($settingrows) && count($settingrows) > 0 ) 155 { 156 157 foreach ($settingrows as $setting) 158 { 159 if($setting['mapid']==0 && $setting['groupid']==0) 160 { 161 debug("Setting additional (all maps) option: ".$setting['optname']." to '".$setting['optvalue']."'\n"); 162 $wmap->add_hint($setting['optname'],$setting['optvalue']); 163 } 164 elseif($setting['groupid']!=0) 165 { 166 debug("Setting additional (all maps in group) option: ".$setting['optname']." to '".$setting['optvalue']."'\n"); 167 $wmap->add_hint($setting['optname'],$setting['optvalue']); 168 } 169 else 170 { debug("Setting additional map-global option: ".$setting['optname']." to '".$setting['optvalue']."'\n"); 171 $wmap->add_hint($setting['optname'],$setting['optvalue']); 172 } 173 } 174 } 175 } 176 177 weathermap_memory_check("MEM postread $mapcount"); 178 $wmap->ReadData(); 179 weathermap_memory_check("MEM postdata $mapcount"); 180 181 // why did I change this before? It's useful... 182 // $wmap->imageuri = $config['url_path'].'/plugins/weathermap/output/weathermap_'.$map['id'].".".$imageformat; 183 $wmap->imageuri = 'weathermap-cacti-plugin.php?action=viewimage&id='.$map['filehash']."&time=".time(); 184 185 if($quietlogging==0) warn("About to write image file. If this is the last message in your log, increase memory_limit in php.ini [WMPOLL01]\n",TRUE); 186 weathermap_memory_check("MEM pre-render $mapcount"); 187 188 $wmap->DrawMap($imagefile,$thumbimagefile,read_config_option("weathermap_thumbsize")); 189 190 if($quietlogging==0) warn("Wrote map to $imagefile and $thumbimagefile\n",TRUE); 191 $fd = @fopen($htmlfile, 'w'); 192 if($fd != FALSE) 193 { 194 fwrite($fd, $wmap->MakeHTML('weathermap_'.$map['filehash'].'_imap')); 195 fclose($fd); 196 debug("Wrote HTML to $htmlfile"); 197 } 198 else 199 { 200 if(file_exists($htmlfile)) 201 { 202 warn("Failed to overwrite $htmlfile - permissions of existing file are wrong? [WMPOLL02]\n"); 203 } 204 else 205 { 206 warn("Failed to create $htmlfile - permissions of output directory are wrong? [WMPOLL03]\n"); 207 } 208 } 209 210 $processed_title = $wmap->ProcessString($wmap->title,$wmap); 211 212 db_execute("update weathermap_maps set titlecache='".mysql_real_escape_string($processed_title)."' where id=".intval($map['id'])); 213 if(intval($wmap->thumb_width) > 0) 214 { 215 db_execute("update weathermap_maps set thumb_width=".intval($wmap->thumb_width).", thumb_height=".intval($wmap->thumb_height)." where id=".intval($map['id'])); 216 } 217 218 unset($wmap); 219 $map_duration = time() - $map_start; 220 debug("TIME: $mapfile took $map_duration seconds.\n"); 221 weathermap_memory_check("MEM after $mapcount"); 222 $mapcount++; 223 db_execute("replace into settings values('weathermap_last_finished_file','".mysql_escape_string($weathermap_map)."')"); 224 } 225 else 226 { 227 warn("Mapfile $mapfile is not readable or doesn't exist [WMPOLL04]\n"); 228 } 229 db_execute("update weathermap_maps set warncount=".intval($weathermap_warncount)." where id=".intval($map['id'])); 230 $total_warnings += $weathermap_warncount; 231 $weathermap_warncount = 0; 232 $weathermap_map=""; 233 } 234 else 235 { 236 debug("Skipping ".$map['id']." (".$map['configfile'].") due to schedule.\n"); 237 } 238 } 239 debug("Iterated all $mapcount maps.\n"); 240 } 241 else 242 { 243 if($quietlogging==0) warn("No activated maps found. [WMPOLL05]\n"); 244 } 245 } 246 else 247 { 248 warn("Output directory ($outdir) isn't writable (tried to create '$testfile'). No maps created. You probably need to make it writable by the poller process (like you did with the RRA directory) [WMPOLL06]\n"); 249 } 250 } 251 else 252 { 253 warn("Output directory ($outdir) doesn't exist!. No maps created. You probably need to create that directory, and make it writable by the poller process (like you did with the RRA directory) [WMPOLL07]\n"); 254 } 255 weathermap_memory_check("MEM Final"); 256 chdir($orig_cwd); 257 $duration = time() - $start_time; 258 259 $stats_string = date(DATE_RFC822) . ": $mapcount maps were run in $duration seconds with $total_warnings warnings."; 260 if($quietlogging==0) warn("STATS: Weathermap $WEATHERMAP_VERSION run complete - $stats_string\n", TRUE); 261 db_execute("replace into settings values('weathermap_last_stats','".mysql_escape_string($stats_string)."')"); 262 db_execute("replace into settings values('weathermap_last_finish_time','".mysql_escape_string(time())."')"); 263 } 264 else 265 { 266 warn("Required modules for PHP Weathermap $WEATHERMAP_VERSION were not present. Not running. [WMPOLL08]\n"); 267 } 268} 269 270// vim:ts=4:sw=4: 271?> 272