/usr/bin/watch-mimedefang is in mimedefang 2.83-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 | #!/bin/sh
# -*-Mode: TCL;-*-
# Next line restarts using wish \
exec wish "$0" -- "$@" ; clear; echo "*****"; echo "Cannot find 'wish' -- you need Tcl/Tk installed to run this program"; exit 1
# Update interval in milliseconds
set UpdateInterval 500
# Message list
set MsgList {}
set Title ""
# Graph margins
set Margin(left) 60
set Margin(right) 15
set Margin(top) 15
set Margin(bottom) 15
# Which plots to show
set Show(0) 1
set Show(1) 1
set Show(5) 1
set Show(10) 1
# Last time we did MSGS
set MSGS -1
# File descriptor for md-mx-ctrl
set CtrlFD 0
# Default md-mx-ctrl command
set MD_MX_CTRL "md-mx-ctrl"
set AfterResult 0
### Built-in graphing library
global GraphData
set GraphData(_attributes) {
width height xmin ymin xmax ymax origin_x origin_y xticks yticks
}
set GraphData(_data_attributes) {
color width
}
## translated from C-code in Blt, who got it from:
## Taken from Paul Heckbert's "Nice Numbers for Graph Labels" in
## Graphics Gems (pp 61-63). Finds a "nice" number approximately
## equal to x.
proc nicenum {x floor} {
if {$x == 0} {
return 0
}
set negative 0
if {$x < 0} {
set x [expr -$x]
set negative 1
}
set exponX [expr floor(log10($x))]
set fractX [expr $x/pow(10,$exponX)]; # between 1 and 10
if {$floor} {
if {$fractX < 2.0} {
set nf 1.0
} elseif {$fractX < 5.0} {
set nf 2.0
} elseif {$fractX < 10.0} {
set nf 5.0
} else {
set nf 10.0
}
} elseif {$fractX <= 1.0} {
set nf 1.0
} elseif {$fractX <= 2.0} {
set nf 2.0
} elseif {$fractX <= 5.0} {
set nf 5.0
} else {
set nf 10.0
}
if { $negative } {
return [expr -$nf * pow(10,$exponX)]
} else {
set value [expr $nf * pow(10,$exponX)]
return $value
}
}
proc graph_create { name } {
graph_configure $name width 300
graph_configure $name height 120
graph_configure $name sxmin auto
graph_configure $name symin auto
graph_configure $name sxmax auto
graph_configure $name symax auto
graph_configure $name origin_x 0
graph_configure $name origin_y 0
graph_configure $name xticks 10
graph_configure $name yticks 10
graph_configure $name gridcolor "#C0C0C0"
graph_configure $name gridwidth 1
}
proc graph_configure { name attribute value } {
global GraphData
set GraphData(g$name,$attribute) $value
}
proc graph_cget { name {attribute ""} } {
global GraphData
if {"$attribute" == ""} {
graph_cget_all $name
} else {
if { [info exists GraphData(g$name,$attribute)] } {
return $GraphData(g$name,$attribute)
} else {
return ""
}
}
}
proc graph_cget_all { name } {
global GraphData
set keys [array names GraphData "g$name*"]
set ans {}
foreach thing $keys {
set stuff [split $thing ,]
if { [lindex $stuff 1] == "data" } {
continue
}
lappend ans [lindex $stuff 1]
lappend ans $GraphData($thing)
}
return $ans
}
proc graph_add_data { name tag points } {
graph_configure_data $name $tag points $points
}
proc graph_get_points { name tag } {
graph_cget_data $name $tag points
}
proc graph_next_auto_x { name tag } {
set x [graph_cget_data $name $tag auto_x]
if {"$x" == ""} {
set x 0
} else {
incr x
}
graph_configure_data $name $tag auto_x $x
return $x
}
proc graph_add_point { name tag x y } {
global GraphData
if { "$x" == "auto" } {
set x [graph_next_auto_x $name $tag]
}
lappend GraphData(g$name,data,$tag,points) $x $y
if {[graph_cget $name sxmax] == "timeseries"} {
graph_keep_lastn $name $tag [graph_cget $name width]
}
}
proc graph_keep_lastn { name tag n } {
global GraphData
set l [llength $GraphData(g$name,data,$tag,points)]
if {$l > $n * 2} {
set toChop [expr $l - $n * 2]
set GraphData(g$name,data,$tag,points) [lrange $GraphData(g$name,data,$tag,points) $toChop end]
}
}
proc graph_configure_data { name tag attribute value } {
graph_configure $name "data,$tag,$attribute" $value
}
proc graph_cget_data { name tag attribute } {
graph_cget $name "data,$tag,$attribute"
}
proc graph_get_data_tags { name } {
global GraphData
set keys [array names GraphData "g$name,data,*,points"]
set ans {}
foreach thing $keys {
set stuff [split $thing ,]
set tag [lindex $stuff 2]
if { ! [info exists done($tag)] } {
set done($tag) 1
lappend ans $tag
}
}
return $ans
}
proc _graph_set_scale { name } {
set tags [graph_get_data_tags $name]
set sxmin [graph_cget $name sxmin]
set sxmax [graph_cget $name sxmax]
set symin [graph_cget $name symin]
set symax [graph_cget $name symax]
set xmin 1e60
set ymin 1e60
set xmax -1e60
set ymax -1e60
foreach tag $tags {
set points [graph_cget_data $name $tag points]
foreach {x y} $points {
if { $x < $xmin } { set xmin $x }
if { $y < $ymin } { set ymin $y }
if { $x > $xmax } { set xmax $x }
if { $y > $ymax } { set ymax $y }
}
}
set nxmin [nicenum $xmin 1]
set nxmax [nicenum $xmax 0]
set nymin [nicenum $ymin 1]
set nymax [nicenum $ymax 0]
set width [graph_cget $name width]
if { $xmin == $xmax } {
set nxmin [expr $xmin - 0.1]
set nxmax [expr $xmin + 0.1]
}
if { $ymin == $ymax } {
set nymin [expr $ymin - 0.1]
set nymax [expr $ymin + 0.1]
}
if { "$sxmin" == "auto" } {
graph_configure $name xmin $nxmin
} elseif { "$sxmin" == "timeseries" } {
graph_configure $name xmin $xmin
} else {
graph_configure $name xmin $sxmin
}
if { "$symin" == "auto" } {
graph_configure $name ymin $nymin
} else {
graph_configure $name ymin $symin
}
if { "$sxmax" == "auto" } {
graph_configure $name xmax $nxmax
} elseif { "$sxmin" == "timeseries" } {
graph_configure $name xmax [expr $xmin + $width]
} else {
graph_configure $name xmax $sxmax
}
if { "$symax" == "auto" } {
graph_configure $name ymax $nymax
} else {
graph_configure $name ymax $symax
}
}
proc graph_draw { name canvas } {
_graph_set_scale $name
set xmin [graph_cget $name xmin]
set ymin [graph_cget $name ymin]
set xmax [graph_cget $name xmax]
set ymax [graph_cget $name ymax]
set delta_x [expr 1.0 * ($xmax - $xmin)]
set delta_y [expr 1.0 * ($ymax - $ymin)]
if { $delta_x == 0 } { set delta_x 1}
if { $delta_y == 0 } { set delta_y 1}
set ox [graph_cget $name origin_x]
set oy [graph_cget $name origin_y]
set width [graph_cget $name width]
set height [graph_cget $name height]
set cheight [winfo height .c]
set cwidth [winfo width .c]
set tags [lsort [graph_get_data_tags $name]]
$canvas delete withtag graph_$name
_graph_draw_grids $name $canvas $xmin $ymin $xmax $ymax $delta_x $delta_y
foreach tag $tags {
set ans {}
set offset [graph_cget_data $name $tag yoffset]
if {"$offset" == ""} {
set offset 0
}
set points [graph_cget_data $name $tag points]
set color [graph_cget_data $name $tag color]
if { "$color" == "" } { set color "black" }
set lwidth [graph_cget_data $name $tag width]
if { "$lwidth" == "" } { set lwidth 1 }
foreach {x y} $points {
set dx [expr ($x - $xmin) / $delta_x]
set dy [expr ($y - $ymin) / $delta_y]
set x [expr $dx * $width + $ox]
set y [expr $oy - ($dy * $height) - $offset]
lappend ans $x $y
}
if {[llength $ans] >= 4} {
$canvas create line $ans -fill $color -width $lwidth -tag graph_$name
}
}
# Draw the title in the upper left-hand corner
set title [graph_cget $name title]
if {"$title" != ""} {
set x [expr $ox + $width]
set y [expr $oy - $height]
set t [$canvas create text $x $y -anchor ne -text $title -tag graph_$name -font fixed]
set bbox [$canvas bbox $t]
$canvas create rectangle $bbox -fill white -outline white
$canvas raise $t
}
}
proc _graph_draw_grids { name canvas xmin ymin xmax ymax delta_x delta_y } {
set ox [graph_cget $name origin_x]
set oy [graph_cget $name origin_y]
set width [graph_cget $name width]
set height [graph_cget $name height]
set cheight [winfo height .c]
set cwidth [winfo width .c]
set xticks [graph_cget $name xticks]
set yticks [graph_cget $name yticks]
set gridcolor [graph_cget $name gridcolor]
set gridwidth [graph_cget $name gridwidth]
if {$xticks > 0 && $xmax > $xmin} {
set diff [expr ($xmax - $xmin) / $xticks]
set diff [nicenum $diff 1]
if { $diff > 0 } {
set last_item 0
for {set x $xmin} {$x <= $xmax} {set x [expr $x + $diff]} {
# Draw gridline
set x1 [expr (($x - $xmin) / $delta_x) * $width + $ox]
set y1 $oy
set y2 [expr $oy - $height]
$canvas create line $x1 $y1 $x1 $y2 -fill $gridcolor -width $gridwidth -tag graph_$name -stipple gray25
set this_item [$canvas create text $x1 [expr $y1 + 2] -text [format %.5g $x] -anchor n -tag graph_$name -font fixed]
foreach {bx1 by1 bx2 by2} [$canvas bbox $this_item] { break }
set overlaps [$canvas find overlapping $bx1 $by1 $bx2 $by2]
if {[lsearch -exact $overlaps $last_item] >= 0} {
$canvas delete $this_item
} else {
set last_item $this_item
}
}
}
}
if {$yticks > 0 && $ymax > $ymin} {
set diff [expr ($ymax - $ymin) / $yticks]
set diff [nicenum $diff 1]
if { $diff > 0 } {
set last_item 0
for {set y $ymin} {$y <= $ymax} {set y [expr $y + $diff]} {
# Draw gridline
set x1 $ox
set x2 [expr $ox + $width]
set y1 [expr $oy - (($y - $ymin) / $delta_y * $height)]
$canvas create line $x1 $y1 $x2 $y1 -fill $gridcolor -width $gridwidth -tag graph_$name -stipple gray25
set this_item [$canvas create text [expr $x1 - 2] $y1 -text [format %.5g $y] -anchor e -tag graph_$name -font fixed]
foreach {bx1 by1 bx2 by2} [$canvas bbox $this_item] { break }
set overlaps [$canvas find overlapping $bx1 $by1 $bx2 $by2]
if {[lsearch -exact $overlaps $last_item] >= 0} {
$canvas delete $this_item
} else {
set last_item $this_item
}
}
}
}
}
proc y {h max val border} {
set inner [expr $h - 2 * $border]
if {$max > 0} {
set step [expr (1.0 * $inner) / (1.0 * $max)]
} else {
set step 1
}
set y [expr $h - ($border + $val * $step)]
return $y
}
#***********************************************************************
# %PROCEDURE: get_status
# %ARGUMENTS:
# None
# %RETURNS:
# A status string from the multiplexor
# %DESCRIPTION:
# Gets mimedefang-multiplexor status
#***********************************************************************
proc get_status {} {
mx_command "rawload"
}
proc mx_command { cmd } {
global CtrlFD
open_command_channel
puts $CtrlFD $cmd
flush $CtrlFD
gets $CtrlFD line
if {[string match "ERROR *" $line]} {
error $line
}
return $line
}
proc open_command_channel {} {
global CtrlFD
global MD_MX_CTRL
if {"$CtrlFD" != "0"} {
return
}
set CtrlFD [open "|$MD_MX_CTRL -i" "r+"]
# Fix for Windoze boxes...
fconfigure $CtrlFD -translation binary
}
proc close_command_channel {} {
global CtrlFD
catch { close $CtrlFD }
set CtrlFD 0
}
#***********************************************************************
# %PROCEDURE: create_gui
# %ARGUMENTS:
# None
# %RETURNS:
# Nothing
# %DESCRIPTION:
# Creates the GUI
#***********************************************************************
proc create_gui {} {
global Margin
global MD_MX_CTRL
global Title
if {"$Title" != ""} {
wm title . "Watch MIMEDefang - $Title"
wm iconname . "Watch MIMEDefang - $Title"
} else {
wm title . "Watch MIMEDefang"
wm iconname . "Watch MIMEDefang"
}
canvas .c -relief sunken -width 400 -height 120 -takefocus 0 -borderwidth 2 -background white
canvas .load -relief sunken -width 400 -height 120 -takefocus 0 -borderwidth 2 -background white
canvas .latency -relief sunken -width 400 -height 120 -takefocus 0 -borderwidth 2 -background white
canvas .mps -relief sunken -width 400 -height 120 -takefocus 0 -borderwidth 2 -background white
canvas .activations -relief sunken -width 400 -height 120 -takefocus 0 -borderwidth 2 -background white
canvas .reaps -relief sunken -width 400 -height 120 -takefocus 0 -borderwidth 2 -background white
frame .f
scale .s -from 100 -to 10000 -resolution 100 -orient horizontal \
-label "Update Interval (ms)" -variable UpdateInterval
grid .c -row 0 -column 0 -sticky nsew
grid .load -row 0 -column 1 -sticky nsew
grid .latency -row 1 -column 0 -sticky nsew
grid .mps -row 1 -column 1 -sticky nsew
grid .activations -row 2 -column 0 -sticky nsew
grid .reaps -row 2 -column 1 -sticky nsew
grid .f -row 3 -column 0 -columnspan 2 -sticky nsew
grid columnconfigure . 0 -weight 1
grid columnconfigure . 1 -weight 1
grid rowconfigure . 0 -weight 1
grid rowconfigure . 1 -weight 1
grid rowconfigure . 2 -weight 1
label .f.l1 -text "Max: " -fg black
label .f.l2 -text "Busy: " -fg "#A00000"
label .f.l3 -text "Idle: " -fg "#00A000"
label .f.l4 -text "Queued: " -fg "#A0A000"
label .f.max -fg black -width 4 -anchor w
label .f.busy -fg "#A00000" -width 4 -anchor w
label .f.idle -fg "#00A000" -width 4 -anchor w
label .f.queued -fg "#A0A000" -width 4 -anchor w
button .f.reread -text "Reread Filters" -command reread
button .f.quit -text "Quit" -command exit
label .f.result -text "" -relief sunken -anchor w
frame .f.g
entry .f.g.cmd -width 40 -insertofftime 0
.f.g.cmd delete 0 end
.f.g.cmd insert end $MD_MX_CTRL
bind .f.g.cmd <Return> set_ctrl_command
label .f.g.cmdup -text "Control Command: "
pack .f.g.cmdup -side left -expand 0 -fill none
pack .f.g.cmd -side left -expand 1 -fill x
frame .f.legend
label .f.legend.uptime -text ""
checkbutton .f.legend.t0 -fg "#A00000" -text "10s " -variable Show(0) -command update_show
checkbutton .f.legend.t10 -fg "#A0A000" -text "10m" -variable Show(10) -command update_show
checkbutton .f.legend.t5 -fg "#00A000" -text "5m " -variable Show(5) -command update_show
checkbutton .f.legend.t1 -fg "#0000A0" -text "1m " -variable Show(1) -command update_show
pack .f.legend.uptime .f.legend.t0 .f.legend.t1 .f.legend.t5 .f.legend.t10 -side left -expand 0 -anchor center
grid .f.l1 -row 0 -column 0 -sticky w
grid .f.max -row 0 -column 1 -sticky w
grid .f.legend -row 0 -column 2
grid .f.reread -row 0 -column 3 -sticky e
grid .f.l2 -row 1 -column 0 -sticky e
grid .f.busy -row 1 -column 1 -sticky w
grid .f.quit -row 1 -column 3 -sticky e
grid .f.l4 -row 2 -column 0 -sticky e
grid .f.queued -row 2 -column 1 -sticky w
grid .f.g -row 2 -column 2 -sticky ew
grid .f.l3 -row 3 -column 0 -sticky e
grid .f.idle -row 3 -column 1 -sticky w
grid .f.result -row 3 -column 2 -columnspan 2 -sticky ew
grid columnconfigure .f 0 -weight 0
grid columnconfigure .f 1 -weight 0
grid columnconfigure .f 2 -weight 1
grid columnconfigure .f 3 -weight 0
grid .s -row 4 -column 0 -columnspan 2 -sticky ew
bind .c <Configure> [list canvas_resized .c BusyGraph]
bind .load <Configure> [list canvas_resized .load LoadGraph]
bind .latency <Configure> [list canvas_resized .latency LatencyGraph]
bind .mps <Configure> [list canvas_resized .mps MPSGraph]
bind .activations <Configure> [list canvas_resized .activations ActGraph]
bind .reaps <Configure> [list canvas_resized .reaps ReapGraph]
foreach i {BusyGraph LoadGraph LatencyGraph MPSGraph ActGraph ReapGraph} {
graph_create $i
graph_configure $i width [expr 400 - $Margin(left) - $Margin(right)]
graph_configure $i height [expr 120 - $Margin(top) - $Margin(bottom)]
graph_configure $i sxmin timeseries
graph_configure $i sxmax timeseries
graph_configure $i origin_y [expr 120 - $Margin(bottom)]
graph_configure $i origin_x $Margin(left)
graph_configure $i xticks 0
graph_configure $i yticks 5
}
graph_configure_data BusyGraph Busy color "#A00000"
graph_configure_data BusyGraph Busy width 1
graph_configure BusyGraph title "Busy Workers"
graph_configure LatencyGraph title "Latency (ms)"
graph_configure LoadGraph title "Workers/scan"
graph_configure MPSGraph title "Messages/s"
graph_configure ActGraph title "Activations/s"
graph_configure ReapGraph title "Reaps/s"
foreach i {LoadGraph LatencyGraph MPSGraph ActGraph ReapGraph} {
graph_configure_data $i D0 color "#A00000"
graph_configure_data $i D1 color "#0000A0"
graph_configure_data $i D5 color "#00A000"
graph_configure_data $i D10 color "#A0A000"
graph_configure_data $i D0 width 1
graph_configure_data $i D1 width 1
graph_configure_data $i D5 width 1
graph_configure_data $i D10 width 1
graph_configure_data $i D0 yoffset -1
graph_configure_data $i D1 yoffset 0
graph_configure_data $i D5 yoffset 1
graph_configure_data $i D10 yoffset 2
}
}
proc reread {} {
if {[catch {set ans [mx_command reread]} err]} {
do_result $err "#A00000" 3000
} else {
do_result $ans black 3000
}
}
proc set_ctrl_command {} {
global MD_MX_CTRL
global AfterResult
set MD_MX_CTRL [.f.g.cmd get]
close_command_channel
clear_result
catch {after cancel $AfterResult}
update_show
graph_add_data BusyGraph Busy {}
}
proc do_result { text color delay } {
global AfterResult
.f.result configure -fg $color -text $text
catch {after cancel $AfterResult}
set AfterResult [after $delay clear_result]
}
proc clear_result {} {
global AfterResult
set AfterResult 0
.f.result configure -text "" -fg black
}
proc update_show {} {
foreach g {LatencyGraph MPSGraph LoadGraph ActGraph ReapGraph} {
foreach d {D0 D1 D5 D10} {
graph_add_data $g $d {}
graph_configure_data $g $d auto_x 0
}
}
}
proc canvas_resized {c g} {
global Margin
set w [winfo width $c]
set h [winfo height $c]
graph_configure $g width [expr $w - $Margin(left) - $Margin(right)]
graph_configure $g height [expr $h - $Margin(top) - $Margin(bottom)]
graph_configure $g origin_y [expr $h - $Margin(bottom)]
graph_draw $g $c
}
proc clear_after_error { msg } {
global UpdateInterval
do_result $msg "#A00000" 3000
close_command_channel
graph_add_data BusyGraph Busy {}
foreach i {LoadGraph LatencyGraph MPSGraph ActGraph ReapGraph} {
foreach d {D0 D1 D5 D10} {
graph_add_data $i $d {}
}
}
graph_draw LoadGraph .load
graph_draw LatencyGraph .latency
graph_draw MPSGraph .mps
graph_draw BusyGraph .c
graph_draw ActGraph .activations
graph_draw ReapGraph .reaps
.f.max configure -text "???"
.f.busy configure -text "???"
.f.idle configure -text "???"
.f.queued configure -text "???"
.f.legend.uptime configure -text "Uptime ??? "
return
}
proc uptime { secs } {
set weeks [expr $secs / 604800]
set secs [expr $secs - ($weeks * 604800)]
set days [expr $secs / 86400]
set secs [expr $secs - ($days * 86400)]
set hours [expr $secs / 3600]
set secs [expr $secs - ($hours * 3600)]
set mins [expr $secs / 60]
set secs [expr $secs - ($mins * 60)]
set ans ""
if {$weeks != 0} { append ans "${weeks}w " }
if {$days != 0} { append ans "${days}d " }
if {$hours != 0} { append ans [format "%02dh " $hours]}
if {$mins != 0} { append ans [format "%02dm " $mins]}
append ans [format "%02ds" $secs]
return $ans
}
proc take_reading {} {
global UpdateInterval
if {[catch {take_reading_aux} ans]} {
clear_after_error $ans
after $UpdateInterval take_reading
return
}
after $UpdateInterval take_reading
}
#***********************************************************************
# %PROCEDURE: take_reading_aux
# %ARGUMENTS:
# None
# %RETURNS:
# Nothing
# %DESCRIPTION:
# Takes a reading and updates GUI
#***********************************************************************
proc take_reading_aux {} {
global Show
set line [get_status]
foreach {msgs_0 msgs_1 msgs_5 msgs_10 avg_0 avg_1 avg_5 avg_10 ams_0 ams_1 ams_5 ams_10 a0 a1 a5 a10 r0 r1 r5 r10 nbusy nidle nstopped nkilled msgs activations qsize numq secs} $line {break}
set secs [uptime $secs]
if {![info exists msgs_0] || ![info exists secs]} {
error "Error: Unable to interpret result: $line"
return
}
set mps_0 [expr $msgs_0 / 10.0]
set mps_1 [expr $msgs_1 / 60.0]
set mps_5 [expr $msgs_5 / 300.0]
set mps_10 [expr $msgs_10 / 600.0]
set a0 [expr $a0 / 10.0]
set a1 [expr $a1 / 60.0]
set a5 [expr $a5 / 300.0]
set a10 [expr $a10 / 600.0]
set r0 [expr $r0 / 10.0]
set r1 [expr $r1 / 60.0]
set r5 [expr $r5 / 300.0]
set r10 [expr $r10 / 600.0]
graph_add_point BusyGraph Busy auto $nbusy
graph_keep_lastn BusyGraph Busy [graph_cget BusyGraph width]
graph_configure BusyGraph symin 0
set total [expr $nbusy + $nidle + $nstopped + $nkilled]
graph_configure BusyGraph symax $total
graph_configure BusyGraph yticks $total
graph_draw BusyGraph .c
if {$Show(0)} {
graph_add_point LoadGraph D0 auto $avg_0
graph_add_point LatencyGraph D0 auto $ams_0
graph_add_point MPSGraph D0 auto $mps_0
graph_add_point ActGraph D0 auto $a0
graph_add_point ReapGraph D0 auto $r0
}
if {$Show(1)} {
graph_add_point LoadGraph D1 auto $avg_1
graph_add_point LatencyGraph D1 auto $ams_1
graph_add_point MPSGraph D1 auto $mps_1
graph_add_point ActGraph D1 auto $a1
graph_add_point ReapGraph D1 auto $r1
}
if {$Show(5)} {
graph_add_point LoadGraph D5 auto $avg_5
graph_add_point LatencyGraph D5 auto $ams_5
graph_add_point MPSGraph D5 auto $mps_5
graph_add_point ActGraph D5 auto $a5
graph_add_point ReapGraph D5 auto $r5
}
if {$Show(10)} {
graph_add_point LoadGraph D10 auto $avg_10
graph_add_point LatencyGraph D10 auto $ams_10
graph_add_point MPSGraph D10 auto $mps_10
graph_add_point ActGraph D10 auto $a10
graph_add_point ReapGraph D10 auto $r10
}
graph_draw LoadGraph .load
graph_draw LatencyGraph .latency
graph_draw MPSGraph .mps
graph_draw ActGraph .activations
graph_draw ReapGraph .reaps
.f.max configure -text "$total"
.f.legend.uptime configure -text "Uptime $secs "
.f.busy configure -text $nbusy
.f.idle configure -text $nidle
.f.queued configure -text $numq
}
proc usage {} {
global argv0
puts stderr "Usage: $argv0 options"
puts stderr "\nOptions are:"
puts stderr " -command cmd Use 'cmd' as Control Command"
puts stderr " -interval msec Update every msec milliseconds"
puts stderr " -10s 0_or_1 Show or hide 10s graph plot"
puts stderr " -1m 0_or_1 Show or hide 1m graph plot"
puts stderr " -5m 0_or_1 Show or hide 5ms graph plot"
puts stderr " -10m 0_or_1 Show or hide 10m graph plot"
puts stderr " -title string Add string to window title"
puts stderr " -help Show this usage info"
exit 0
}
proc parse_cmdline_args {} {
global argv
global MD_MX_CTRL
global UpdateInterval
global Show
global Title
foreach {opt val} $argv {
switch -exact -- $opt {
-command {
set MD_MX_CTRL $val
}
-interval {
set UpdateInterval $val
}
-10s {
set Show(0) $val
}
-1m {
set Show(1) $val
}
-5m {
set Show(5) $val
}
-10m {
set Show(10) $val
}
-title {
set Title $val
}
-help {
usage
exit 0
}
default {
puts stderr "Unrecognized option $opt"
usage
exit 1
}
}
}
}
parse_cmdline_args
create_gui
# Kick things off
take_reading
|