trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bc...@apache.org
Subject git commit: Top type program for traffic server. Shows statistical information.
Date Fri, 27 Apr 2012 22:03:12 GMT
Updated Branches:
  refs/heads/master 09d85f6cd -> 9c0f0ef94


Top type program for traffic server.  Shows statistical information.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/9c0f0ef9
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/9c0f0ef9
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/9c0f0ef9

Branch: refs/heads/master
Commit: 9c0f0ef94bfb8a2e5d904097a7a64cae20268bf5
Parents: 09d85f6
Author: Bryan Call <bryan_call@yahoo.com>
Authored: Fri Apr 27 14:35:19 2012 -0700
Committer: Bryan Call <bryan_call@yahoo.com>
Committed: Fri Apr 27 14:35:19 2012 -0700

----------------------------------------------------------------------
 contrib/tstop/.#README |    1 +
 contrib/tstop/README   |    4 +
 contrib/tstop/tstop    |  445 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 450 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9c0f0ef9/contrib/tstop/.#README
----------------------------------------------------------------------
diff --git a/contrib/tstop/.#README b/contrib/tstop/.#README
new file mode 120000
index 0000000..eda3bff
--- /dev/null
+++ b/contrib/tstop/.#README
@@ -0,0 +1 @@
+bcall@snowball.fodder.org.12212:1334785067
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9c0f0ef9/contrib/tstop/README
----------------------------------------------------------------------
diff --git a/contrib/tstop/README b/contrib/tstop/README
new file mode 100644
index 0000000..10f33b7
--- /dev/null
+++ b/contrib/tstop/README
@@ -0,0 +1,4 @@
+Top type program for Apache Traffic Server that displays common
+statistical information about the server.  Requires the server to be
+running the stats_over_http plugin.
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9c0f0ef9/contrib/tstop/tstop
----------------------------------------------------------------------
diff --git a/contrib/tstop/tstop b/contrib/tstop/tstop
new file mode 100755
index 0000000..bf72ab7
--- /dev/null
+++ b/contrib/tstop/tstop
@@ -0,0 +1,445 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use JSON;
+use LWP::Simple;
+use Data::Dumper;
+use Curses;
+use Getopt::Std;
+
+#open(LOG, ">/tmp/tstop.log");
+
+my $sleep = 5;
+my $server;
+my $os;                         # old stats
+my $w;
+my %lookup = (
+              disk_total => { name => "Disk Total",
+                              stat => "proxy.process.cache.bytes_total",
+                              type => "sum",
+                            },
+              disk_used => { name => "Disk Used",
+                             stat => "proxy.process.cache.bytes_used",
+                             type => "sum",
+                           },
+              ram_total => { name => "Ram Total",
+                             stat => "proxy.process.cache.ram_cache.total_bytes",
+                             type => "sum",
+                           },
+              ram_used => { name => "Ram Used",
+                            stat => "proxy.process.cache.ram_cache.bytes_used",
+                            type => "sum",
+                          },
+              cache_lookup => { name => "Lookups",
+                                stat => "proxy.process.http.cache_lookups",
+                              },
+              cache_writes => { name => "Writes",
+                                stat => "proxy.process.http.cache_writes",
+                              },
+              cache_updates => { name => "Updates",
+                                 stat => "proxy.process.http.cache_updates",
+                               },
+              cache_deletes => { name => "Deletes",
+                                 stat => "proxy.process.http.cache_deletes",
+                               },
+              cache_read_active => { name => "Read Activ",
+                                     stat => "proxy.process.cache.read.active",
+                                     type => "sum",
+                                   },
+              cache_write_active => { name => "Write Acti",
+                                      stat => "proxy.process.cache.write.active",
+                                      type => "sum",
+                                    },
+              cache_update_active => { name => "Update Act",
+                                       stat => "proxy.process.cache.update.active",
+                                       type => "sum",
+                                     },
+              get => { name => "GET",
+                       stat => "proxy.process.http.get_requests",
+                       type => 'percent'
+                     },
+              head => { name => "HEAD",
+                        stat => "proxy.process.http.head_requests",
+                        type => 'percent'
+                      },
+              post => { name => "POST",
+                        stat => "proxy.process.http.post_requests",
+                        type => 'percent'
+                      },
+              '2xx' => { name => "2xx",
+                         stat => "proxy.process.http.2xx_responses",
+                         type => 'percent'
+                       },
+              '200' => { name => "200",
+                         stat => "proxy.process.http.200_responses",
+                         type => 'percent'
+                       },
+              '206' => { name => "206",
+                         stat => "proxy.process.http.206_responses",
+                         type => 'percent'
+                       },
+              '3xx' => { name => "3xx",
+                         stat => "proxy.process.http.3xx_responses",
+                         type => 'percent'
+                       },
+              '301' => { name => "301",
+                         stat => "proxy.process.http.301_responses",
+                         type => 'percent'
+                       },
+              '302' => { name => "302",
+                         stat => "proxy.process.http.302_responses",
+                         type => 'percent'
+                       },
+              '304' => { name => "304",
+                         stat => "proxy.process.http.304_responses",
+                         type => 'percent'
+                       },
+              '4xx' => { name => "4xx",
+                         stat => "proxy.process.http.4xx_responses",
+                         type => 'percent'
+                       },
+              '404' => { name => "404",
+                         stat => "proxy.process.http.404_responses",
+                         type => 'percent'
+                       },
+              '5xx' => { name => "5xx",
+                         stat => "proxy.process.http.5xx_responses",
+                         type => 'percent'
+                       },
+              '502' => { name => "502",
+                         stat => "proxy.process.http.502_responses",
+                         type => 'percent'
+                       },
+              client_req => { name => "Requests",
+                              stat => "proxy.process.http.incoming_requests",
+                            },
+              mean_req_size => { name => "Avg Size",
+                               },
+              mean_res_size => { name => "Avg Size",
+                               },
+              client_req_time => { name => "Resp (ms)",
+                                 },
+              server_req_time => { name => "Resp (ms)",
+                                 },
+              client_req_conn => { name => "Req/Conn",
+                                 },
+              client_conn => { name => "New Conn",
+                               stat => "proxy.process.http.total_client_connections",
+                             },
+              client_cconn => { name => "Curr Conn",
+                                stat => "proxy.process.http.current_client_connections",
+                                type => "sum",
+                              },
+              client_aconn => { name => "Active Con",
+                                stat => "proxy.process.http.current_active_client_connections",
+                                type => "sum",
+                              },
+              client_head => { name => "Head Bytes",
+                               stat => "proxy.process.http.user_agent_response_header_total_size",
+                             },
+              client_body => { name => "Body Bytes",
+                               stat => "proxy.process.http.user_agent_response_document_total_size",
+                             },
+              client_net => { name => "Network",
+                            },
+              server_req => { name => "Requests",
+                              stat => "proxy.process.http.outgoing_requests",
+                            },
+              server_req_conn => { name => "Req/Conn",
+                                 },
+              server_conn => { name => "New Conn",
+                               stat => "proxy.process.http.total_server_connections",
+                             },
+              server_cconn => { name => "Curr Conn",
+                                stat => "proxy.process.http.current_server_connections",
+                                type => "sum",
+                              },
+              server_head => { name => "Head Bytes",
+                               stat => "proxy.process.http.origin_server_response_header_total_size",
+                             },
+              server_body => { name => "Body Bytes",
+                               stat => "proxy.process.http.origin_server_response_document_total_size",
+                             },
+              server_net => { name => "Network",
+                            },
+              total_time => { name => "Time",
+                              stat => "proxy.process.http.total_transactions_time",
+                            },
+              hit_fresh => { name => "Fresh",
+                             stat => "proxy.process.http.transaction_counts.hit_fresh",
+                             type => 'percent'
+                           },
+              hit_fresh_time => { name => "Fresh (ms)",
+                                  stat => "proxy.process.http.transaction_totaltime.hit_fresh",
+                                },
+              hit_reval_time => { name => "Reval (ms)",
+                                  stat => "proxy.process.http.transaction_totaltime.hit_revalidated",
+                                },
+              miss_cold_time => { name => "Cold (ms)",
+                                  stat => "proxy.process.http.transaction_totaltime.miss_cold",
+                                },
+              miss_changed_time => { name => "Chang (ms)",
+                                     stat => "proxy.process.http.transaction_totaltime.miss_changed",
+                                   },
+              miss_not_cacheable_time => { name => "Not (ms)",
+                                           stat => "proxy.process.http.transaction_totaltime.miss_not_cacheable",
+                                         },
+              miss_no_cache_time => { name => "No (ms)",
+                                      stat => "proxy.process.http.transaction_totaltime.miss_client_no_cache",
+                                    },
+              ram_hit => { name => "Ram Hit",
+                           stat => "proxy.process.cache.ram_cache.hits",
+                         },
+              ram_miss => { name => "Ram Misses",
+                            stat => "proxy.process.cache.ram_cache.misses",
+                          },
+              hit_reval => { name => "Revalidate",
+                             stat => "proxy.process.http.transaction_counts.hit_revalidated",
+                             type => 'percent'
+                           },
+              miss_cold => { name => "Cold",
+                             stat => "proxy.process.http.transaction_counts.miss_cold",
+                             type => 'percent'
+                           },
+              miss_changed => { name => "Changed",
+                                stat => "proxy.process.http.transaction_counts.miss_changed",
+                                type => 'percent'
+                              },
+              miss_not_cacheable => { name => "Not Cache",
+                                      stat => "proxy.process.http.transaction_counts.miss_not_cacheable",
+                                      type => 'percent'
+                                    },
+              miss_no_cache => { name => "No Cache",
+                                 stat => "proxy.process.http.transaction_counts.miss_client_no_cache",
+                                 type => 'percent'
+                               },
+              client_abort => { name => "Clnt Abort",
+                                stat => "proxy.process.http.err_client_abort_count_stat",
+                              },
+              client_fail => { name => "Clnt Fail",
+                               stat => "proxy.process.http.err_connect_fail_count_stat",
+                             },
+              error_abort => { name => "Abort",
+                               stat => "proxy.process.http.transaction_counts.errors.aborts",
+                             },
+              error_fail => { name => "Conn Fail",
+                              stat => "proxy.process.http.transaction_counts.errors.connect_failed",
+                            },
+              error_other => { name => "ERR Other",
+                               stat => "proxy.process.http.transaction_counts.errors.other",
+                             },
+              size_100 => { name => "100 B",
+                            stat => "proxy.process.http.response_document_size_100",
+                            type => 'percent'
+                          },
+              size_1k => { name => "1 KB",
+                           stat => "proxy.process.http.response_document_size_1K",
+                           type => 'percent'
+                         },
+              size_3k => { name => "3 KB",
+                           stat => "proxy.process.http.response_document_size_3K",
+                           type => 'percent'
+                         },
+              size_5k => { name => "5 KB",
+                           stat => "proxy.process.http.response_document_size_5K",
+                           type => 'percent'
+                         },
+              size_10k => { name => "10 KB",
+                            stat => "proxy.process.http.response_document_size_10K",
+                            type => 'percent'
+                          },
+              size_1m => { name => "1 MB",
+                           stat => "proxy.process.http.response_document_size_1M",
+                           type => 'percent'
+                         },
+              size_inf => { name => "> 1 MB",
+                            stat => "proxy.process.http.response_document_size_inf",
+                            type => 'percent'
+                          },
+              cache_entries => { name => "Entries",
+                            stat => "proxy.process.cache.direntries.used",
+                            type => 'sum'
+                          },
+              cache_avg_size => { name => "Avg Size",
+                                },
+             );
+
+sub getStats() {
+
+  my $content = get("http://$server/_stats");
+  die "can't get stats from server" if (!defined $content);
+  my $data = decode_json($content);
+  #   $stats = $data;
+  #print Dumper($stats);
+  #   print $data->{global}, "\n";
+  #return $data->{global};
+  return $data;
+}
+
+sub prettyPrint($) {
+  my($number) = @_;
+
+  if ($number / 1_000_000_000_000 > 1) {
+    $number = sprintf("%6.1fT", $number / 1_000_000_000_000);
+  } elsif ($number / 1_000_000_000 > 1) {
+    $number = sprintf("%6.1fG", $number / 1_000_000_000);
+  } elsif ($number / 1_000_000 > 1) {
+    $number = sprintf("%6.1fM", $number / 1_000_000);
+  } elsif ($number / 1_000 > 1) {
+    $number = sprintf("%6.1fK", $number / 1_000);
+  } else {
+    $number = sprintf("%6.1f ", $number);
+  }
+
+  return $number;
+}
+
+sub printStat($$) {
+  my($stat, $name) = @_;
+  my $delta = 0;
+
+  if ($name eq 'client_req_conn') {
+    my $d1 = ($stat->{$lookup{client_req}->{stat}} - $os->{$lookup{client_req}->{stat}})
/ $sleep;
+    my $d2 = ($stat->{$lookup{client_conn}->{stat}} - $os->{$lookup{client_conn}->{stat}})
/ $sleep;
+    $delta = $d1 / $d2 if $d2 > 0;
+  } elsif ($name eq 'server_req_conn') {
+    my $d1 = ($stat->{$lookup{server_req}->{stat}} - $os->{$lookup{server_req}->{stat}})
/ $sleep;
+    my $d2 = ($stat->{$lookup{server_conn}->{stat}} - $os->{$lookup{server_conn}->{stat}})
/ $sleep;
+    $delta = $d1 / $d2 if $d2 > 0;
+  } elsif ($name eq 'mean_req_size') {
+    my $d1 = ($stat->{$lookup{client_head}->{stat}} + $stat->{$lookup{client_body}->{stat}})
* 8;
+    my $d2 = ($os->{$lookup{client_head}->{stat}} + $os->{$lookup{client_body}->{stat}})
* 8;
+    my $bytes = ($d1 - $d2);
+    my $req = $stat->{$lookup{client_req}->{stat}} - $os->{$lookup{client_req}->{stat}};
+    $delta = $bytes / $req;
+  } elsif ($name eq 'mean_res_size') {
+    my $d1 = ($stat->{$lookup{server_head}->{stat}} + $stat->{$lookup{server_body}->{stat}})
* 8;
+    my $d2 = ($os->{$lookup{server_head}->{stat}} + $os->{$lookup{server_body}->{stat}})
* 8;
+    my $bytes = ($d1 - $d2);
+    my $req = $stat->{$lookup{server_req}->{stat}} - $os->{$lookup{server_req}->{stat}};
+    $delta = $bytes / $req;
+  } elsif ($name eq 'client_net') {
+    my $d1 = ($stat->{$lookup{client_head}->{stat}} + $stat->{$lookup{client_body}->{stat}})
* 8;
+    my $d2 = ($os->{$lookup{client_head}->{stat}} + $os->{$lookup{client_body}->{stat}})
* 8;
+    $delta = ($d1 - $d2) / $sleep;
+  } elsif ($name eq 'server_net') {
+    my $d1 = ($stat->{$lookup{server_head}->{stat}} + $stat->{$lookup{server_body}->{stat}})
* 8;
+    my $d2 = ($os->{$lookup{server_head}->{stat}} + $os->{$lookup{server_body}->{stat}})
* 8;
+    $delta = ($d1 - $d2) / $sleep;
+  } elsif ($name eq 'client_req_time') {
+    my $d1 = ($stat->{$lookup{total_time}->{stat}} - $os->{$lookup{total_time}->{stat}})
/ $sleep / 10_000_000;
+    my $d2 = ($stat->{$lookup{client_req}->{stat}} - $os->{$lookup{client_req}->{stat}})
/ $sleep;
+    $delta = $d1 / $d2 if $d2 > 0;
+  } elsif ($name eq 'hit_fresh_time') {
+    my $d1 = ($stat->{$lookup{hit_fresh}->{stat}} - $os->{$lookup{hit_fresh}->{stat}})
/ $sleep;
+    my $d2 = ($stat->{$lookup{hit_fresh_time}->{stat}} - $os->{$lookup{hit_fresh_time}->{stat}})
/ $sleep;
+    $delta = $d2 / $d1 * 1000 if $d1 > 0;
+  } elsif ($name eq 'hit_reval_time') {
+    my $d1 = ($stat->{$lookup{hit_reval}->{stat}} - $os->{$lookup{hit_reval}->{stat}})
/ $sleep;
+    my $d2 = ($stat->{$lookup{hit_reval_time}->{stat}} - $os->{$lookup{hit_reval_time}->{stat}})
/ $sleep;
+    $delta = $d2 / $d1 * 1000 if $d1 > 0;
+  } elsif ($name eq 'miss_cold_time') {
+    my $d1 = ($stat->{$lookup{miss_cold}->{stat}} - $os->{$lookup{miss_cold}->{stat}})
/ $sleep;
+    my $d2 = ($stat->{$lookup{miss_cold_time}->{stat}} - $os->{$lookup{miss_cold_time}->{stat}})
/ $sleep;
+    $delta = $d2 / $d1 * 1000 if $d1 > 0;
+  } elsif ($name eq 'miss_changed_time') {
+    my $d1 = ($stat->{$lookup{miss_changed}->{stat}} - $os->{$lookup{miss_changed}->{stat}})
/ $sleep;
+    my $d2 = ($stat->{$lookup{miss_changed_time}->{stat}} - $os->{$lookup{miss_changed_time}->{stat}})
/ $sleep;
+    $delta = $d2 / $d1 * 1000 if $d1 > 0;
+  } elsif ($name eq 'miss_not_cacheable_time') {
+    my $d1 = ($stat->{$lookup{miss_not_cacheable}->{stat}} - $os->{$lookup{miss_not_cacheable}->{stat}})
/ $sleep;
+    my $d2 = ($stat->{$lookup{miss_not_cacheable_time}->{stat}} - $os->{$lookup{miss_not_cacheable_time}->{stat}})
/ $sleep;
+    $delta = $d2 / $d1 * 1000 if $d1 > 0;
+  } elsif ($name eq 'miss_no_cache_time') {
+    my $d1 = ($stat->{$lookup{miss_no_cache}->{stat}} - $os->{$lookup{miss_no_cache}->{stat}})
/ $sleep;
+    my $d2 = ($stat->{$lookup{miss_no_cache_time}->{stat}} - $os->{$lookup{miss_no_cache_time}->{stat}})
/ $sleep;
+    $delta = $d2 / $d1 * 1000 if $d1 > 0;
+  } elsif ($name eq 'ram_ratio') {
+    my $d1 = ($stat->{$lookup{ram_hit}->{stat}} - $os->{$lookup{ram_hit}->{stat}})
/ $sleep;
+    my $d2 = ($stat->{$lookup{ram_miss}->{stat}} - $os->{$lookup{ram_miss}->{stat}})
/ $sleep;
+    $delta = $d1 / ($d1 + $d2) * 100 if ($d1 != 0 && $d2 != 0);
+    return sprintf("%10s %6.1f%%", "Ram Hit", $delta);
+    return;
+  } elsif ($name eq 'cache_avg_size') {
+    $delta = $stat->{$lookup{disk_total}->{stat}} / $stat->{$lookup{cache_entries}->{stat}};
+  } elsif (!defined $lookup{$name}->{type}) {
+    $delta = ($stat->{$lookup{$name}->{stat}} - $os->{$lookup{$name}->{stat}})
/ $sleep;
+  } elsif ($lookup{$name}->{type} eq 'sum') {
+    $delta = $stat->{$lookup{$name}->{stat}};
+  } elsif ($lookup{$name}->{type} eq 'percent') {
+    my $d1 = ($stat->{$lookup{$name}->{stat}} - $os->{$lookup{$name}->{stat}})
/ $sleep;
+    my $d2 = ($stat->{$lookup{client_req}->{stat}} - $os->{$lookup{client_req}->{stat}})
/ $sleep;
+    $delta = $d1 / $d2 * 100 if $d2 > 0;
+    return sprintf("%10s %6.1f%%", $lookup{$name}->{name}, $delta);
+    return;
+  }
+
+  return sprintf("%10s %7s", $lookup{$name}->{name}, prettyPrint($delta));
+}
+
+sub makeTable($$$$$) {
+  my($w, $s, $x, $y, $info) = @_;
+  $w->addstr($x++, $y + 10, $info->{title});
+
+  foreach (@{$info->{items}}) {
+    $w->addstr($x, $y, printStat($s, $_));
+    $x++;
+  }
+}
+
+sub help() {
+  print STDERR "USAGE: tstop [-s seconds] server_host|server_host:port\n\n";
+  print STDERR "NOTE: be default it will update every 5 seconds...\n";
+  exit;
+}
+
+{
+  my %opts;
+  getopts("s:", \%opts);
+  $sleep = $opts{s} if (defined $opts{s});
+  help() if (! defined $ARGV[0]);
+  $server = $ARGV[0];
+
+  my $s = getStats();
+  $s = $s->{global};
+
+  print "Sleeping for $sleep before gathering stats again...\n";
+  sleep $sleep;
+  initscr;
+  $w = newwin(80, COLS(), 0, 0);  
+  while (1) {
+    $os = $s;
+    $s = getStats();
+    $s = $s->{global};
+    #print Dumper($s);
+
+    #-------------------------
+    # grid
+    foreach (1..22) {
+      $w->addstr($_, 39, "|");
+    }
+    foreach ((0,16,23)) {
+      $w->addstr($_, 0, "-" x 80);
+    }
+
+    # data
+    makeTable($w, $s, 1, 0, {title => 'CACHE INFORMATION', items => [qw(disk_used disk_total
ram_used ram_total cache_lookup cache_writes cache_updates cache_deletes cache_write_active
cache_read_active cache_update_active cache_entries cache_avg_size)],});
+    makeTable($w, $s, 1, 21, {title => '', items => [qw(ram_ratio hit_fresh hit_reval
miss_cold miss_changed miss_not_cacheable miss_no_cache hit_fresh_time hit_reval_time miss_cold_time
miss_changed_time miss_not_cacheable_time miss_no_cache_time)],});
+    makeTable($w, $s, 1, 40, {title => 'CLIENT REQUEST & RESPONSE', items => [qw(get
head post 2xx 3xx 4xx 5xx client_abort client_fail error_abort error_fail error_other)],});
+    makeTable($w, $s, 1, 60, {title => '', items => [qw(200 206 301 302 304 404 502
size_100 size_1k size_3k size_5k size_10k size_1m size_inf)],});
+
+    makeTable($w, $s, 17, 0, {title => 'CLIENT', items => [qw(client_req client_req_conn
client_conn client_cconn client_aconn)],});
+    makeTable($w, $s, 17, 21, {title => '', items => [qw(client_head client_body client_net
mean_req_size client_req_time)],});
+    makeTable($w, $s, 17, 40, {title => 'ORIGIN SERVER', items => [qw(server_req server_req_conn
server_conn server_cconn)],});
+    makeTable($w, $s, 17, 61, {title => '', items => [qw(server_head server_body server_net
mean_res_size)],});
+
+    #-------------------------
+
+    $w->refresh();
+    sleep $sleep;
+    $w->clear();
+  }
+
+  endwin;
+}


Mime
View raw message