Changeset 34930 for trunk/ippMonitor
- Timestamp:
- Jan 15, 2013, 1:46:48 PM (14 years ago)
- Location:
- trunk/ippMonitor/czartool
- Files:
-
- 3 edited
-
czarDbSchema.sql (modified) (1 diff)
-
czartool/CzarDb.pm (modified) (52 diffs)
-
czartool/Nebulous.pm (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ippMonitor/czartool/czarDbSchema.sql
r33434 r34930 78 78 `total` float default NULL, 79 79 `available` float default NULL, 80 `usable` float default NULL, 80 81 `used` float default NULL, 81 82 `hostsOver98` smallint(6) default NULL, -
trunk/ippMonitor/czartool/czartool/CzarDb.pm
r34096 r34930 9 9 10 10 my @stages = ( 11 "chip", 12 "cam", 13 "fake", 14 "warp", 15 "stack", 16 "diff", 17 "dist", 11 "chip", 12 "cam", 13 "fake", 14 "warp", 15 "stack", 16 "diff", 17 "dist", 18 18 "pub", 19 19 "chipbackground"); # TODO put elsewhere … … 64 64 SELECT DISTINCT label 65 65 FROM processed 66 WHERE timestamp >= '$begin' 67 AND timestamp <= '$end' 66 WHERE timestamp >= '$begin' 67 AND timestamp <= '$end' 68 68 SQL 69 69 … … 109 109 110 110 SELECT DISTINCT label 111 FROM chip 112 WHERE timestamp >= '$begin' 113 AND timestamp <= '$end' 111 FROM chip 112 WHERE timestamp >= '$begin' 113 AND timestamp <= '$end' 114 114 AND label NOT LIKE '%_ud%' 115 115 AND label NOT LIKE 'update%' … … 153 153 154 154 my $query = $self->{_db}->prepare(<<SQL); 155 SELECT reverting 155 SELECT reverting 156 156 FROM reverts 157 WHERE stage LIKE '$stage'; 157 WHERE stage LIKE '$stage'; 158 158 SQL 159 159 … … 171 171 172 172 my $query = $self->{_db}->prepare(<<SQL); 173 UPDATE reverts 174 SET reverting = $reverting 173 UPDATE reverts 174 SET reverting = $reverting 175 175 WHERE stage LIKE '$stage'; 176 176 SQL … … 188 188 189 189 my $query = $self->{_db}->prepare(<<SQL); 190 UPDATE current_labels 191 SET priority = $priority 192 WHERE label LIKE '$label' 190 UPDATE current_labels 191 SET priority = $priority 192 WHERE label LIKE '$label' 193 193 AND server LIKE 'stdscience'; 194 194 SQL … … 323 323 ########################################################################### 324 324 sub insertNewClusterSpace { 325 my ($self, $total, $available, $us ed, $hostsOver98) = @_;325 my ($self, $total, $available, $usable, $used, $hostsOver98) = @_; 326 326 327 327 my $query = $self->{_db}->prepare(<<SQL); 328 328 INSERT INTO cluster_space 329 (total, available, us ed, hostsOver98)329 (total, available, usable, used, hostsOver98) 330 330 VALUES 331 ( $total, $available, $us ed, $hostsOver98);331 ( $total, $available, $usable, $used, $hostsOver98); 332 332 SQL 333 333 … … 362 362 363 363 my $query = $self->{_db}->prepare(<<SQL); 364 SELECT 365 DATE_FORMAT(MAX(timestamp),'$self->{_dateFormat}'), 364 SELECT 365 DATE_FORMAT(MAX(timestamp),'$self->{_dateFormat}'), 366 366 DATE_FORMAT(MIN(timestamp),'$self->{_dateFormat}'), 367 367 TIME_TO_SEC(TIMEDIFF(max(timestamp ), min(timestamp))) 368 FROM $stage 368 FROM $stage 369 369 WHERE label LIKE '$label' 370 AND timestamp >= '$fromTime' AND timestamp <= '$toTime'; 370 AND timestamp >= '$fromTime' AND timestamp <= '$toTime'; 371 371 SQL 372 372 … … 413 413 ########################################################################### 414 414 # 415 # Analysis this stage between these times 415 # Analysis this stage between these times 416 416 # 417 417 ########################################################################### … … 429 429 430 430 my $query = $self->{_db}->prepare(<<SQL); 431 SELECT 432 timestamp, pending, faults, processed 433 FROM $stage 434 WHERE label LIKE '$label' 435 AND timestamp >= '$fromTime' AND timestamp <= '$toTime' 431 SELECT 432 timestamp, pending, faults, processed 433 FROM $stage 434 WHERE label LIKE '$label' 435 AND timestamp >= '$fromTime' AND timestamp <= '$toTime' 436 436 ORDER BY timestamp; 437 437 SQL … … 452 452 # get linear values 453 453 if($lastProcessed != -1 && $thisProcessed > $lastProcessed) { 454 454 455 455 $totalProcessed = $totalProcessed + ($thisProcessed - $lastProcessed); 456 456 } … … 480 480 my $started = undef; 481 481 my $finished = undef; 482 482 483 483 my ($have25, $have50, $have75, $have90, $have95, $have100) = 0; 484 484 … … 492 492 # get linear values 493 493 if($lastProcessed != -1 && $thisProcessed > $lastProcessed) { 494 494 495 495 $linearProcessed = $linearProcessed + ($thisProcessed - $lastProcessed); 496 496 } … … 508 508 509 509 my $timeDiff = $self->diffTimesInSecs($thisTimestamp, $lastTimestamp) + 0.001; 510 510 511 511 if ($thisProcessed >= $lastProcessed){ 512 $derivProcessed = abs($thisProcessed - $lastProcessed)/$timeDiff; 512 $derivProcessed = abs($thisProcessed - $lastProcessed)/$timeDiff; 513 513 } 514 514 else {$derivProcessed = 0;} 515 $derivPending = abs($thisPending - $lastPending)/$timeDiff; 516 $derivFaults = abs($thisFaults - $lastFaults)/$timeDiff; 515 $derivPending = abs($thisPending - $lastPending)/$timeDiff; 516 $derivFaults = abs($thisFaults - $lastFaults)/$timeDiff; 517 517 } 518 518 else { 519 519 520 520 $derivProcessed = 0; 521 521 $derivPending = 0; … … 539 539 else { 540 540 if (defined $notProcessing) { 541 542 $notProcessing = undef; 543 $stuck = undef; 541 542 $notProcessing = undef; 543 $stuck = undef; 544 544 } 545 545 if (!defined $started) { 546 546 547 547 $started = $lastTimestamp; 548 $finished = undef; 548 $finished = undef; 549 549 } 550 550 } … … 564 564 # how long not processing? 565 565 if (defined $notProcessing) { 566 566 567 567 $howLongNotProcessing = $self->diffTimes($lastTimestamp, $notProcessing); 568 568 $notProcessingLongerThanInterval = $self->isBefore($interval, $howLongNotProcessing); 569 569 } 570 570 else { 571 571 572 572 $howLongNotProcessing = 0; 573 573 $notProcessingLongerThanInterval = 0; … … 611 611 612 612 if (!defined $started){ 613 613 614 614 $stageMetrics->setStarted(undef); 615 615 } 616 616 else { 617 617 618 618 my $rate = ($stageMetrics->getProcessed()/$self->getTimeInSecs($stageMetrics->getTotalTime) ) * 3600.0; 619 619 $stageMetrics->setRate($rate); … … 625 625 } 626 626 else { 627 627 628 628 $stageMetrics->setStuck(undef); 629 629 } … … 642 642 my $query = $self->{_db}->prepare(<<SQL); 643 643 SELECT COUNT(*) 644 FROM $stage 644 FROM $stage 645 645 WHERE label LIKE '$label' 646 AND timestamp >= '$fromTime' AND timestamp <= '$toTime'; 646 AND timestamp >= '$fromTime' AND timestamp <= '$toTime'; 647 647 SQL 648 648 … … 657 657 # grab all the data for the provided time range 658 658 $query = $self->{_db}->prepare(<<SQL); 659 SELECT 660 timestamp, pending, faults, processed 661 FROM $stage 662 WHERE label LIKE '$label' 663 AND timestamp >= '$fromTime' AND timestamp <= '$toTime' 659 SELECT 660 timestamp, pending, faults, processed 661 FROM $stage 662 WHERE label LIKE '$label' 663 AND timestamp >= '$fromTime' AND timestamp <= '$toTime' 664 664 ORDER BY timestamp; 665 665 SQL … … 724 724 $diffFaults = $thisFaults - $lastFaults; 725 725 726 # First, look for large positive jumps in processed, most likely a label 726 # First, look for large positive jumps in processed, most likely a label 727 727 # added, and store value to subtract from linear value below. If > 1000 728 728 # processed per hour, then it must be wrong … … 741 741 } 742 742 else { 743 743 744 744 $diffProcessed = 0; 745 745 $linearProcessed = $linearProcessed; … … 747 747 748 748 # calculate first derivative in units of images per hour 749 $derivPending = $diffPending/($timeSep/3600); 750 $derivFaults = $diffFaults/($timeSep/3600); 751 $derivProcessed = $diffProcessed/($timeSep/3600); 749 $derivPending = $diffPending/($timeSep/3600); 750 $derivFaults = $diffFaults/($timeSep/3600); 751 $derivProcessed = $diffProcessed/($timeSep/3600); 752 752 753 753 } 754 754 # first time in 755 755 else { 756 756 757 757 $derivPending = 0; 758 758 $derivFaults = 0; … … 777 777 my $totalPending = 0; 778 778 my $totalFaults = 0; 779 for (my $i=$size-1; $i>=($size - $range); $i--) { 780 779 for (my $i=$size-1; $i>=($size - $range); $i--) { 780 781 781 $totalPending = $totalPending + $ratePending[$i]; 782 782 $totalFaults = $totalFaults + $rateFaults[$i]; … … 833 833 # get earliest time for this label 834 834 my $query = $self->{_db}->prepare(<<SQL); 835 SELECT GREATEST(MIN(timestamp), now() - INTERVAL $interval) 835 SELECT GREATEST(MIN(timestamp), now() - INTERVAL $interval) 836 836 FROM $stage 837 WHERE label LIKE '$label'; 838 SQL 839 $query->execute; 840 841 my $timestamp = $query->fetchrow_array(); 837 WHERE label LIKE '$label'; 838 SQL 839 $query->execute; 840 841 my $timestamp = $query->fetchrow_array(); 842 842 843 843 $query = $self->{_db}->prepare(<<SQL); 844 SELECT faults 844 SELECT faults 845 845 FROM $stage 846 WHERE label LIKE '$label' 846 WHERE label LIKE '$label' 847 847 AND timestamp <= '$timestamp' LIMIT 1; 848 848 SQL … … 861 861 862 862 my $query = $self->{_db}->prepare(<<SQL); 863 SELECT pending - faults 864 FROM $stage 865 WHERE label LIKE '$label' 863 SELECT pending - faults 864 FROM $stage 865 WHERE label LIKE '$label' 866 866 ORDER BY timestamp DESC LIMIT 1; 867 867 SQL … … 880 880 881 881 my $query = $self->{_db}->prepare(<<SQL); 882 SELECT 883 pending, faults 882 SELECT 883 pending, faults 884 884 FROM $stage 885 885 WHERE label LIKE '$label' … … 890 890 if (!$query->execute) {return 0;} 891 891 892 (${$pending}, ${$faults}) = $query->fetchrow_array(); 892 (${$pending}, ${$faults}) = $query->fetchrow_array(); 893 893 894 894 ${$processed} = $self->countProcessed($label, $stage, $fromTime, $toTime); … … 912 912 913 913 my $query = $self->{_db}->prepare(<<SQL); 914 SELECT 915 host, used, available, writable, readable 914 SELECT 915 host, used, available, writable, readable 916 916 FROM hosts 917 917 ORDER BY host; … … 926 926 927 927 my ($host, $used, $available, $writable, $readable) = @row; 928 929 if (($used+$available) == 0) {930 $underLimit = 1;931 } elsif (($used/($used+$available))*100 > $limit) {932 $underLimit = 0;933 } else {934 $underLimit = 1;935 }928 929 if (($used+$available) == 0) { 930 $underLimit = 1; 931 } elsif (($used/($used+$available))*100 > $limit) { 932 $underLimit = 0; 933 } else { 934 $underLimit = 1; 935 } 936 936 937 937 # Col 1: host 938 938 print GNUDAT "$host"; 939 939 940 940 # Col 2: available, readable used space under limit 941 941 if ($readable && $underLimit) {print GNUDAT " $used";} … … 973 973 974 974 my $query = $self->{_db}->prepare(<<SQL); 975 SELECT used/total*100 976 FROM cluster_space 975 SELECT used/total*100 976 FROM cluster_space 977 977 ORDER BY timestamp DESC LIMIT 1; 978 978 SQL … … 983 983 ########################################################################### 984 984 # 985 # Gets time series data for cluster storage and saves it to file 985 # Gets time series data for cluster storage and saves it to file 986 986 # 987 987 ########################################################################### … … 992 992 993 993 my $query = $self->{_db}->prepare(<<SQL); 994 SELECT 995 MAX(available), MIN(available), 996 DATE_FORMAT(MAX(timestamp),'$self->{_dateFormat}'), 994 SELECT 995 MAX(available), MIN(available), 996 DATE_FORMAT(MAX(timestamp),'$self->{_dateFormat}'), 997 997 DATE_FORMAT(MIN(timestamp),'$self->{_dateFormat}'), 998 998 TIME_TO_SEC(TIMEDIFF(max(timestamp ), min(timestamp))) 999 FROM cluster_space 1000 WHERE timestamp >= '$fromTime' AND timestamp <= '$toTime'; 999 FROM cluster_space 1000 WHERE timestamp >= '$fromTime' AND timestamp <= '$toTime'; 1001 1001 SQL 1002 1002 … … 1009 1009 1010 1010 $query = $self->{_db}->prepare(<<SQL); 1011 SELECT 1012 DATE_FORMAT(timestamp, '$self->{_dateFormat}'), available 1013 FROM cluster_space 1014 WHERE timestamp >= '$fromTime' AND timestamp <= '$toTime' 1011 SELECT 1012 DATE_FORMAT(timestamp, '$self->{_dateFormat}'), available 1013 FROM cluster_space 1014 WHERE timestamp >= '$fromTime' AND timestamp <= '$toTime' 1015 1015 ORDER BY timestamp; 1016 1016 SQL … … 1074 1074 ########################################################################### 1075 1075 # 1076 # Gets count of processed stuff in a given time period 1076 # Gets count of processed stuff in a given time period 1077 1077 # 1078 1078 ########################################################################### … … 1081 1081 1082 1082 my $query = $self->{_db}->prepare(<<SQL); 1083 SELECT 1084 processed 1083 SELECT 1084 processed 1085 1085 FROM $stage 1086 WHERE label LIKE '$label' 1087 AND timestamp >= '$begin' 1088 AND timestamp < '$end' 1086 WHERE label LIKE '$label' 1087 AND timestamp >= '$begin' 1088 AND timestamp < '$end' 1089 1089 SQL 1090 1090 $query->execute; … … 1168 1168 1169 1169 $query = $self->{_db}->prepare(<<SQL); 1170 SELECT COUNT(*) 1171 FROM $stage 1170 SELECT COUNT(*) 1171 FROM $stage 1172 1172 WHERE timestamp > '$fromTime' 1173 1173 AND timestamp <= '$toTime' 1174 AND label = '$label' 1174 AND label = '$label' 1175 1175 SQL 1176 1176 … … 1181 1181 1182 1182 $query = $self->{_db}->prepare(<<SQL); 1183 DELETE FROM $stage 1184 WHERE timestamp > '$fromTime' 1185 AND timestamp <= '$toTime' 1183 DELETE FROM $stage 1184 WHERE timestamp > '$fromTime' 1185 AND timestamp <= '$toTime' 1186 1186 AND label = '$label' ORDER BY timestamp DESC LIMIT $toDelete 1187 1187 SQL … … 1203 1203 1204 1204 $query = $self->{_db}->prepare(<<SQL); 1205 SELECT COUNT(*) 1206 FROM servers 1205 SELECT COUNT(*) 1206 FROM servers 1207 1207 WHERE timestamp > '$fromTime' 1208 1208 AND timestamp <= '$toTime' 1209 AND server = '$server' 1209 AND server = '$server' 1210 1210 SQL 1211 1211 $query->execute; … … 1215 1215 1216 1216 $query = $self->{_db}->prepare(<<SQL); 1217 DELETE FROM servers 1218 WHERE timestamp > '$fromTime' 1219 AND timestamp <= '$toTime' 1217 DELETE FROM servers 1218 WHERE timestamp > '$fromTime' 1219 AND timestamp <= '$toTime' 1220 1220 AND server = '$server' ORDER BY timestamp DESC LIMIT $toDelete 1221 1221 SQL … … 1229 1229 # now deal with cluster_space table 1230 1230 $query = $self->{_db}->prepare(<<SQL); 1231 SELECT COUNT(*) 1232 FROM cluster_space 1231 SELECT COUNT(*) 1232 FROM cluster_space 1233 1233 WHERE timestamp > '$fromTime' 1234 1234 AND timestamp <= '$toTime' … … 1240 1240 1241 1241 $query = $self->{_db}->prepare(<<SQL); 1242 DELETE FROM cluster_space 1243 WHERE timestamp > '$fromTime' 1244 AND timestamp <= '$toTime' 1242 DELETE FROM cluster_space 1243 WHERE timestamp > '$fromTime' 1244 AND timestamp <= '$toTime' 1245 1245 ORDER BY timestamp DESC LIMIT $toDelete 1246 1246 SQL … … 1257 1257 ########################################################################### 1258 1258 # 1259 # Optimizes all tables that need to be optimized 1259 # Optimizes all tables that need to be optimized 1260 1260 # 1261 1261 ########################################################################### … … 1275 1275 ########################################################################### 1276 1276 # 1277 # Returns if a particular server has been stopped for a certain interval 1277 # Returns if a particular server has been stopped for a certain interval 1278 1278 # 1279 1279 ########################################################################### … … 1286 1286 ########################################################################### 1287 1287 # 1288 # Returns if a particular server has been down for a certain interval 1288 # Returns if a particular server has been down for a certain interval 1289 1289 # 1290 1290 ########################################################################### … … 1297 1297 ########################################################################### 1298 1298 # 1299 # Returns if a particular server has been down for a certain interval 1299 # Returns if a particular server has been down for a certain interval 1300 1300 # 1301 1301 ########################################################################### … … 1304 1304 1305 1305 my $query = $self->{_db}->prepare(<<SQL); 1306 SELECT COUNT(*) 1306 SELECT COUNT(*) 1307 1307 FROM servers 1308 WHERE server = '$server' 1308 WHERE server = '$server' 1309 1309 AND timestamp > now() - INTERVAL $interval 1310 1310 SQL … … 1316 1316 1317 1317 $query = $self->{_db}->prepare(<<SQL); 1318 SELECT COUNT(*) 1318 SELECT COUNT(*) 1319 1319 FROM servers 1320 WHERE server = '$server' 1320 WHERE server = '$server' 1321 1321 AND timestamp > now() - INTERVAL $interval 1322 1322 AND !$mode … … 1329 1329 1330 1330 $query = $self->{_db}->prepare(<<SQL); 1331 SELECT 1331 SELECT 1332 1332 timestamp 1333 1333 FROM servers 1334 1334 WHERE server = '$server' 1335 AND $mode 1336 ORDER BY timestamp DESC 1335 AND $mode 1336 ORDER BY timestamp DESC 1337 1337 LIMIT 1 1338 1338 … … 1346 1346 ########################################################################### 1347 1347 # 1348 # Returns an array of servers 1348 # Returns an array of servers 1349 1349 # 1350 1350 ########################################################################### … … 1369 1369 ########################################################################### 1370 1370 # 1371 # Returns an array of labels present during the provided time frame 1371 # Returns an array of labels present during the provided time frame 1372 1372 # 1373 1373 ########################################################################### … … 1376 1376 1377 1377 my $query = $self->{_db}->prepare(<<SQL); 1378 SELECT DISTINCT label 1379 FROM $stage 1380 WHERE timestamp > '$fromTime' 1378 SELECT DISTINCT label 1379 FROM $stage 1380 WHERE timestamp > '$fromTime' 1381 1381 AND timestamp <= '$toTime'; 1382 1382 SQL -
trunk/ippMonitor/czartool/czartool/Nebulous.pm
r34096 r34930 28 28 ########################################################################### 29 29 # 30 # Converts Kb to Tb 31 # 30 # Converts Kb to Tb 31 # 32 32 ########################################################################### 33 33 sub convertKbToTb { … … 50 50 ########################################################################### 51 51 # 52 # Returns total cluster usage in T 52 # Returns total cluster usage in T 53 53 # 54 54 ########################################################################### … … 61 61 ########################################################################### 62 62 # 63 # Returns total cluster space in T 63 # Returns total cluster space in T 64 64 # 65 65 ########################################################################### … … 72 72 ########################################################################### 73 73 # 74 # Returns total cluster available in T 74 # Returns total cluster available in T 75 75 # 76 76 ########################################################################### … … 83 83 ########################################################################### 84 84 # 85 # Runs neb-df and puts output in gnuplot ready format 85 # Runs neb-df and puts output in gnuplot ready format 86 86 # 87 87 ########################################################################### … … 93 93 $self->{_totalHosts} = 0; 94 94 $self->{_hostsOverNinetyEightPC} = 0; 95 $self->{_totalUsable} = 0; 95 96 my $readable; 96 97 my $writable; … … 100 101 if ($line =~ m/.*Filesystem.*/i) {next;} 101 102 elsif ($line =~ m/.*summmary.*/i) {next;} 102 elsif ($line =~ m/.*total.*/i) {next;} 103 elsif ($line =~ m/\s+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+.*allocated.*/i) { 103 elsif ($line =~ m/\s+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+.*total.*/i) { 104 $self->{_totalUsable} += $self->convertKbToTb($2); 105 } elsif ($line =~ m/\s+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+.*allocated.*/i) { 104 106 105 107 $self->{_totalUsed} = $self->convertKbToTb($1); … … 109 111 110 112 next; 111 } 112 elsif (($line =~ m/(ipp[0-9]+\.[0-9]{1})\s.+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)%.*/i)|| 113 ($line =~ m/(ippb[0-9]+\.[0-9]{1})\s.+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)%.*/i) || 114 ($line =~ m/(stsci0[0-9]+\.[0-9]{1})\s.+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)%.*/i)) { 115 113 } elsif (($line =~ m/(ipp[0-9]+\.[0-9]{1})\s.+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)%.*/i)|| 114 ($line =~ m/(ippb[0-9]+\.[0-9]{1})\s.+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)%.*/i) || 115 ($line =~ m/(stsci0[0-9]+\.[0-9]{1})\s.+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)%.*/i)) { 116 116 117 $self->{_totalHosts}++; 117 118 if ($4 >= 98) {$self->{_hostsOverNinetyEightPC}++;} … … 119 120 $self->getReadableWritableStatus($1, \$readable, \$writable); 120 121 121 $self->{_czarDb}->updateHost($1, 122 $self->convertKbToTb($2+$3), 123 $self->convertKbToTb($3), 124 $self->convertKbToTb($2), 122 $self->{_czarDb}->updateHost($1, 123 $self->convertKbToTb($2+$3), 124 $self->convertKbToTb($3), 125 $self->convertKbToTb($2), 125 126 $readable, $writable); 126 127 } … … 128 129 129 130 $self->{_czarDb}->insertNewClusterSpace( 130 $self->{_totalCluster}, 131 $self->{_totalAvail}, 132 $self->{_totalUsed}, 131 $self->{_totalCluster}, 132 $self->{_totalAvail}, 133 $self->{_totalUsable}, 134 $self->{_totalUsed}, 133 135 $self->{_hostsOverNinetyEightPC}); 134 136 } … … 136 138 ########################################################################### 137 139 # 138 # Runs neb-host and readable/writable status for this host 140 # Runs neb-host and readable/writable status for this host 139 141 # 140 142 ###########################################################################
Note:
See TracChangeset
for help on using the changeset viewer.
