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

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

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

  • Cosmetic HTML change

web/addons/toga/index.php:

  • Added Joblist filter tree text

web/addons/toga/overview.php:

  • Setup clusterimage filter

web/addons/toga/image.php:

  • Added filter handling

web/addons/toga/libtoga.php:

File size: 12.8 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 getJobs() {
159                $handler = $this->xmlhandler;
160                return $handler->getJobs();
161        }
162
163        function getHeartbeat() {
164                $handler = $this->xmlhandler;
165                return $handler->getHeartbeat();
166        }
167}
168
169class TorqueXMLHandler {
170
171        var $clusters, $heartbeat, $nodes, $jobs;
172
173        function TorqueXMLHandler() {
174                $jobs = array();
175                $clusters = array();
176                $nodes = array();
177                $heartbeat = array();
178        }
179
180        function startElement( $parser, $name, $attrs ) {
181
182                $jobs = &$this->jobs;
183                $nodes = &$this->nodes;
184
185                if ( $attrs[TN] ) {
186
187                        // Ignore dead metrics. Detect and mask failures.
188                        if ( $attrs[TN] > $attrs[TMAX] * 4 )
189                                return;
190                }
191
192                $jobid = null;
193
194                // printf( '%s=%s', $attrs[NAME], $attrs[VAL] );
195
196                if( $name == 'CLUSTER' ) {
197
198                        $clustername = $attrs[VAL];
199
200                        if( !isset( $clusters[$clustername] ) )
201                                $clusters[$clustername] = array();
202
203                } else if( $name == 'HOST' ) {
204
205                        $hostname = $attrs[NAME];
206                        $location = $attrs[LOCATION];
207
208                        if( !isset( $this->nodes[$hostname] ) )
209                                $this->nodes[$hostname] = new NodeImage( $hostname );
210
211                } else if( $name == 'METRIC' and strstr( $attrs[NAME], 'TOGA' ) ) {
212
213                        if( strstr( $attrs[NAME], 'TOGA-HEARTBEAT' ) ) {
214
215                                $this->heartbeat['time'] = $attrs[VAL];
216                                //printf( "heartbeat %s\n", $heartbeat['time'] );
217
218                        } else if( strstr( $attrs[NAME], 'TOGA-JOB' ) ) {
219
220                                sscanf( $attrs[NAME], 'TOGA-JOB-%d', $jobid );
221
222                                //printf( "jobid %s\n", $jobid );
223
224                                if( !isset( $jobs[$jobid] ) )
225                                        $jobs[$jobid] = array();
226
227                                $fields = explode( ' ', $attrs[VAL] );
228
229                                foreach( $fields as $f ) {
230                                        $togavalues = explode( '=', $f );
231
232                                        $toganame = $togavalues[0];
233                                        $togavalue = $togavalues[1];
234
235                                        //printf( "\t%s\t= %s\n", $toganame, $togavalue );
236
237                                        if( $toganame == 'nodes' ) {
238
239                                                if( !isset( $jobs[$jobid][$toganame] ) )
240                                                        $jobs[$jobid][$toganame] = array();
241
242                                                $mynodes = explode( ';', $togavalue );
243
244                                                foreach( $mynodes as $node )
245
246                                                        $jobs[$jobid][$toganame][] = $node;
247                                        } else {
248
249                                                $jobs[$jobid][$toganame] = $togavalue;
250                                        }
251                                }
252
253                                if( isset( $jobs[$jobid][domain] ) and isset( $jobs[$jobid][nodes] ) ) {
254                       
255                                        $nr_nodes = count( $jobs[$jobid][nodes] );
256                       
257                                        foreach( $jobs[$jobid][nodes] as $node ) {
258
259                                                $host = $node.'.'.$jobs[$jobid][domain];
260                               
261                                                if( !isset( $this->nodes[$host] ) )
262                                                        $my_node = new NodeImage( $host );
263                                                else
264                                                        $my_node = $this->nodes[$host];
265
266                                                if( !$my_node->hasJob( $jobid ) )
267
268                                                        if( isset( $jobs[$jobid][ppn] ) )
269                                                                $my_node->addJob( $jobid, ((int) $jobs[$jobid][ppn]) );
270                                                        else
271                                                                $my_node->addJob( $jobid, 1 );
272
273                                                $this->nodes[$host] = $my_node;
274                                        }
275                                }
276                        }
277                }
278                $this->jobs = $jobs;
279        }
280
281        function stopElement( $parser, $name ) {
282        }
283
284        function printInfo() {
285
286                $jobs = &$this->jobs;
287
288                printf( "---jobs---\n" );
289
290                foreach( $jobs as $jobid => $job ) {
291
292                        printf( "job %s\n", $jobid );
293
294                        if( isset( $job[nodes] ) ) {
295
296                                foreach( $job[nodes] as $node ) {
297
298                                        $mynode = $this->nodes[$node];
299                                        $hostname = $mynode->getHostname();
300                                        $location = $mynode->getLocation();
301
302                                        printf( "\t- node %s\tlocation %s\n", $hostname, $location );
303                                        //$this->nodes[$hostname]->setLocation( "hier draait job ".$jobid );
304                                }
305                        }
306                }
307
308                printf( "---nodes---\n" );
309
310                $nodes = &$this->nodes;
311
312                foreach( $nodes as $node ) {
313
314                        $hostname = $node->getHostname();
315                        $location = $node->getLocation();
316                        $jobs = implode( ' ', $node->getJobs() );
317                        printf( "* node %s\tlocation %s\tjobs %s\n", $hostname, $location, $jobs );
318                }
319        }
320
321        function getNodes() {
322                return $this->nodes;
323        }
324
325        function getJobs() {
326                return $this->jobs;
327        }
328
329        function getHeartbeat() {
330                return $this->heartbeat['time'];
331        }
332}
333
334class NodeImage {
335
336        var $image, $x, $y, $hostname, $jobs, $tasks, $showinfo;
337
338        function NodeImage( $hostname ) {
339
340                $this->jobs = array();
341                //$this->image = $image;
342                //$this->x = $x;
343                //$this->y = $y;
344                $this->tasks = 0;
345                $this->hostname = $hostname;
346                $this->cpus = $this->determineCpus();
347                $this->showinfo = 1;
348        }
349
350        function addJob( $jobid, $cpus ) {
351                $jobs = &$this->jobs;
352
353                $jobs[] = $jobid;
354                $this->jobs = $jobs;
355
356                $this->addTask( $cpus );
357        }
358
359        function hasJob( $jobid ) {
360
361                $jobfound = 0;
362
363                if( count( $this->jobs ) > 0 )
364                        foreach( $this->jobs as $job )
365
366                                if( $job == $jobid )
367                                        $jobfound = 1;
368
369                return $jobfound;
370        }
371
372        function addTask( $cpus ) {
373
374                $this->tasks = $this->tasks + $cpus;
375        }
376
377        function setImage( $image ) {
378
379                $this->image = $image;
380        }
381
382        function setCoords( $x, $y ) {
383
384                $this->x = $x;
385                $this->y = $y;
386        }
387
388        function colorHex( $color ) {
389       
390                $my_color = imageColorAllocate( $this->image, hexdec( substr( $color, 0, 2 )), hexdec( substr( $color, 2, 2 )), hexdec( substr( $color, 4, 2 )) );
391
392                return $my_color;
393        }
394
395        function setLoad( $load ) {
396                $this->load = $load;
397        }
398
399        function setHostname( $hostname ) {
400                $this->hostname = $hostname;
401        }
402
403        function getHostname() {
404                return $this->hostname;
405        }
406
407        function getJobs() {
408                return $this->jobs;
409        }
410
411        function setShowinfo( $showinfo ) {
412                $this->showinfo = $showinfo;
413        }
414
415        function draw() {
416
417                $this->drawSmall();
418        }
419
420        function drawBig() {
421
422        }
423
424        function drawSmall() {
425
426                global $SMALL_CLUSTERIMAGE_NODEWIDTH;
427                global $JOB_NODE_MARKING;
428
429                $black_color = imageColorAllocate( $this->image, 0, 0, 0 );
430                $size = $SMALL_CLUSTERIMAGE_NODEWIDTH;
431
432                imageFilledRectangle( $this->image, $this->x, $this->y, $this->x+($size), $this->y+($size), $black_color );
433
434                if( $this->showinfo) {
435               
436                        $this->load = $this->determineLoad();
437
438                        if( !isset( $this->image ) or !isset( $this->x ) or !isset( $this->y ) ) {
439                                printf( "aborting\n" );
440                                printf( "x %d y %d load %f\n", $this->x, $this->y, $load );
441                                return;
442                        }
443
444
445                        // Convert Ganglias Hexadecimal load color to a Decimal one
446                        //
447                        $load = $this->determineLoad(); 
448                        $usecolor = $this->colorHex( load_color($load) );
449                        imageFilledRectangle( $this->image, $this->x+1, $this->y+1, $this->x+($size-1), $this->y+($size-1), $usecolor );
450                        if( count( $this->jobs ) > 0 )
451                                imageString( $this->image, 1, $this->x+(($size/2)-2), $this->y+(($size/2)-3), $JOB_NODE_MARKING, $black_color );
452
453                } else {
454
455                        // White
456                        $usecolor = imageColorAllocate( $this->image, 255, 255, 255 );
457                        imageFilledRectangle( $this->image, $this->x+1, $this->y+1, $this->x+($size-1), $this->y+($size-1), $usecolor );
458                }
459
460
461        }
462
463        function determineCpus() {
464
465                global $metrics;
466
467                $cpus = $metrics[$this->hostname][cpu_num][VAL];
468                if (!$cpus) $cpus=1;
469
470                return $cpus;
471        }
472
473        function determineLoad() {
474
475                global $metrics;
476
477                $load_one = $metrics[$this->hostname][load_one][VAL];
478                $load = ((float) $load_one)/$this->cpus;
479
480                return $load;
481        }
482}
483
484class ClusterImage {
485
486        var $dataget, $image, $clustername;
487        var $filtername, $filtervalue;
488
489        function ClusterImage( $clustername ) {
490
491                $this->dataget = new DataGatherer();
492                $this->clustername = $clustername;
493                $this->filtername = null;
494                $this->filtervalue = null;
495        }
496
497        function setFilter( $filtername, $filtervalue ) {
498
499                //printf( "filter set to %s = %s\n", $filtername, $filtervalue );
500                $this->filtername = $filtername;
501                $this->filtervalue = $filtervalue;
502        }
503
504        function filterNodes( $jobs, $nodes ) {
505
506                $filtered_nodes = array();
507
508                foreach( $nodes as $node ) {
509
510                        $mynjobs = $node->getJobs();
511                        $hostname = $node->getHostname();
512
513                        if( $this->filtername ) {
514                                foreach( $mynjobs as $myjob )
515
516                                        if( $this->filtername == 'jobid' && $node->hasJob( $this->filtervalue) )
517                                                $filtered_nodes[] = $hostname;
518                                        else if( $jobs[$myjob][$this->filtername] == $this->filtervalue  && !in_array( $hostname, $filtered_nodes  ) )
519                                                $filtered_nodes[] = $hostname;
520                        } else
521                                $filtered_nodes[] = $hostname;
522                }
523
524                return $filtered_nodes;
525        }
526
527        function draw() {
528
529                global $SMALL_CLUSTERIMAGE_MAXWIDTH, $SMALL_CLUSTERIMAGE_NODEWIDTH;
530       
531                $mydatag = $this->dataget;
532                $mydatag->parseXML();
533
534                //$max_width = 250;
535                //$node_width = 11;
536
537                $max_width = $SMALL_CLUSTERIMAGE_MAXWIDTH;
538                $node_width = $SMALL_CLUSTERIMAGE_NODEWIDTH;
539
540                //printf( "cmaxw %s nmaxw %s", $SMALL_CLUSTERIMAGE_MAXWIDTH, $SMALL_CLUSTERIMAGE_NODEWIDTH );
541
542                $nodes = $mydatag->getNodes();
543                $nodes_hosts = array_keys( $nodes );
544
545                $nodes_nr = count( $nodes );
546
547                $nodes_size = $nodes_nr*$node_width;
548                $node_rows = 0;
549
550                if( $nodes_size > $max_width ) {
551                        $nodes_per_row = ( (int) ($max_width/$node_width) );
552                } else {
553                        $nodes_per_row = $nodes_size;
554                        $node_rows = 1;
555                }
556
557                if( $nodes_per_row < $nodes_nr ) {
558                        $node_rows = ( (int) ($nodes_nr/$nodes_per_row) );
559                        $node_rest = fmod( $nodes_nr, $nodes_per_row );
560                        //printf( "nodesnr %d noderest %f\n", $nodes_nr, $node_rest );
561                        if( $node_rest > 0 ) {
562                                $node_rows++;
563                                //printf( "noderows %d\n", $node_rows );
564                        }
565                }
566
567                //printf( "imagecreate: %dx%d", ($nodes_per_row*$node_width), ($node_rows*$node_width) );
568                $image = imageCreateTrueColor( ($nodes_per_row*$node_width)+1, ($node_rows*$node_width)+1 );
569                $colorwhite = imageColorAllocate( $image, 255, 255, 255 );
570                imageFill( $image, 0, 0, $colorwhite );
571
572                $jobs = $mydatag->getJobs();
573                //printf("filtername = %s\n", $filtername );
574                $filtered_nodes = $this->filterNodes( $jobs, $nodes );
575
576                //print_r($filtered_nodes);
577
578                for( $n = 0; $n < $node_rows; $n++ ) {
579                       
580                        for( $m = 0; $m < $nodes_per_row; $m++ ) {
581                       
582                                $x = ($m * $node_width);
583                                $y = ($n * $node_width);
584
585                                $cur_node = ($n * $nodes_per_row) + ($m);
586                                $host = $nodes_hosts[$cur_node];
587
588
589                                if( isset( $nodes[$host] ) ) {
590
591                                        $nodes[$host]->setCoords( $x, $y );
592                                        $nodes[$host]->setImage( $image );
593
594                                        if( !in_array( $host, $filtered_nodes ) )
595                                                $nodes[$host]->setShowinfo( 0 );
596
597                                        $nodes[$host]->draw();
598                                }
599                        }
600                }
601               
602                header( 'Content-type: image/png' );
603                imagePNG( $image );
604                imageDestroy( $image );
605        }
606}
607
608//$my_data = new DataGatherer();
609//$my_data->parseXML();
610//$my_data->printInfo();
611
612//$ic = new ClusterImage( "LISA Cluster" );
613//$ic->draw();
614?>
Note: See TracBrowser for help on using the repository browser.