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

Last change on this file since 111 was 111, checked in by bastiaans, 18 years ago

toga/conf.php:

  • How nodes will be marked with a job is now configurable

toga/image.php:

  • Really use clustername for image

toga/libtoga.php:

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