root / plugins / other / opentracker_ @ 83159620
Historique | Voir | Annoter | Télécharger (11,6 ko)
| 1 | 0979570a | Matt West | #!/usr/bin/perl |
|---|---|---|---|
| 2 | # |
||
| 3 | =head1 OPENTRACKER PLUGIN |
||
| 4 | |||
| 5 | A Plugin to monitor OpenTracker Servers and their Performance |
||
| 6 | |||
| 7 | =head1 MUNIN CONFIGURATION |
||
| 8 | |||
| 9 | [opentracker*] |
||
| 10 | env.host 127.0.0.1 *default* |
||
| 11 | env.port 6969 *default* |
||
| 12 | env.uri /stats *default* |
||
| 13 | |||
| 14 | =head2 MUNIN ENVIRONMENT CONFIGURATION EXPLANATION |
||
| 15 | |||
| 16 | host = opentracker host to connect to |
||
| 17 | port = opentracker http port to connect to |
||
| 18 | uri = stats uri for appending requests for data |
||
| 19 | |||
| 20 | I need this information so I can later build the full url which normally |
||
| 21 | looks like the following example when put together: |
||
| 22 | http://127.0.0.1:6969/stats?mode=conn |
||
| 23 | |||
| 24 | =head1 AUTHOR |
||
| 25 | |||
| 26 | Matt West < https://github.com/mhwest13/OpenTracker-Munin-Plugin > |
||
| 27 | |||
| 28 | =head1 LICENSE |
||
| 29 | |||
| 30 | GPLv2 |
||
| 31 | |||
| 32 | =head1 MAGIC MARKERS |
||
| 33 | |||
| 34 | #%# family=auto |
||
| 35 | #%# capabilities=autoconf suggest |
||
| 36 | |||
| 37 | =cut |
||
| 38 | |||
| 39 | use strict; |
||
| 40 | use warnings; |
||
| 41 | |||
| 42 | use File::Basename; |
||
| 43 | use LWP::UserAgent; |
||
| 44 | |||
| 45 | if (basename($0) !~ /^opentracker_/) {
|
||
| 46 | print "This script needs to be named opentracker_ and have symlinks which start the same.\n"; |
||
| 47 | exit 1; |
||
| 48 | } |
||
| 49 | |||
| 50 | my $host = $ENV{host} || '127.0.0.1';
|
||
| 51 | my $port = $ENV{port} || 6969;
|
||
| 52 | my $uri = $ENV{uri} || '/stats';
|
||
| 53 | |||
| 54 | =head1 Graph Declarations |
||
| 55 | |||
| 56 | This block of code builds up all of the graph info for all root / sub graphs. |
||
| 57 | |||
| 58 | %graphs is a container for all of the graph definition information. In here is where you'll |
||
| 59 | find the configuration information for munin's graphing procedure. |
||
| 60 | Format: |
||
| 61 | |||
| 62 | $graph{graph_name} => {
|
||
| 63 | config => {
|
||
| 64 | { key => value }, You'll find the main graph config stored here.
|
||
| 65 | { ... },
|
||
| 66 | }, |
||
| 67 | keys => [ 'Name', 'Name', 'Name', ... ], Used for building results set. |
||
| 68 | datasrc => [ |
||
| 69 | # Name: name given to data value |
||
| 70 | # Attr: Attribute for given value, attribute must be valid plugin argument |
||
| 71 | { name => 'Name', info => 'info about graph' },
|
||
| 72 | { ... },
|
||
| 73 | ], |
||
| 74 | results => {
|
||
| 75 | { key => value }, You'll find the results info from fetch_stats call stored here.
|
||
| 76 | { ... },
|
||
| 77 | }, |
||
| 78 | } |
||
| 79 | |||
| 80 | =cut |
||
| 81 | |||
| 82 | my %graphs; |
||
| 83 | |||
| 84 | # graph for connections |
||
| 85 | $graphs{conn} = {
|
||
| 86 | config => {
|
||
| 87 | args => '--lower-limit 0', |
||
| 88 | vlabel => 'Connections', |
||
| 89 | category => 'opentracker', |
||
| 90 | title => 'Current Connections', |
||
| 91 | info => 'Current Connections to OpenTracker', |
||
| 92 | }, |
||
| 93 | keys => [ 'Requests', 'Announces' ], |
||
| 94 | datasrc => [ |
||
| 95 | { name => 'Requests', label => 'Requests', min => '0', type => 'COUNTER', info => 'number of Requests', draw => 'AREA' },
|
||
| 96 | { name => 'Announces', label => 'Announces', min => '0', type => 'COUNTER', info => 'number of Announces', draw => 'LINE2' },
|
||
| 97 | ], |
||
| 98 | }; |
||
| 99 | # graph for peers |
||
| 100 | $graphs{peer} = {
|
||
| 101 | config => {
|
||
| 102 | args => '--lower-limit 0', |
||
| 103 | vlabel => 'Peers', |
||
| 104 | category => 'opentracker', |
||
| 105 | title => 'Peers and Seeders', |
||
| 106 | info => 'Current Peer and Seeder Connections', |
||
| 107 | }, |
||
| 108 | keys => [ 'Peers', 'Seeders' ], |
||
| 109 | datasrc => [ |
||
| 110 | { name => 'Peers', label => 'Peers', min => '0', type => 'GAUGE', info => 'current number of leechers & seeders (peers)', draw => 'AREA' },
|
||
| 111 | { name => 'Seeders', label => 'Seeders', min => '0', type => 'GAUGE', info => 'current number of seeders', draw => 'LINE2' },
|
||
| 112 | ], |
||
| 113 | }; |
||
| 114 | # graph for scrapes |
||
| 115 | $graphs{scrp} = {
|
||
| 116 | config => {
|
||
| 117 | args => '--lower-limit 0', |
||
| 118 | vlabel => 'Scrapes', |
||
| 119 | category => 'opentracker', |
||
| 120 | title => 'Scrapes', |
||
| 121 | info => 'Number of Scrapes (TCP/UDP)', |
||
| 122 | }, |
||
| 123 | keys => [ 'TCP', 'UDP' ], |
||
| 124 | datasrc => [ |
||
| 125 | { name => 'TCP', label => 'TCP Requests', min => '0', type => 'COUNTER', info => 'number of scrapes requested via tcp', draw => 'AREASTACK' },
|
||
| 126 | { name => 'UDP', label => 'UDP Requests', min => '0', type => 'COUNTER', info => 'number of scrapes requested via udp', draw => 'AREA' },
|
||
| 127 | ], |
||
| 128 | }; |
||
| 129 | # graph for livesyncs |
||
| 130 | $graphs{syncs} = {
|
||
| 131 | config => {
|
||
| 132 | args => '--lower-limit 0', |
||
| 133 | vlabel => 'Syncs', |
||
| 134 | category => 'opentracker', |
||
| 135 | title => 'LiveSyncs', |
||
| 136 | info => 'OpenTracker LiveSync Requests', |
||
| 137 | }, |
||
| 138 | keys => [ 'Incoming', 'Outgoing' ], |
||
| 139 | datasrc => [ |
||
| 140 | { name => 'Incoming', label => 'Incoming Syncs', min => '0', type => 'COUNTER', info => 'number of Incoming Syncs', draw => 'AREA' },
|
||
| 141 | { name => 'Outgoing', label => 'Outgoing Syncs', min => '0', type => 'COUNTER', info => 'number of Outgoing Syncs', draw => 'LINE2' },
|
||
| 142 | ], |
||
| 143 | }; |
||
| 144 | # graph for tcp4 connections |
||
| 145 | $graphs{tcp4} = {
|
||
| 146 | config => {
|
||
| 147 | args => '--lower-limit 0', |
||
| 148 | vlabel => 'TCP4 Requests', |
||
| 149 | category => 'opentracker', |
||
| 150 | title => 'TCP4 Requests', |
||
| 151 | info => 'Current TCP4 Requests / Announces', |
||
| 152 | }, |
||
| 153 | keys => [ 'Requests', 'Announces' ], |
||
| 154 | datasrc => [ |
||
| 155 | { name => 'Requests', label => 'Requests', min => '0', type => 'COUNTER', info => 'number of tcp4 Requests', draw => 'AREA' },
|
||
| 156 | { name => 'Announces', label => 'Announces', min => '0', type => 'COUNTER', info => 'number of tcp4 Announces', draw => 'LINE2' },
|
||
| 157 | ], |
||
| 158 | }; |
||
| 159 | # graph for torrents |
||
| 160 | $graphs{torr} = {
|
||
| 161 | config => {
|
||
| 162 | args => '--lower-limit 0', |
||
| 163 | vlabel => '# of Torrents', |
||
| 164 | category => 'opentracker', |
||
| 165 | title => 'Torrents', |
||
| 166 | info => 'Current number of Torrents', |
||
| 167 | }, |
||
| 168 | keys => [ 'Torrents' ], |
||
| 169 | datasrc => [ |
||
| 170 | { name => 'Torrents', label => 'Torrents', min => '0', type => 'GAUGE', info => 'number of torrents', draw => 'AREA' },
|
||
| 171 | ], |
||
| 172 | }; |
||
| 173 | # graph for udp4 connections |
||
| 174 | $graphs{udp4} = {
|
||
| 175 | config => {
|
||
| 176 | args => '--lower-limit 0', |
||
| 177 | vlabel => 'UDP4 Requests', |
||
| 178 | category => 'opentracker', |
||
| 179 | title => 'UDP4 Requests', |
||
| 180 | info => 'Current UDP4 Requests / Announces', |
||
| 181 | }, |
||
| 182 | keys => [ 'Requests', 'Announces' ], |
||
| 183 | datasrc => [ |
||
| 184 | { name => 'Requests', label => 'Requests', min => '0', type => 'COUNTER', info => 'number of udp4 Requests', draw => 'AREA' },
|
||
| 185 | { name => 'Announces', label => 'Announces', min => '0', type => 'COUNTER', info => 'number of udp4 Announces', draw => 'LINE2' },
|
||
| 186 | ], |
||
| 187 | }; |
||
| 188 | |||
| 189 | =head1 Munin Checks |
||
| 190 | |||
| 191 | These checks look for config / autoconf / suggest params |
||
| 192 | |||
| 193 | =head2 Config Check |
||
| 194 | |||
| 195 | This block of code looks at the argument that is possibly supplied, |
||
| 196 | should it be config, it then checks to make sure the plugin |
||
| 197 | specified exists, assuming it does, it will run the do_config |
||
| 198 | subroutine for the plugin specified, otherwise it dies complaining |
||
| 199 | about an unknown plugin. |
||
| 200 | |||
| 201 | =cut |
||
| 202 | |||
| 203 | if (defined $ARGV[0] && $ARGV[0] eq 'config') {
|
||
| 204 | # Lets take the plugin from the execution name. |
||
| 205 | $0 =~ /opentracker_(.+)*/; |
||
| 206 | my $plugin = $1; |
||
| 207 | # And lets make sure we have a plugin called that. |
||
| 208 | die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
|
||
| 209 | # Now lets go ahead and print out our config. |
||
| 210 | print_config($plugin); |
||
| 211 | exit 0; |
||
| 212 | } |
||
| 213 | |||
| 214 | =head2 Autoconf Check |
||
| 215 | |||
| 216 | This block of code looks at the argument that is possibly supplied, |
||
| 217 | should it be autoconf, we are going to print yes at this point since |
||
| 218 | we've already tested for our binary to exist and be executable, the |
||
| 219 | process will then exit. |
||
| 220 | |||
| 221 | =cut |
||
| 222 | |||
| 223 | if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
|
||
| 224 | # well we can execute the binary, so lets make sure we can curl opentracker |
||
| 225 | my $url = "http://".$host.":".$port.$uri."\?mode=version"; |
||
| 226 | my $ua = LWP::UserAgent->new; |
||
| 227 | $ua->timeout(15); |
||
| 228 | my $response = $ua->get($url); |
||
| 229 | if ($response->is_success) {
|
||
| 230 | print "yes\n"; |
||
| 231 | exit 0; |
||
| 232 | } else {
|
||
| 233 | print "no: unable to connect to url: $url\n"; |
||
| 234 | exit 1; |
||
| 235 | } |
||
| 236 | } |
||
| 237 | |||
| 238 | =head2 Suggest Check |
||
| 239 | |||
| 240 | This block of code looks at the argument that is possibly supplied, |
||
| 241 | should it be suggest, we are going to print the possible plugins |
||
| 242 | which can be specified. |
||
| 243 | |||
| 244 | =cut |
||
| 245 | |||
| 246 | if (defined $ARGV[0] && $ARGV[0] eq 'suggest') {
|
||
| 247 | # well we can execute the binary, so print possible plugin names |
||
| 248 | my @rootplugins = ('conn','peer','scrp','syncs','tcp4','torr','udp4');
|
||
| 249 | foreach my $plugin (@rootplugins) {
|
||
| 250 | print "$plugin\n"; |
||
| 251 | } |
||
| 252 | exit 0; |
||
| 253 | } |
||
| 254 | |||
| 255 | =head1 Subroutines |
||
| 256 | |||
| 257 | Begin Subroutine calls to output data / config information |
||
| 258 | |||
| 259 | =head2 fetch_output |
||
| 260 | |||
| 261 | This subroutine is the main call for printing data for the plugin. |
||
| 262 | No parameters are taken as this is the default call if no arguments |
||
| 263 | are supplied from the command line. |
||
| 264 | |||
| 265 | =cut |
||
| 266 | |||
| 267 | fetch_output(); |
||
| 268 | |||
| 269 | sub fetch_output {
|
||
| 270 | # Lets figure out what plugin they want to run, and check that it exists |
||
| 271 | $0 =~ /opentracker_(.+)*/; |
||
| 272 | my $plugin = $1; |
||
| 273 | die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
|
||
| 274 | # Lets print out the data for our plugin |
||
| 275 | print_output($plugin); |
||
| 276 | return; |
||
| 277 | } |
||
| 278 | |||
| 279 | =head2 print_output |
||
| 280 | |||
| 281 | This block of code prints out the return values for our graphs. It takes |
||
| 282 | one parameter $plugin. Returns when completed |
||
| 283 | |||
| 284 | $plugin; graph we are calling up to print data values for |
||
| 285 | |||
| 286 | Example: print_output($plugin); |
||
| 287 | |||
| 288 | =cut |
||
| 289 | |||
| 290 | sub print_output {
|
||
| 291 | # Lets get our plugin, set our graph information, and print for Munin to process |
||
| 292 | my ($plugin) = (@_); |
||
| 293 | my $graph = $graphs{$plugin};
|
||
| 294 | print "graph opentracker_$plugin\n"; |
||
| 295 | # Getting keys to pass to fetch_stats for data retrieval |
||
| 296 | # call up fetch_stats with the keys we just got. |
||
| 297 | my @keys = @{$graph->{keys}};
|
||
| 298 | fetch_stats($plugin,@keys); |
||
| 299 | # print the results for the keys with the name for Munin to process |
||
| 300 | foreach my $dsrc (@{$graph->{datasrc}}) {
|
||
| 301 | my $output = 0; |
||
| 302 | my %datasrc = %$dsrc; |
||
| 303 | while ( my ($key, $value) = each(%datasrc)) {
|
||
| 304 | next if ($key ne 'name'); |
||
| 305 | print "$dsrc->{name}.value $graph->{results}->{$value}\n";
|
||
| 306 | } |
||
| 307 | } |
||
| 308 | return; |
||
| 309 | } |
||
| 310 | |||
| 311 | =head2 print_config |
||
| 312 | |||
| 313 | This subroutine prints out the main config information for all of the graphs. |
||
| 314 | It takes one parameters, $plugin |
||
| 315 | |||
| 316 | $plugin; graph being called up to print config for |
||
| 317 | |||
| 318 | Example: print_config($plugin); |
||
| 319 | |||
| 320 | =cut |
||
| 321 | |||
| 322 | sub print_config {
|
||
| 323 | # Lets get our plugin and graph, after that print for Munin to process it. |
||
| 324 | my ($plugin) = (@_); |
||
| 325 | my $graph = $graphs{$plugin};
|
||
| 326 | print "graph opentracker_$plugin\n"; |
||
| 327 | # Lets print out graph's main config info. |
||
| 328 | my %graphconf = %{$graph->{config}};
|
||
| 329 | while ( my ($key, $value) = each(%graphconf)) {
|
||
| 330 | print "graph_$key $value\n"; |
||
| 331 | } |
||
| 332 | # Lets print our graphs per graph config info. |
||
| 333 | foreach my $dsrc (@{$graph->{datasrc}}) {
|
||
| 334 | my %datasrc = %$dsrc; |
||
| 335 | while ( my ($key, $value) = each(%datasrc)) {
|
||
| 336 | next if ($key eq 'name'); |
||
| 337 | print "$dsrc->{name}.$key $value\n";
|
||
| 338 | } |
||
| 339 | } |
||
| 340 | return; |
||
| 341 | } |
||
| 342 | |||
| 343 | =head2 fetch_stats |
||
| 344 | |||
| 345 | This subroutine actually fetches data from opentracker with the plugin specified |
||
| 346 | It will then parse the data using the keys assigned in an array. |
||
| 347 | Two parameters are passed, $plugin and @keys, and it will return when complete. |
||
| 348 | |||
| 349 | $plugin; graph we are calling up, we use this to store the results in the hash |
||
| 350 | for easy recall later. |
||
| 351 | @keys; keys we want the values for from opentracker stats url. |
||
| 352 | |||
| 353 | Example: fetch_stats($plugin,@keys); |
||
| 354 | |||
| 355 | =cut |
||
| 356 | |||
| 357 | sub fetch_stats {
|
||
| 358 | # Lets get our current plugin and list of keys we want info for, as well as reference our graph |
||
| 359 | my ($plugin,@keys) = (@_); |
||
| 360 | my $graph = $graphs{$plugin};
|
||
| 361 | # Lets create our url to fetch |
||
| 362 | my $url = "http://".$host.":".$port.$uri."\?mode=".$plugin; |
||
| 363 | my $ua = LWP::UserAgent->new; |
||
| 364 | $ua->timeout(15); |
||
| 365 | my $response = $ua->get($url); |
||
| 366 | # Lets print some info since we got back some info |
||
| 367 | if ($response->is_success) {
|
||
| 368 | my @tmparray = split("\n",$response->content);
|
||
| 369 | foreach my $key (@keys) {
|
||
| 370 | my $value = shift(@tmparray); |
||
| 371 | $graph->{results}->{$key} = $value;
|
||
| 372 | } |
||
| 373 | } else {
|
||
| 374 | print "Unable to Fetch data from URL: $url\n"; |
||
| 375 | exit 1; |
||
| 376 | } |
||
| 377 | return; |
||
| 378 | } |
