1 | 13 | simandl | <?php |
2 | 1 | simandl | // 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 | | | |
5 | 13 | simandl | function 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 | | | |
15 | 85 | simandl | function 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 | | | |
30 | | | function 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 | | | |
49 | 1 | simandl | function weathermap_run_maps($mydir) { |
50 | | | global $config; |
51 | | | global $weathermap_debugging, $WEATHERMAP_VERSION; |
52 | 85 | simandl | global $weathermap_map; |
53 | | | global $weathermap_warncount; |
54 | | | global $weathermap_poller_start_time; |
55 | 1 | simandl | |
56 | | | include_once($mydir.DIRECTORY_SEPARATOR."HTML_ImageMap.class.php"); |
57 | | | include_once($mydir.DIRECTORY_SEPARATOR."Weathermap.class.php"); |
58 | | | |
59 | 85 | simandl | $total_warnings = 0; |
60 | | | |
61 | | | $start_time = time(); |
62 | | | if($weathermap_poller_start_time==0) $weathermap_poller_start_time = $start_time; |
63 | | | |
64 | 1 | simandl | $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 | 85 | simandl | if($quietlogging==0) cacti_log("Weathermap $WEATHERMAP_VERSION starting - $mode_message\n",true,"WEATHERMAP"); |
82 | 1 | simandl | |
83 | | | if(module_checks()) |
84 | | | { |
85 | 13 | simandl | weathermap_memory_check("MEM Initial"); |
86 | 1 | simandl | // 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 | 85 | simandl | db_execute("replace into settings values('weathermap_last_start_time','".mysql_escape_string(time())."')"); |
91 | | | |
92 | 1 | simandl | // 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 | 85 | simandl | $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 | 1 | simandl | |
106 | | | if( is_array($queryrows) ) |
107 | | | { |
108 | | | debug("Iterating all maps."); |
109 | | | |
110 | | | $imageformat = strtolower(read_config_option("weathermap_output_format")); |
111 | 85 | simandl | $rrdtool_path = read_config_option("path_rrdtool"); |
112 | 1 | simandl | |
113 | | | foreach ($queryrows as $map) { |
114 | 85 | simandl | // 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 | 1 | simandl | { |
123 | 85 | simandl | $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 | 1 | simandl | |
128 | 85 | simandl | 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 | 1 | simandl | |
137 | 85 | simandl | // we can grab the rrdtool path from Cacti's config, in this case |
138 | | | $wmap->rrdtool = $rrdtool_path; |
139 | 1 | simandl | |
140 | 85 | simandl | $wmap->ReadConfig($mapfile); |
141 | 1 | simandl | |
142 | 85 | simandl | $wmap->add_hint("mapgroup",$map['groupname']); |
143 | | | $wmap->add_hint("mapgroupextra",($map['group_id'] ==1 ? "" : $map['groupname'] )); |
144 | 1 | simandl | |
145 | 85 | simandl | # 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 | 1 | simandl | { |
153 | 85 | simandl | $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 | 1 | simandl | } |
198 | | | else |
199 | | | { |
200 | 85 | simandl | 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 | 1 | simandl | } |
209 | 85 | simandl | |
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 | 1 | simandl | } |
225 | 85 | simandl | 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 | 1 | simandl | } |
234 | | | else |
235 | | | { |
236 | 85 | simandl | debug("Skipping ".$map['id']." (".$map['configfile'].") due to schedule.\n"); |
237 | 1 | simandl | } |
238 | | | } |
239 | 85 | simandl | debug("Iterated all $mapcount maps.\n"); |
240 | 1 | simandl | } |
241 | | | else |
242 | | | { |
243 | 85 | simandl | if($quietlogging==0) warn("No activated maps found. [WMPOLL05]\n"); |
244 | 1 | simandl | } |
245 | | | } |
246 | | | else |
247 | | | { |
248 | 85 | simandl | 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 | 1 | simandl | } |
250 | | | } |
251 | | | else |
252 | | | { |
253 | 85 | simandl | 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 | 1 | simandl | } |
255 | 13 | simandl | weathermap_memory_check("MEM Final"); |
256 | 1 | simandl | chdir($orig_cwd); |
257 | 85 | simandl | $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 | 1 | simandl | } |
264 | | | else |
265 | | | { |
266 | 85 | simandl | warn("Required modules for PHP Weathermap $WEATHERMAP_VERSION were not present. Not running. [WMPOLL08]\n"); |
267 | 1 | simandl | } |
268 | | | } |
269 | | | |
270 | | | // vim:ts=4:sw=4: |
271 | | | ?> |