source: trunk/web/addons/toga/libtoga.php @ 124

Last change on this file since 124 was 124, checked in by bastiaans, 19 years ago

web/addons/toga/templates/overview.tpl:

  • Setup javascript for multiple filters
  • Cosmetic updates

web/addons/toga/index.php:

  • Rearranged filter order

web/addons/toga/overview.php:

  • Changed for multiple filters
  • Cosmetic updates

web/addons/toga/image.php:

  • Changed for multiple filters

web/addons/toga/libtoga.php:

  • Changed filterNodes() for multiple filters
File size: 13.7 KB
Line 
1<?php
2// If php is compiled without globals
3//
4if ( !empty( $_GET ) ) {
5        extract( $_GET );
6}
7
8class HTTPVariables {
9
10        var $clustername, $metricname;
11        var $restvars, $httpvars;
12
13        function HTTPVariables( $httpvars, $getvars ) {
14
15                $this->restvars = array();
16
17                $this->clustername = $httpvars["c"] ? $httpvars["c"] : null;
18                $this->metricname = $httpvars["m"] ? $httpvars["m"] : null;
19
20                foreach( $httpvars as $httpvar => $httpval ) {
21                       
22                        if( $httpval ) {
23                                $this->restvars[$httpvar] = $httpval;
24                        }
25                }
26
27                foreach( $getvars as $getvar => $getval ) {
28
29                        if( $getval ) {
30                                $this->restvars[$getvar] = $getval;
31                        }
32                }
33        }
34
35        function getClusterName() {
36                return $this->clustername;
37        }
38
39        function getMetricName() {
40                return $this->metricname;
41        }
42
43        function getHttpVar( $var ) {
44                if( isset( $this->restvars[$var] ) )
45                        return $this->restvars[$var];
46                else
47                        return null;
48        }
49}
50
51// Toga's conf
52//
53include_once "./conf.php";
54
55global $GANGLIA_PATH;
56
57$my_dir = getcwd();
58
59// Load Ganglia's PHP
60chdir( $GANGLIA_PATH );
61
62include_once "./conf.php";
63include_once "./functions.php";
64include_once "./ganglia.php";
65include_once "./get_context.php";
66include_once "./get_ganglia.php";
67
68// Back to our PHP
69chdir( $my_dir );
70
71global $SMALL_CLUSTERIMAGE_MAXWIDTH, $SMALL_CLUSTERIMAGE_NODEWIDTH, $DATA_SOURCE, $HTTP_GET_VARS, $_GET;
72$httpvars = new HTTPVariables( $HTTP_GET_VARS, $_GET );
73
74// Set cluster context so that Ganglia will
75// provide us with the correct metrics array
76//
77global $context, $clustername;
78//$clustername = $httpvars->getClusterName();
79//$context = 'cluster';
80
81// Ganglia's array of host metrics
82//
83global $metrics;
84
85
86class DataSource {
87
88        var $data, $ip, $port;
89
90        function DataSource( $ip = '127.0.0.1', $port = 8649 ) {
91                $this->ip = $ip;
92                $this->port = $port;
93        }
94
95        function getData() {
96
97                $errstr;
98                $errno = 0;
99                $timeout = 3;
100
101                $fp = fsockopen( $this->ip, $this->port, &$errno, &$errstr, $timeout );
102
103                if( !$fp ) {
104                        echo 'Unable to connect to '.$this->ip.':'.$this->port; // printf( 'Unable to connect to [%s:%.0f]', $this->ip, $this->port );
105                        return;
106                }
107
108                while ( !feof( $fp ) ) {
109                       
110                        $data .= fread( $fp, 16384 );
111                }
112
113                fclose( $fp );
114
115                return $data;
116        }
117}
118
119class DataGatherer {
120
121        var $xmlhandler, $data, $httpvars;
122
123        function DataGatherer() {
124
125                global $DATA_SOURCE;
126               
127                $ds_fields = explode( ':', $DATA_SOURCE );
128                $ds_ip = $ds_fields[0];
129                $ds_port = $ds_fields[1];
130
131                $this->source = new DataSource( $ds_ip, $ds_port );
132
133                $this->parser = xml_parser_create();
134                $this->httpvars = $httpvars;
135                $this->xmlhandler = new TorqueXMLHandler();
136                xml_set_element_handler( $this->parser, array( &$this->xmlhandler, 'startElement' ), array( &$this->xmlhandler, 'stopElement' ) );
137        }
138
139        function parseXML() {
140
141                $src = &$this->source;
142                $this->data = $src->getData();
143
144                if ( !xml_parse( &$this->parser, $this->data ) )
145                        $error = sprintf( 'XML error: %s at %d', xml_error_string( xml_get_error_code( &$this->parser ) ), xml_get_current_line_number( &$this->parser ) );
146        }
147
148        function printInfo() {
149                $handler = $this->xmlhandler;
150                $handler->printInfo();
151        }
152
153        function getNodes() {
154                $handler = $this->xmlhandler;
155                return $handler->getNodes();
156        }
157
158        function getCpus() {
159                $handler = $this->xmlhandler;
160                return $handler->getCpus();
161        }
162
163        function getJobs() {
164                $handler = $this->xmlhandler;
165                return $handler->getJobs();
166        }
167
168        function getHeartbeat() {
169                $handler = $this->xmlhandler;
170                return $handler->getHeartbeat();
171        }
172}
173
174class TorqueXMLHandler {
175
176        var $clusters, $heartbeat, $nodes, $jobs;
177
178        function TorqueXMLHandler() {
179                $jobs = array();
180                $clusters = array();
181                $nodes = array();
182                $heartbeat = array();
183        }
184
185        function getCpus() {
186
187                $cpus = 0;
188
189                foreach( $this->jobs as $jobid=>$jobattrs ) {
190
191                        $nodes = count( $jobattrs[nodes] );
192                        $ppn = (int) $jobattrs[ppn] ? $jobattrs[ppn] : 1;
193                        $mycpus = $nodes * $ppn;
194
195                        $cpus = $cpus + $mycpus;
196                }
197        }
198
199        function startElement( $parser, $name, $attrs ) {
200
201                $jobs = &$this->jobs;
202                $nodes = &$this->nodes;
203
204                if ( $attrs[TN] ) {
205
206                        // Ignore dead metrics. Detect and mask failures.
207                        if ( $attrs[TN] > $attrs[TMAX] * 4 )
208                                return;
209                }
210
211                $jobid = null;
212
213                // printf( '%s=%s', $attrs[NAME], $attrs[VAL] );
214
215                if( $name == 'CLUSTER' ) {
216
217                        $clustername = $attrs[VAL];
218
219                        if( !isset( $clusters[$clustername] ) )
220                                $clusters[$clustername] = array();
221
222                } else if( $name == 'HOST' ) {
223
224                        $hostname = $attrs[NAME];
225                        $location = $attrs[LOCATION];
226
227                        if( !isset( $this->nodes[$hostname] ) )
228                                $this->nodes[$hostname] = new NodeImage( $hostname );
229
230                } else if( $name == 'METRIC' and strstr( $attrs[NAME], 'TOGA' ) ) {
231
232                        if( strstr( $attrs[NAME], 'TOGA-HEARTBEAT' ) ) {
233
234                                $this->heartbeat['time'] = $attrs[VAL];
235                                //printf( "heartbeat %s\n", $heartbeat['time'] );
236
237                        } else if( strstr( $attrs[NAME], 'TOGA-JOB' ) ) {
238
239                                sscanf( $attrs[NAME], 'TOGA-JOB-%d', $jobid );
240
241                                //printf( "jobid %s\n", $jobid );
242
243                                if( !isset( $jobs[$jobid] ) )
244                                        $jobs[$jobid] = array();
245
246                                $fields = explode( ' ', $attrs[VAL] );
247
248                                foreach( $fields as $f ) {
249                                        $togavalues = explode( '=', $f );
250
251                                        $toganame = $togavalues[0];
252                                        $togavalue = $togavalues[1];
253
254                                        //printf( "\t%s\t= %s\n", $toganame, $togavalue );
255
256                                        if( $toganame == 'nodes' ) {
257
258                                                if( !isset( $jobs[$jobid][$toganame] ) )
259                                                        $jobs[$jobid][$toganame] = array();
260
261                                                $mynodes = explode( ';', $togavalue );
262
263                                                foreach( $mynodes as $node )
264
265                                                        $jobs[$jobid][$toganame][] = $node;
266                                        } else {
267
268                                                $jobs[$jobid][$toganame] = $togavalue;
269                                        }
270                                }
271
272                                if( isset( $jobs[$jobid][domain] ) and isset( $jobs[$jobid][nodes] ) ) {
273                       
274                                        $nr_nodes = count( $jobs[$jobid][nodes] );
275                       
276                                        foreach( $jobs[$jobid][nodes] as $node ) {
277
278                                                $host = $node.'.'.$jobs[$jobid][domain];
279                               
280                                                if( !isset( $this->nodes[$host] ) )
281                                                        $my_node = new NodeImage( $host );
282                                                else
283                                                        $my_node = $this->nodes[$host];
284
285                                                if( !$my_node->hasJob( $jobid ) )
286
287                                                        if( isset( $jobs[$jobid][ppn] ) )
288                                                                $my_node->addJob( $jobid, ((int) $jobs[$jobid][ppn]) );
289                                                        else
290                                                                $my_node->addJob( $jobid, 1 );
291
292                                                $this->nodes[$host] = $my_node;
293                                        }
294                                }
295                        }
296                }
297                $this->jobs = $jobs;
298        }
299
300        function stopElement( $parser, $name ) {
301        }
302
303        function printInfo() {
304
305                $jobs = &$this->jobs;
306
307                printf( "---jobs---\n" );
308
309                foreach( $jobs as $jobid => $job ) {
310
311                        printf( "job %s\n", $jobid );
312
313                        if( isset( $job[nodes] ) ) {
314
315                                foreach( $job[nodes] as $node ) {
316
317                                        $mynode = $this->nodes[$node];
318                                        $hostname = $mynode->getHostname();
319                                        $location = $mynode->getLocation();
320
321                                        printf( "\t- node %s\tlocation %s\n", $hostname, $location );
322                                        //$this->nodes[$hostname]->setLocation( "hier draait job ".$jobid );
323                                }
324                        }
325                }
326
327                printf( "---nodes---\n" );
328
329                $nodes = &$this->nodes;
330
331                foreach( $nodes as $node ) {
332
333                        $hostname = $node->getHostname();
334                        $location = $node->getLocation();
335                        $jobs = implode( ' ', $node->getJobs() );
336                        printf( "* node %s\tlocation %s\tjobs %s\n", $hostname, $location, $jobs );
337                }
338        }
339
340        function getNodes() {
341                return $this->nodes;
342        }
343
344        function getJobs() {
345                return $this->jobs;
346        }
347
348        function getHeartbeat() {
349                return $this->heartbeat['time'];
350        }
351}
352
353class NodeImage {
354
355        var $image, $x, $y, $hostname, $jobs, $tasks, $showinfo;
356
357        function NodeImage( $hostname ) {
358
359                $this->jobs = array();
360                //$this->image = $image;
361                //$this->x = $x;
362                //$this->y = $y;
363                $this->tasks = 0;
364                $this->hostname = $hostname;
365                $this->cpus = $this->determineCpus();
366                $this->showinfo = 1;
367        }
368
369        function addJob( $jobid, $cpus ) {
370                $jobs = &$this->jobs;
371
372                $jobs[] = $jobid;
373                $this->jobs = $jobs;
374
375                $this->addTask( $cpus );
376        }
377
378        function hasJob( $jobid ) {
379
380                $jobfound = 0;
381
382                if( count( $this->jobs ) > 0 )
383                        foreach( $this->jobs as $job )
384
385                                if( $job == $jobid )
386                                        $jobfound = 1;
387
388                return $jobfound;
389        }
390
391        function addTask( $cpus ) {
392
393                $this->tasks = $this->tasks + $cpus;
394        }
395
396        function setImage( $image ) {
397
398                $this->image = $image;
399        }
400
401        function setCoords( $x, $y ) {
402
403                $this->x = $x;
404                $this->y = $y;
405        }
406
407        function colorHex( $color ) {
408       
409                $my_color = imageColorAllocate( $this->image, hexdec( substr( $color, 0, 2 )), hexdec( substr( $color, 2, 2 )), hexdec( substr( $color, 4, 2 )) );
410
411                return $my_color;
412        }
413
414        function setLoad( $load ) {
415                $this->load = $load;
416        }
417
418        function setHostname( $hostname ) {
419                $this->hostname = $hostname;
420        }
421
422        function getHostname() {
423                return $this->hostname;
424        }
425
426        function getJobs() {
427                return $this->jobs;
428        }
429
430        function setShowinfo( $showinfo ) {
431                $this->showinfo = $showinfo;
432        }
433
434        function draw() {
435
436                $this->drawSmall();
437        }
438
439        function drawBig() {
440
441        }
442
443        function drawSmall() {
444
445                global $SMALL_CLUSTERIMAGE_NODEWIDTH;
446                global $JOB_NODE_MARKING;
447
448                $black_color = imageColorAllocate( $this->image, 0, 0, 0 );
449                $size = $SMALL_CLUSTERIMAGE_NODEWIDTH;
450
451                imageFilledRectangle( $this->image, $this->x, $this->y, $this->x+($size), $this->y+($size), $black_color );
452
453                if( $this->showinfo) {
454               
455                        $this->load = $this->determineLoad();
456
457                        if( !isset( $this->image ) or !isset( $this->x ) or !isset( $this->y ) ) {
458                                printf( "aborting\n" );
459                                printf( "x %d y %d load %f\n", $this->x, $this->y, $load );
460                                return;
461                        }
462
463
464                        // Convert Ganglias Hexadecimal load color to a Decimal one
465                        //
466                        $load = $this->determineLoad(); 
467                        $usecolor = $this->colorHex( load_color($load) );
468                        imageFilledRectangle( $this->image, $this->x+1, $this->y+1, $this->x+($size-1), $this->y+($size-1), $usecolor );
469                        if( count( $this->jobs ) > 0 )
470                                imageString( $this->image, 1, $this->x+(($size/2)-2), $this->y+(($size/2)-3), $JOB_NODE_MARKING, $black_color );
471
472                } else {
473
474                        // White
475                        $usecolor = imageColorAllocate( $this->image, 255, 255, 255 );
476                        imageFilledRectangle( $this->image, $this->x+1, $this->y+1, $this->x+($size-1), $this->y+($size-1), $usecolor );
477                }
478
479
480        }
481
482        function determineCpus() {
483
484                global $metrics;
485
486                $cpus = $metrics[$this->hostname][cpu_num][VAL];
487                if (!$cpus) $cpus=1;
488
489                return $cpus;
490        }
491
492        function determineLoad() {
493
494                global $metrics;
495
496                $load_one = $metrics[$this->hostname][load_one][VAL];
497                $load = ((float) $load_one)/$this->cpus;
498
499                return $load;
500        }
501}
502
503class ClusterImage {
504
505        var $dataget, $image, $clustername;
506        var $filtername, $filters;
507
508        function ClusterImage( $clustername ) {
509
510                $this->dataget = new DataGatherer();
511                $this->clustername = $clustername;
512                $this->filters = array();
513        }
514
515        function setFilter( $filtername, $filtervalue ) {
516
517                //printf("filter %s = %s\n", $filtername, $filtervalue );
518                //printf( "filter set to %s = %s\n", $filtername, $filtervalue );
519                $this->filters[$filtername] = $filtervalue;
520                //print_r($this->filters);
521        }
522
523        function filterNodes( $jobs, $nodes ) {
524
525                $filtered_nodes = array();
526
527                foreach( $nodes as $node ) {
528
529                        $hostname = $node->getHostname();
530
531                        $addhost = 1;
532
533                        if( count( $this->filters ) > 0 ) {
534
535                                $mynjobs = $node->getJobs();
536
537                                if( count( $mynjobs ) > 0 ) {
538
539                                        foreach( $mynjobs as $myjob ) {
540
541                                                foreach( $this->filters as $filtername => $filtervalue ) {
542
543                                                        //printf("filter bla %s = %s\n", $filtername,$filtervalue );
544
545                                                        if( $filtername!=null && $filtername!='' ) {
546
547                                                                if( $filtername == 'jobid' && !$node->hasJob( $filtervalue) ) {
548                                                                        $addhost = 0;
549                                                                        //printf("host %s has no job %s\n", $hostname, $filtervalue);
550                                                                } else if( $filtername != 'jobid' ) {
551                                                                        //printf("myjob is %s\n", $myjob );
552                                                                        if( $jobs[$myjob][$filtername] != $filtervalue ) {
553                                                                                //printf("host %s has no job with %s=%s\n", $hostname, $filtername, $filtervalue);
554                                                                                $addhost = 0;
555                                                                        }
556                                                                }
557                                                        }
558                                                }
559                                        }
560                                } else
561                                        $addhost = 0;
562                        }
563
564                        if( $addhost )
565                                $filtered_nodes[] = $hostname;
566                }
567
568                return $filtered_nodes;
569        }
570
571        function draw() {
572
573                //printf("stopt met uitvoer");
574                //return;
575
576                global $SMALL_CLUSTERIMAGE_MAXWIDTH, $SMALL_CLUSTERIMAGE_NODEWIDTH;
577       
578                $mydatag = $this->dataget;
579                $mydatag->parseXML();
580
581                //$max_width = 250;
582                //$node_width = 11;
583
584                $max_width = $SMALL_CLUSTERIMAGE_MAXWIDTH;
585                $node_width = $SMALL_CLUSTERIMAGE_NODEWIDTH;
586
587                //printf( "cmaxw %s nmaxw %s", $SMALL_CLUSTERIMAGE_MAXWIDTH, $SMALL_CLUSTERIMAGE_NODEWIDTH );
588
589                $nodes = $mydatag->getNodes();
590                $nodes_hosts = array_keys( $nodes );
591
592                $nodes_nr = count( $nodes );
593
594                $nodes_size = $nodes_nr*$node_width;
595                $node_rows = 0;
596
597                if( $nodes_size > $max_width ) {
598                        $nodes_per_row = ( (int) ($max_width/$node_width) );
599                } else {
600                        $nodes_per_row = $nodes_size;
601                        $node_rows = 1;
602                }
603
604                if( $nodes_per_row < $nodes_nr ) {
605                        $node_rows = ( (int) ($nodes_nr/$nodes_per_row) );
606                        $node_rest = fmod( $nodes_nr, $nodes_per_row );
607                        //printf( "nodesnr %d noderest %f\n", $nodes_nr, $node_rest );
608                        if( $node_rest > 0 ) {
609                                $node_rows++;
610                                //printf( "noderows %d\n", $node_rows );
611                        }
612                }
613
614                //printf( "imagecreate: %dx%d", ($nodes_per_row*$node_width), ($node_rows*$node_width) );
615                $image = imageCreateTrueColor( ($nodes_per_row*$node_width)+1, ($node_rows*$node_width)+1 );
616                $colorwhite = imageColorAllocate( $image, 255, 255, 255 );
617                imageFill( $image, 0, 0, $colorwhite );
618
619                $jobs = $mydatag->getJobs();
620                //printf("filtername = %s\n", $filtername );
621                $filtered_nodes = $this->filterNodes( $jobs, $nodes );
622
623                //print_r($filtered_nodes);
624
625                for( $n = 0; $n < $node_rows; $n++ ) {
626                       
627                        for( $m = 0; $m < $nodes_per_row; $m++ ) {
628                       
629                                $x = ($m * $node_width);
630                                $y = ($n * $node_width);
631
632                                $cur_node = ($n * $nodes_per_row) + ($m);
633                                $host = $nodes_hosts[$cur_node];
634
635
636                                if( isset( $nodes[$host] ) ) {
637
638                                        $nodes[$host]->setCoords( $x, $y );
639                                        $nodes[$host]->setImage( $image );
640
641                                        if( !in_array( $host, $filtered_nodes ) )
642                                                $nodes[$host]->setShowinfo( 0 );
643
644                                        $nodes[$host]->draw();
645                                }
646                        }
647                }
648               
649                header( 'Content-type: image/png' );
650                imagePNG( $image );
651                imageDestroy( $image );
652        }
653}
654
655//$my_data = new DataGatherer();
656//$my_data->parseXML();
657//$my_data->printInfo();
658
659//$ic = new ClusterImage( "LISA Cluster" );
660//$ic->draw();
661?>
Note: See TracBrowser for help on using the repository browser.