root / plugins / network / bird @ 99542938
Historique | Voir | Annoter | Télécharger (6,86 ko)
| 1 | 5383f21d | luben | #!/usr/bin/perl |
|---|---|---|---|
| 2 | use IO::Socket::UNIX; |
||
| 3 | use Munin::Plugin; |
||
| 4 | use strict; |
||
| 5 | use warnings; |
||
| 6 | use v5.10; |
||
| 7 | |||
| 8 | =head1 NAME |
||
| 9 | |||
| 10 | bird - Munin multigraph plugin to monitor BIRD routing daemon activity |
||
| 11 | |||
| 12 | =head1 APPLICABLE SYSTEMS |
||
| 13 | |||
| 14 | Every system with running bird |
||
| 15 | |||
| 16 | =head1 CONFIGURATION |
||
| 17 | |||
| 18 | The plugin must run with a user or group that could connect to bird |
||
| 19 | control socket. |
||
| 20 | |||
| 21 | This configuration snipplet is an example with the defaults: |
||
| 22 | |||
| 23 | [bird] |
||
| 24 | user root |
||
| 25 | protocols BGP |
||
| 26 | socket /var/run/bird.ctl |
||
| 27 | |||
| 28 | =head1 USAGE |
||
| 29 | |||
| 30 | Link this plugin to /etc/munin/plugins/ and restart the munin-node. |
||
| 31 | |||
| 32 | =head1 MAGIC MARKERS |
||
| 33 | |||
| 34 | #%# family=auto |
||
| 35 | #%# capabilities=autoconf |
||
| 36 | |||
| 37 | =head1 BUGS |
||
| 38 | |||
| 39 | Not known |
||
| 40 | |||
| 41 | =head1 AUTHOR |
||
| 42 | |||
| 43 | Luben Karavelov (karavelov at mail.bg) |
||
| 44 | |||
| 45 | =head1 LICENSE |
||
| 46 | |||
| 47 | Same as perl |
||
| 48 | |||
| 49 | =cut |
||
| 50 | |||
| 51 | need_multigraph(); |
||
| 52 | my $protocols = [ split(/ /, $ENV{'protocols'} || 'BGP') ];
|
||
| 53 | my $socket = $ENV{'socket'} || '/var/run/bird.ctl';
|
||
| 54 | |||
| 55 | sub get_stats {
|
||
| 56 | state $stats; |
||
| 57 | return $stats if defined $stats; |
||
| 58 | |||
| 59 | my $bird_ctl = IO::Socket::UNIX->new( |
||
| 60 | Type => SOCK_STREAM, |
||
| 61 | Peer => $socket |
||
| 62 | ) or die $!; |
||
| 63 | |||
| 64 | my ($protocol,$name); |
||
| 65 | while (<$bird_ctl>) {
|
||
| 66 | given($_) {
|
||
| 67 | when (/1002-(\w+)\s+(\w+)\s+.*/) {
|
||
| 68 | ($name, $protocol) = ($1,$2); |
||
| 69 | next unless $protocol ~~ $protocols; |
||
| 70 | $stats->{$name}->{protocol} = $protocol;
|
||
| 71 | } |
||
| 72 | when (/^0001 /) {
|
||
| 73 | print $bird_ctl "show protocols all\n"; |
||
| 74 | next; |
||
| 75 | } |
||
| 76 | when (/^0000 /) {
|
||
| 77 | last; |
||
| 78 | } |
||
| 79 | when (/^1002- /) {
|
||
| 80 | print; |
||
| 81 | } |
||
| 82 | when (/^1006-\s+Description:\s+(.+)$/){
|
||
| 83 | next unless $protocol ~~ $protocols; |
||
| 84 | $stats->{$name}->{title} = $1;
|
||
| 85 | } |
||
| 86 | when (/^\s+Routes:\s+(\d+)\s+imported,\s+(\d+)\s+exported,\s+(\d+)\s+preferred$/){
|
||
| 87 | next unless $protocol ~~ $protocols; |
||
| 88 | $stats->{$name}->{imported} = $1;
|
||
| 89 | $stats->{$name}->{exported} = $2;
|
||
| 90 | $stats->{$name}->{preferred} = $3;
|
||
| 91 | } |
||
| 92 | # received rejected filtered ignored accepted |
||
| 93 | when (/^\s+(Import|Export)\s(updates|withdraws):\s+(\d+|-+)\s+(\d+|-+)\s+(\d+|-+)\s+(\d+|-+)\s+(\d+|-+)$/){
|
||
| 94 | next unless $protocol ~~ $protocols; |
||
| 95 | $stats->{$name}->{ lc("$1_$2_received") } = $3;
|
||
| 96 | $stats->{$name}->{ lc("$1_$2_rejected") } = $4;
|
||
| 97 | $stats->{$name}->{ lc("$1_$2_filtered") } = $5;
|
||
| 98 | $stats->{$name}->{ lc("$1_$2_ignored" ) } = $6;
|
||
| 99 | $stats->{$name}->{ lc("$1_$2_accepted") } = $7;
|
||
| 100 | } |
||
| 101 | when (/^$/) {
|
||
| 102 | undef $protocol; |
||
| 103 | undef $name; |
||
| 104 | } |
||
| 105 | } |
||
| 106 | } |
||
| 107 | $bird_ctl->close; |
||
| 108 | return $stats; |
||
| 109 | } |
||
| 110 | |||
| 111 | sub autoconf {
|
||
| 112 | if (-S $socket) {
|
||
| 113 | say 'yes'; |
||
| 114 | exit 0; |
||
| 115 | } else {
|
||
| 116 | say 'no'; |
||
| 117 | exit 1; |
||
| 118 | } |
||
| 119 | } |
||
| 120 | |||
| 121 | sub config {
|
||
| 122 | my $stats = get_stats; |
||
| 123 | while ( my ($name,$proto) = each %$stats) {
|
||
| 124 | print <<HEREDOC; |
||
| 125 | multigraph ${name}_routes
|
||
| 126 | graph_title $proto->{title} routes
|
||
| 127 | graph_args --base 1000 |
||
| 128 | graph_vlabel routes |
||
| 129 | graph_category bird |
||
| 130 | exported.label Exported routes |
||
| 131 | exported.type GAUGE |
||
| 132 | exported.info Exported routes |
||
| 133 | exported.min 0 |
||
| 134 | exported.draw LINE1 |
||
| 135 | imported.label Imported routes |
||
| 136 | imported.type GAUGE |
||
| 137 | imported.info Impored routes |
||
| 138 | imported.min 0 |
||
| 139 | imported.draw LINE1 |
||
| 140 | preferred.label Preferred routes |
||
| 141 | preferred.type GAUGE |
||
| 142 | preferred.info Preferred routes |
||
| 143 | preferred.min 0 |
||
| 144 | preferred.draw LINE1 |
||
| 145 | multigraph ${name}_activity
|
||
| 146 | graph_title $proto->{title} activity
|
||
| 147 | graph_args --base 1000 |
||
| 148 | graph_vlabel routes per second |
||
| 149 | graph_category bird |
||
| 150 | import_updates_received.label Import updates received |
||
| 151 | import_updates_received.type DERIVE |
||
| 152 | import_updates_received.draw LINE1 |
||
| 153 | import_updates_rejected.label Import updates rejected |
||
| 154 | import_updates_rejected.type DERIVE |
||
| 155 | import_updates_rejected.draw LINE1 |
||
| 156 | import_updates_filtered.label Import updates filtered |
||
| 157 | import_updates_filtered.type DERIVE |
||
| 158 | import_updates_filtered.draw LINE1 |
||
| 159 | import_updates_ignored.label Import updates ignored |
||
| 160 | import_updates_ignored.type DERIVE |
||
| 161 | import_updates_ignored.draw LINE1 |
||
| 162 | import_updates_accepted.label Import updates accepted |
||
| 163 | import_updates_accepted.type DERIVE |
||
| 164 | import_updates_accepted.draw LINE1 |
||
| 165 | import_withdraws_received.label Import withdraws_received |
||
| 166 | import_withdraws_received.type DERIVE |
||
| 167 | import_withdraws_received.draw LINE1 |
||
| 168 | import_withdraws_rejected.label Import withdraws rejected |
||
| 169 | import_withdraws_rejected.type DERIVE |
||
| 170 | import_withdraws_rejected.draw LINE1 |
||
| 171 | import_withdraws_ignored.label Import withdraws ignored |
||
| 172 | import_withdraws_ignored.type DERIVE |
||
| 173 | import_withdraws_ignored.draw LINE1 |
||
| 174 | import_withdraws_accepted.label Import withdraws accepted |
||
| 175 | import_withdraws_accepted.type DERIVE |
||
| 176 | import_withdraws_accepted.draw LINE1 |
||
| 177 | export_updates_received.label Export updates received |
||
| 178 | export_updates_received.type DERIVE |
||
| 179 | export_updates_received.draw LINE1 |
||
| 180 | export_updates_rejected.label Export updates rejected |
||
| 181 | export_updates_rejected.type DERIVE |
||
| 182 | export_updates_rejected.draw LINE1 |
||
| 183 | export_updates_filtered.label Export updates filtered |
||
| 184 | export_updates_filtered.type DERIVE |
||
| 185 | export_updates_filtered.draw LINE1 |
||
| 186 | export_updates_accepted.label Export updates accepted |
||
| 187 | export_updates_accepted.type DERIVE |
||
| 188 | export_updates_accepted.draw LINE1 |
||
| 189 | export_withdraws_received.draw LINE1 |
||
| 190 | export_withdraws_received.label Export withdraws received |
||
| 191 | export_withdraws_received.type DERIVE |
||
| 192 | export_withdraws_accepted.label Export withdraws accepted |
||
| 193 | export_withdraws_accepted.type DERIVE |
||
| 194 | export_withdraws_accepted.draw LINE1 |
||
| 195 | HEREDOC |
||
| 196 | } |
||
| 197 | } |
||
| 198 | |||
| 199 | sub fetch {
|
||
| 200 | my $stats = get_stats; |
||
| 201 | while ( my ($name,$proto) = each %$stats) {
|
||
| 202 | print <<HEREDOC; |
||
| 203 | multigraph ${name}_routes
|
||
| 204 | exported.value $proto->{exported}
|
||
| 205 | imported.value $proto->{imported}
|
||
| 206 | preferred.value $proto->{preferred}
|
||
| 207 | multigraph ${name}_activity
|
||
| 208 | import_updates_received.value $proto->{import_updates_received}
|
||
| 209 | import_updates_rejected.value $proto->{import_updates_rejected}
|
||
| 210 | import_updates_filtered.value $proto->{import_updates_filtered}
|
||
| 211 | import_updates_ignored.value $proto->{import_updates_ignored}
|
||
| 212 | import_updates_accepted.value $proto->{import_updates_accepted}
|
||
| 213 | import_withdraws_received.value $proto->{import_withdraws_received}
|
||
| 214 | import_withdraws_rejected.value $proto->{import_withdraws_rejected}
|
||
| 215 | import_withdraws_ignored.value $proto->{import_withdraws_ignored}
|
||
| 216 | import_withdraws_accepted.value $proto->{import_withdraws_accepted}
|
||
| 217 | export_updates_received.value $proto->{export_updates_received}
|
||
| 218 | export_updates_rejected.value $proto->{export_updates_rejected}
|
||
| 219 | export_updates_filtered.value $proto->{export_updates_filtered}
|
||
| 220 | export_updates_accepted.value $proto->{export_updates_accepted}
|
||
| 221 | export_withdraws_received.value $proto->{export_withdraws_received}
|
||
| 222 | export_withdraws_accepted.value $proto->{export_withdraws_accepted}
|
||
| 223 | HEREDOC |
||
| 224 | } |
||
| 225 | } |
||
| 226 | |||
| 227 | given ($ARGV[0]) {
|
||
| 228 | when ('autoconf') { autoconf }
|
||
| 229 | when ('config') { config }
|
||
| 230 | default { fetch }
|
||
| 231 | } |
