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

Last change on this file since 111 was 111, checked in by bastiaans, 19 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
RevLine 
[102]1<?php
[110]2//$GANGLIA_PATH = "/var/www/ganglia";
[102]3
[110]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
[102]12include_once "$GANGLIA_PATH/conf.php";
13include_once "$GANGLIA_PATH/functions.php";
[108]14include_once "$GANGLIA_PATH/ganglia.php";
[102]15
[109]16// Set cluster context so that Ganglia will
17// provide us with the correct metrics array
18//
[108]19global $context;
20$context = 'cluster';
21
22include_once "$GANGLIA_PATH/get_ganglia.php";
23
[109]24// If php is compiled without globals
25//
[103]26if ( !empty( $_GET ) ) {
27        extract( $_GET );
28}
29
[109]30// Ganglia's array of host metrics
31//
[108]32global $metrics;
33
34//print_r($metrics);
35
[103]36class HTTPVariables {
37
38        var $clustername, $metricname;
[110]39        var $restvars;
[103]40
41        function HTTPVariables() {
42
[110]43                $this->restvars = array();
44
[103]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;
[110]49
50                foreach( $HTTP_GET_VARS as $httpvar => $httpval ) {
51                       
52                        if( $httpval ) {
53                                $this->restvars[$httpvar] = $httpval;
54                        }
55                }
[103]56        }
57
58        function getClusterName() {
59                return $this->clustername;
60        }
61
62        function getMetricName() {
63                return $this->metricname;
64        }
[110]65
66        function getHttpVar( $var ) {
67                if( isset( $this->restvars[$var] ) )
68                        return $retval;
69                else
70                        return null;
71        }
[103]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
[106]91                if( !$fp ) {
[103]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
[105]109        var $xmlhandler, $data, $httpvars;
[103]110
111        function DataGatherer() {
112
[110]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
[103]121                $this->parser = xml_parser_create();
[105]122                $this->httpvars = new HTTPVariables();
[103]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
[105]138        function printInfo() {
139                $handler = $this->xmlhandler;
140                $handler->printInfo();
141        }
142
[106]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
[103]153}
154
155class TorqueXMLHandler {
156
[105]157        var $clusters, $heartbeat, $nodes, $jobs;
[104]158
[103]159        function TorqueXMLHandler() {
[105]160                $jobs = array();
[104]161                $clusters = array();
[105]162                $nodes = array();
[104]163                $heartbeat = array();
[103]164        }
165
[110]166        function gotNode( $hostname, $location = 'unspecified', $jobid ) {
[105]167
168                $nodes = &$this->nodes;
169
170                if( !isset( $nodes[$hostname] ) ) {
171
172                        $nodes[$hostname] = new Node( $hostname );
173                }
174
[106]175                if( $location ) {
[105]176
177                        $nodes[$hostname]->setLocation( $location );
178                }
179
180                if( $jobid ) {
181                        $nodes[$hostname]->addJob( $jobid );
[110]182                        //printf("add job %s to node %s", $jobid, $hostname );
[105]183                }
184        }
185
[103]186        function startElement( $parser, $name, $attrs ) {
187
[105]188                $jobs = &$this->jobs;
[111]189                $nodes = &$this->nodes;
[105]190
[103]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
[104]200                // printf( '%s=%s', $attrs[NAME], $attrs[VAL] );
[103]201
[104]202                if( $name == 'CLUSTER' ) {
[103]203
[104]204                        $clustername = $attrs[VAL];
[103]205
[104]206                        if( !isset( $clusters[$clustername] ) )
207                                $clusters[$clustername] = array();
[103]208
[105]209                } else if( $name == 'HOST' ) {
210
211                        $hostname = $attrs[NAME];
212                        $location = $attrs[LOCATION];
213
[111]214                        if( !isset( $this->nodes[$hostname] ) )
215                                $this->nodes[$hostname] = new NodeImage( $hostname );
[105]216
[111]217                        //$this->gotNode( $hostname, $location, null );
218
[104]219                } else if( $name == 'METRIC' and strstr( $attrs[NAME], 'TOGA' ) ) {
[103]220
[104]221                        if( strstr( $attrs[NAME], 'TOGA-HEARTBEAT' ) ) {
[103]222
[104]223                                $heartbeat['time'] = $attrs[VAL];
[106]224                                //printf( "heartbeat %s\n", $heartbeat['time'] );
[104]225
226                        } else if( strstr( $attrs[NAME], 'TOGA-JOB' ) ) {
227
228                                sscanf( $attrs[NAME], 'TOGA-JOB-%d', $jobid );
229
[106]230                                //printf( "jobid %s\n", $jobid );
[104]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
[106]243                                        //printf( "\t%s\t= %s\n", $toganame, $togavalue );
[104]244
[103]245                                        if( $toganame == 'nodes' ) {
246
[106]247                                                if( !isset( $jobs[$jobid][$toganame] ) )
[105]248                                                        $jobs[$jobid][$toganame] = array();
[104]249
[111]250                                                $mynodes = explode( ';', $togavalue );
[103]251
[111]252                                                foreach( $mynodes as $node ) {
[103]253
[111]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 );
[103]264                                                }
265
[104]266                                        } else {
[103]267
[105]268                                                $jobs[$jobid][$toganame] = $togavalue;
[104]269                                        }
[103]270                                }
[111]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                                }
[103]296                        }
297                }
298        }
299
300        function stopElement( $parser, $name ) {
301        }
[105]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        }
[106]339
340        function getNodes() {
341                return $this->nodes;
342        }
343
344        function getJobs() {
345                return $this->jobs;
346        }
[103]347}
348
349class Node {
350
[105]351        var $img, $hostname, $location, $jobs;
[106]352        var $x, $y;
[103]353
[104]354        function Node( $hostname ) {
[103]355
[104]356                $this->hostname = $hostname;
[107]357                //$this->img = new NodeImg();
[105]358                $this->jobs = array();
[103]359        }
[104]360
[105]361        function addJob( $jobid ) {
362                $jobs = &$this->jobs;
363
364                $jobs[] = $jobid;
[110]365                //print_r( $jobs );
366                $this->jobs = $jobs;
[105]367        }
368
[111]369
[104]370        function setLocation( $location ) {
371                $this->location = $location;
372        }
373
[105]374        function setHostname( $hostname ) {
375                $this->hostname = $hostname;
376        }
377
[104]378        function setCpus( $cpus ) {
379                $this->cpus = $cpus;
380        }
[105]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() {
[110]395                //print_r( $this->jobs );
[105]396                return $this->jobs;
397        }
[106]398
[111]399        //function setCoords( $x, $y ) {
400                //$myimg = $this->img;
401                //$myimg->setCoords( $x, $y );
402        //}
[106]403
404        function setImage( $image ) {
405                $myimg = $this->img;
406                $myimg->setImage( &$image );
407        }
408
409        function draw() {
[108]410                global $metrics;
411       
[106]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        }
[103]422}
423
[107]424class NodeImage {
[102]425
[111]426        var $image, $x, $y, $hostname, $jobs, $tasks;
[102]427
[111]428        function NodeImage( $hostname ) {
[102]429
[111]430                $this->jobs = array();
431                //$this->image = $image;
432                //$this->x = $x;
433                //$this->y = $y;
434                $this->tasks = 0;
[110]435                $this->hostname = $hostname;
[111]436                $this->cpus = $this->determineCpus();
[102]437        }
438
[111]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
[106]471        function setCoords( $x, $y ) {
[107]472
[106]473                $this->x = $x;
474                $this->y = $y;
475        }
476
[102]477        function colorHex( $color ) {
478       
[109]479                $my_color = imageColorAllocate( $this->image, hexdec( substr( $color, 0, 2 )), hexdec( substr( $color, 2, 2 )), hexdec( substr( $color, 4, 2 )) );
[102]480
481                return $my_color;
482        }
483
[106]484        function setLoad( $load ) {
485                $this->load = $load;
486        }
487
[108]488        function setHostname( $hostname ) {
489                $this->hostname = $hostname;
490        }
491
[111]492        function draw() {
[106]493
[111]494                global $SMALL_CLUSTERIMAGE_NODEWIDTH, $JOB_NODE_MARKING_ALLCPUS, $JOB_NODE_MARKING_SINGLECPU;
[110]495
[111]496                $this->load = $this->determineLoad();
497
498                if( !isset( $this->x ) or !isset( $this->y ) or !isset( $this->load ) ) {
[107]499                        printf( "aborting\n" );
500                        printf( "x %d y %d load %f\n", $this->x, $this->y, $load );
[106]501                        return;
502                }
503
[111]504                $black_color = imageColorAllocate( $this->image, 0, 0, 0 );
[106]505
[103]506                // Convert Ganglias Hexadecimal load color to a Decimal one
[111]507                //
508                $load = $this->determineLoad(); 
[102]509                $my_loadcolor = $this->colorHex( load_color($load) );
510
[110]511                $size = $SMALL_CLUSTERIMAGE_NODEWIDTH;
[107]512
[110]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
[111]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 );
[102]530        }
531
[111]532        function determineCpus() {
[102]533
[108]534                global $metrics;
535
536                $cpus = $metrics[$this->hostname][cpu_num][VAL];
[107]537                if (!$cpus) $cpus=1;
[111]538
539                return $cpus;
540        }
541
542        function determineLoad() {
543
544                global $metrics;
545
[108]546                $load_one = $metrics[$this->hostname][load_one][VAL];
[111]547                $load = ((float) $load_one)/$this->cpus;
[102]548
[111]549                return $load;
[106]550        }
551}
552
[107]553class ClusterImage {
[106]554
[111]555        var $dataget, $image, $clustername;
[106]556
[111]557        function ClusterImage( $clustername ) {
[106]558                $this->dataget = new DataGatherer();
[111]559                $this->clustername = $clustername;
[106]560        }
561
562        function draw() {
[110]563
564                global $SMALL_CLUSTERIMAGE_MAXWIDTH, $SMALL_CLUSTERIMAGE_NODEWIDTH;
565       
[107]566                $mydatag = $this->dataget;
[106]567                $mydatag->parseXML();
568
[110]569                //$max_width = 250;
570                //$node_width = 11;
[106]571
[110]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
[106]577                $nodes = $mydatag->getNodes();
[111]578                $nodes_hosts = array_keys( $nodes );
[106]579
580                $nodes_nr = count( $nodes );
[111]581                //printf( "%d nodes\n", $nodes_nr );
[106]582
583                $nodes_size = $nodes_nr*$node_width;
584                $node_rows = 0;
585
586                if( $nodes_size > $max_width ) {
[107]587                        $nodes_per_row = ( (int) ($max_width/$node_width) );
[106]588                } else {
589                        $nodes_per_row = $nodes_size;
590                        $node_rows = 1;
591                }
592
593                if( $nodes_per_row < $nodes_nr ) {
[107]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 ) {
[106]598                                $node_rows++;
[107]599                                //printf( "noderows %d\n", $node_rows );
[106]600                        }
601                }
602
[107]603                //printf( "imagecreate: %dx%d", ($nodes_per_row*$node_width), ($node_rows*$node_width) );
[109]604                $image = imageCreateTrueColor( ($nodes_per_row*$node_width)+1, ($node_rows*$node_width)+1 );
[107]605                $colorwhite = imageColorAllocate( $image, 255, 255, 255 );
606                imageFill( $image, 0, 0, $colorwhite );
[106]607
608                for( $n = 0; $n < $node_rows; $n++ ) {
609                       
610                        for( $m = 0; $m < $nodes_per_row; $m++ ) {
[107]611                       
612                                $x = ($m * $node_width);
613                                $y = ($n * $node_width);
614
[109]615                                $cur_node = ($n * $nodes_per_row) + ($m);
[111]616                                $host = $nodes_hosts[$cur_node];
[107]617
[111]618                                if( isset( $nodes[$host] ) ) {
619
620                                        $nodes[$host]->setCoords( $x, $y );
621                                        $nodes[$host]->setImage( $image );
622                                        $nodes[$host]->draw();
623                                }
624                               
625
[109]626                                //printf( "host %s curnode %s ", $host, $cur_node );
627
[111]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();
[110]632
[111]633                        //              $multiproc_job = 0;
[110]634
[111]635                        //              if( count( $nodejobs ) > 0 ) {
636                        //                      $multiproc_job = 1;
[110]637
[111]638                        //                      foreach( $nodejobs as $myjob ){
639                        //                              if( isset($jobs[$myjob]['ppn']) and $jobs[$myjob]['ppn'] > 1 )
640                        //                                      $multiproc_job = 2;
641                        //                                      break;
642                        //                      }
643                        //              }
[110]644
645                                        //printf( "jobs %s node %s", $nrjobs, $host );
[111]646                        //              $node = new NodeImage( $image, $x, $y, $host, $multiproc_job );
[110]647                                        //$node->setHostname( $host );
[111]648                        //              $node->draw();
[107]649                                        //$nodes[$host]->setCoords( $x, $y );
650                                        //$nodes[$host]->setImage( &$image );
651                                        //$nodes[$host]->draw();
652                                        //$cur_node++;
[111]653                        //      }
[106]654                        }
655                }
656               
[103]657                header( 'Content-type: image/png' );
[106]658                imagePNG( $image );
659                imageDestroy( $image );
[102]660        }
661}
662
[106]663//$my_data = new DataGatherer();
664//$my_data->parseXML();
665//$my_data->printInfo();
666
[111]667$ic = new ClusterImage( "LISA Cluster" );
[106]668$ic->draw();
[102]669?>
Note: See TracBrowser for help on using the repository browser.