1########################################################################## 2# INN module for innreport (3.*). 3# 4# $Id: innreport_inn.pm 10442 2020-12-09 21:04:31Z iulius $ 5# 6# Sample file tested with INN 2.5, 2.4, 2.3, 2.2, 1.7.2 and 1.5.1. 7# 8# (c) 1997-2001 by Fabien Tassin <fta@sofaraway.org>. 9# See innreport for more information. 10# 11# Version 3.1.0. 12# 13########################################################################## 14 15# TODO: add the map file. 16 17package innreport_inn; 18use strict; 19 20my $MIN = 1E10; 21my $MAX = -1; 22 23my %ctlinnd = ('a', 'addhist', 'D', 'allow', 24 'b', 'begin', 'c', 'cancel', 25 'u', 'changegroup', 'd', 'checkfile', 26 'e', 'drop', 'f', 'flush', 27 'g', 'flushlogs', 'h', 'go', 28 'i', 'hangup', 's', 'mode', 29 'j', 'name', 'k', 'newgroup', 30 'l', 'param', 'm', 'pause', 31 'v', 'readers', 'H', 'stathist', 32 'C', 'reject', 'o', 'reload', 33 'n', 'renumber', 'z', 'reserve', 34 'p', 'rmgroup', 'A', 'send', 35 'q', 'shutdown', 'B', 'signal', 36 'r', 'throttle', 'w', 'trace', 37 'x', 'xabort', 'y', 'xexec', 38 'E', 'logmode', 'F', 'feedinfo', 39 'S', 'status', 'P', 'perl', 40 'L', 'lowmark', 'Y', 'python', 41 'Z', 'timer'); 42 43my %timer_names = (idle => 'idle', 44 hishave => 'history lookup', 45 hisgrep => 'history grep', 46 hiswrite => 'history write', 47 hissync => 'history sync', 48 nntpread => 'nntp read', 49 artparse => 'article parse', 50 artclean => 'article cleanup', 51 artwrite => 'article write', 52 artcncl => 'article cancel', 53 artlog => 'article logging', 54 sitesend => 'site send', 55 overv => 'overview write', 56 perl => 'perl filter', 57 python => 'python filter', 58 datamove => 'data move' 59); 60 61my %innfeed_timer_names = ( 62 'idle' => 'idle', 63 'blstats' => 'backlog stats', 64 'stsfile' => 'status file', 65 'newart' => 'article new', 66 'prepart' => 'article prepare', 67 'readart' => 'article read', 68 'read' => 'data read', 69 'write' => 'data write', 70 'cb' => 'callbacks', 71); 72 73my %nnrpd_timer_names = ( 74 'idle' => 'idle', 75 'newnews' => 'newnews', 76); 77 78our %batcher_articles; 79our %batcher_bytes; 80our %batcher_elapsed; 81our %batcher_offered; 82our %cnfsstat; 83our %cnfsstat_cycles; 84our %cnfsstat_rate; 85our %cnfsstat_samples; 86our %cnfsstat_size; 87our %cnfsstat_time; 88our %cnfsstat_used; 89our %controlchan_doit; 90our %controlchan_ihave_site; 91our %controlchan_new; 92our %controlchan_ok; 93our %controlchan_other; 94our %controlchan_rm; 95our %controlchan_sendme_site; 96our %controlchan_skippgp; 97our %controlchan_who; 98our %inn_badart; 99our %innd_accepted; 100our %innd_accepted_sum; 101our %innd_bad_command; 102our %innd_bad_ihave; 103our %innd_bad_msgid; 104our %innd_bad_newsgroup; 105our %innd_bad_sendme; 106our %innd_blocked; 107our %innd_cache; 108our %innd_changegroup; 109our %innd_connect; 110our %innd_connect_sum; 111our %innd_control; 112our %innd_duplicated_size; 113our %innd_duplicated_size_sum; 114our %innd_filter_perl; 115our %innd_filter_python; 116our %innd_his; 117our %innd_huge; 118our %innd_max_conn; 119our %innd_misc; 120our %innd_misc_stat; 121our %innd_newgroup; 122our %innd_no_colon_space; 123our %innd_no_permission; 124our %innd_offered; 125our %innd_offered_size; 126our %innd_offered_size_sum; 127our %innd_offered_sum; 128our %innd_others; 129our %innd_posted_future; 130our %innd_refused; 131our %innd_refused_sum; 132our %innd_rejected; 133our %innd_rejected_size; 134our %innd_rejected_size_sum; 135our %innd_rejected_sum; 136our %innd_rmgroup; 137our %innd_seconds; 138our %innd_seconds_sum; 139our %innd_stored_size; 140our %innd_stored_size_sum; 141our %innd_strange_strings; 142our %innd_time_max; 143our %innd_time_min; 144our %innd_time_num; 145our %innd_time_time; 146our $innd_time_times; 147our %innd_too_many_connects_per_minute; 148our %inn_duplicate; 149our %innfeed_accepted; 150our %innfeed_accepted_size; 151our %innfeed_connect; 152our %innfeed_missing; 153our %innfeed_offered; 154our %innfeed_refused; 155our %innfeed_rejected; 156our %innfeed_rejected_size; 157our %innfeed_seconds; 158our %innfeed_shrunk; 159our %innfeed_spooled; 160our %innfeed_time_max; 161our %innfeed_time_min; 162our %innfeed_time_num; 163our %innfeed_time_time; 164our $innfeed_time_times; 165our %inn_flow; 166our %inn_flow_labels; 167our %inn_flow_size; 168our $inn_flow_size_total; 169our %inn_flow_time; 170our $inn_flow_total; 171our %inn_linecount; 172our %inn_site_path; 173our %inn_tooold; 174our %inn_unapproved; 175our %inn_unapproved_g; 176our %inn_uw_dist; 177our %inn_uw_dist_s; 178our %inn_uw_ng; 179our %inn_uw_ng_s; 180our %inn_uw_site; 181our %innxmit_accepted; 182our %innxmit_accepted_size; 183our %innxmit_afail_host; 184our %innxmit_badart; 185our %innxmit_cfail_host; 186our %innxmit_crefused; 187our %innxmit_duplicate; 188our %innxmit_expire; 189our %innxmit_hiload; 190our %innxmit_ihfail; 191our %innxmit_linecount; 192our %innxmit_missing; 193our %innxmit_nospace; 194our %innxmit_offered; 195our %innxmit_others; 196our %innxmit_refused; 197our %innxmit_rejected; 198our %innxmit_rejected_size; 199our %innxmit_site; 200our %innxmit_times; 201our %innxmit_tooold; 202our %innxmit_unapproved; 203our %innxmit_unapproved_g; 204our %innxmit_uw_dist; 205our %innxmit_uw_dist_s; 206our %innxmit_uw_ng; 207our %innxmit_uw_ng_s; 208our %innxmit_uw_site; 209our %nnrpd_articles; 210our %nnrpd_auth; 211our %nnrpd_bytes; 212our %nnrpd_connect; 213our %nnrpd_curious; 214our %nnrpd_dom_articles; 215our %nnrpd_dom_bytes; 216our %nnrpd_dom_connect; 217our %nnrpd_dom_groups; 218our %nnrpd_dom_no_permission; 219our %nnrpd_dom_post_error; 220our %nnrpd_dom_post_ok; 221our %nnrpd_dom_post_rej; 222our %nnrpd_dom_reset_peer; 223our %nnrpd_dom_timeout; 224our %nnrpd_dom_times; 225our %nnrpd_dom_unrecognized; 226our %nnrpd_gethostbyaddr; 227our %nnrpd_group; 228our %nnrpd_groups; 229our %nnrpd_hierarchy; 230our %nnrpd_no_permission; 231our %nnrpd_post_error; 232our %nnrpd_post_ok; 233our %nnrpd_post_rej; 234our %nnrpd_reset_peer; 235our %nnrpd_resource_elapsed; 236our %nnrpd_resource_idle; 237our %nnrpd_resource_system; 238our %nnrpd_resource_user; 239our %nnrpd_sys_times; 240our %nnrpd_time_max; 241our %nnrpd_time_min; 242our %nnrpd_time_num; 243our %nnrpd_timeout; 244our %nnrpd_times; 245our %nnrpd_time_time; 246our $nnrpd_time_times; 247our %nnrpd_unrecogn_cmd; 248our %nnrpd_unrecognized; 249our %nnrpd_usr_times; 250our %nntplink_accepted; 251our %nntplink_auth; 252our %nntplink_bpipe; 253our %nntplink_connects; 254our %nntplink_eof; 255our %nntplink_expire; 256our %nntplink_fail; 257our %nntplink_failed; 258our %nntplink_fake_connects; 259our %nntplink_hiload; 260our %nntplink_ihfail; 261our %nntplink_nospace; 262our %nntplink_offered; 263our %nntplink_rejected; 264our %nntplink_selecterr; 265our %nntplink_site; 266our %nntplink_sockerr; 267our %nntplink_times; 268our %nocem_badsigs; 269our %nocem_goodsigs; 270our $nocem_lastid; 271our $nocem_newids; 272our %nocem_newids; 273our $nocem_totalbad; 274our $nocem_totalgood; 275our $nocem_totalids; 276our %nocem_totalids; 277our %rnews_bogus_date; 278our %rnews_bogus_dist; 279our %rnews_bogus_ng; 280our $rnews_duplicate; 281our %rnews_host; 282our $rnews_linecount; 283our %rnews_misc; 284our $rnews_no_colon_space; 285our %rnews_rejected; 286our $rnews_too_old; 287our %rnews_unapproved; 288our $server; 289 290# init innd timer 291foreach (values %timer_names) { 292 $innd_time_min{$_} = $MIN; 293 $innd_time_max{$_} = $MAX; 294 $innd_time_time{$_} = 0; # to avoid a warning... Perl < 5.004 295 $innd_time_num{$_} = 0; # ... 296} 297$innd_time_times = 0; # ... 298 299# init innfeed timer 300foreach (values %innfeed_timer_names) { 301 $innfeed_time_min{$_} = $MIN; 302 $innfeed_time_max{$_} = $MAX; 303 $innfeed_time_time{$_} = 0; # to avoid a warning... Perl < 5.004 304 $innfeed_time_num{$_} = 0; # ... 305} 306$innfeed_time_times = 0; # ... 307 308# init nnrpd timer 309foreach (values %nnrpd_timer_names) { 310 $nnrpd_time_min{$_} = $MIN; 311 $nnrpd_time_max{$_} = $MAX; 312 $nnrpd_time_time{$_} = 0; # to avoid a warning... Perl < 5.004 313 $nnrpd_time_num{$_} = 0; # ... 314} 315$nnrpd_time_times = 0; # ... 316 317# collect: Used to collect the data. 318sub collect($$$$$$) { 319 my ($day, $hour, $prog, $res, $left, $CASE_SENSITIVE) = @_; 320 321 return 1 if $left =~ /Reading config from (\S+)$/o; 322 323 ######## 324 ## inn (from the "news" log file - not from "news.notice") 325 ## 326 if ($prog eq "inn") { 327 # accepted article 328 if ($res =~ m/[\+j]/o) { 329 $hour =~ s/:.*$//o; 330 $inn_flow{"$day $hour"}++; 331 $inn_flow_total++; 332 333 # Memorize the size. This can only be done with INN >= 1.5xx and 334 # DO_LOG_SIZE = DO. 335 336 # server <msg-id> size [feeds] 337 # or 338 # server <msg-id> (filename) size [feeds] 339 340 my ($s) = $left =~ /^\S+ \S+ (?:\(\S+\) )?(\d+)(?: |$)/o; 341 if ($s) { 342 $inn_flow_size{"$day $hour"} += $s; 343 $inn_flow_size_total += $s; 344 } 345 return 1; 346 } 347 348 # 437 Duplicate article 349 if ($left =~ /(\S+) <[^>]+> (?:437|439) Duplicate(?: article)?$/o) { 350 my $server = $1; 351 $server = lc $server unless $CASE_SENSITIVE; 352 $inn_badart{$server}++; 353 $inn_duplicate{$server}++; 354 return 1; 355 } 356 # 437 Unapproved for 357 if ($left =~ /(\S+) <[^>]+> (?:437|439) Unapproved for \"([^\"]+)\"$/o) { 358 my ($server, $group) = ($1, $2); 359 $server = lc $server unless $CASE_SENSITIVE; 360 $inn_badart{$server}++; 361 $inn_unapproved{$server}++; 362 $inn_unapproved_g{$group}++; 363 return 1; 364 } 365 # 437 Too old -- ... 366 if ($left =~ /(\S+) <[^>]+> (?:437|439) Too old -- /o) { 367 my $server = $1; 368 $server = lc $server unless $CASE_SENSITIVE; 369 $inn_badart{$server}++; 370 $inn_tooold{$server}++; 371 return 1; 372 } 373 # 437 Unwanted site ... in path 374 if ($left =~ /(\S+) <[^>]+> (?:437|439) Unwanted site (\S+) in path$/o) { 375 my ($server, $site) = ($1, $2); 376 $server = lc $server unless $CASE_SENSITIVE; 377 $inn_badart{$server}++; 378 $inn_uw_site{$server}++; 379 $inn_site_path{$site}++; 380 return 1; 381 } 382 # 437 Unwanted newsgroup "..." 383 if ($left =~ /(\S+) <[^>]+> (?:437|439) Unwanted newsgroup \"(\S+)\"$/o) { 384 my ($server, $group) = ($1, $2); 385 ($group) = split(/,/, $group); 386 $server = lc $server unless $CASE_SENSITIVE; 387 $inn_badart{$server}++; 388 $inn_uw_ng_s{$server}++; 389 $inn_uw_ng{$group}++; 390 return 1; 391 } 392 # 437 Unwanted distribution "..." 393 if ($left =~ /(\S+) <[^>]+> (?:437|439) Unwanted distribution \"(\S+)\"$/o) { 394 my ($server, $dist) = ($1, $2); 395 $server = lc $server unless $CASE_SENSITIVE; 396 $inn_badart{$server}++; 397 $inn_uw_dist_s{$server}++; 398 $inn_uw_dist{$dist}++; 399 return 1; 400 } 401 # 437 Linecount x != y +- z 402 if ($left =~ /(\S+) <[^>]+> (?:437|439) Linecount/o) { 403 my $server = $1; 404 $server = lc $server unless $CASE_SENSITIVE; 405 $inn_badart{$server}++; 406 $inn_linecount{$server}++; 407 return 1; 408 } 409 # 437 No colon-space in "xxxx" header 410 if ($left =~ /(\S+) <[^>]+> (?:437|439) No colon-space in \"[^\"]+\" header/o) { 411 my $server = $1; 412 $server = lc $server unless $CASE_SENSITIVE; 413 $inn_badart{$server}++; 414 $innd_others{$server}++; 415 $innd_no_colon_space{$server}++; 416 return 1; 417 } 418 # 437 Article injected or posted in the future -- "xxxxx" 419 if ($left =~ /(\S+) <[^>]+> (?:437|439) Article injected or posted in the future -- \"[^\"]+\"/o) { 420 my $server = $1; 421 $server = lc $server unless $CASE_SENSITIVE; 422 $innd_posted_future{$server}++; 423 $innd_others{$server}++; 424 $inn_badart{$server}++; 425 return 1; 426 } 427 # Article accepted but includes "....." 428 if ($left =~ /(\S+) <[^>]+> Article accepted but includes/o) { 429 my $server = $1; 430 $server = lc $server unless $CASE_SENSITIVE; 431 $innd_strange_strings{$server}++; 432 $innd_others{$server}++; 433 $inn_badart{$server}++; 434 return 1; 435 } 436 # Cancelling <...> 437 if ($left =~ /(\S+) <[^>]+> Cancelling/o) { 438 return 1; 439 } 440 # all others are just counted as "Other" 441 if ($left =~ /(\S+) /o) { 442 my $server = $1; 443 $server = lc $server unless $CASE_SENSITIVE; 444 $inn_badart{$server}++; 445 $innd_others{$server}++; 446 return 1; 447 } 448 } 449 450 ######## 451 ## innd 452 if ($prog eq "innd") { 453 ## Note for innd logs: 454 ## there's a lot of entries detected but still not used 455 ## (because of a lack of interest). 456 457 # think it's a dotquad 458 return 1 if $left =~ /^think it\'s a dotquad$/o; 459 if ($left =~ /^SERVER /o) { 460 # SERVER perl filtering enabled 461 return 1 if $left =~ /^SERVER perl filtering enabled$/o; 462 # SERVER perl filtering disabled 463 return 1 if $left =~ /^SERVER perl filtering disabled$/o; 464 # SERVER Python filtering enabled 465 return 1 if $left =~ /^SERVER Python filtering enabled$/o; 466 # SERVER Python filtering disabled 467 return 1 if $left =~ /^SERVER Python filtering disabled$/o; 468 # SERVER cancelled +id 469 return 1 if $left =~ /^SERVER cancelled /o; 470 } 471 # Python filter 472 return 1 if $left =~ /^defined python methods$/o; 473 return 1 if $left =~ /^reloading pyfilter$/o; 474 return 1 if $left =~ /^reloaded pyfilter OK$/o; 475 return 1 if $left =~ /^python interpreter initialized OK$/o; 476 return 1 if $left =~ /^python is not initialized$/o; 477 return 1 if $left =~ /^pyfilter .+ not installed$/o; 478 return 1 if $left =~ /^python method \w+ not found$/o; 479 return 1 if $left =~ /^python: First load, so I can do initialization stuff\.$/o; 480 return 1 if $left =~ /^python: filter_before_reload executing\.\.\.$/o; 481 return 1 if $left =~ /^python: I\'m just reloading, so skip the formalities\.$/o; 482 return 1 if $left =~ /^python: spamfilter successfully hooked into INN$/o; 483 return 1 if $left =~ /^python: state change from \w+ to \w+ - /o; 484 return 1 if $left =~ /^python: filter_close running, bye!$/o; 485 # rejecting[perl] 486 if ($left =~ /^rejecting\[perl\] <[^>]+> \d+ (.*)/o) { 487 $innd_filter_perl{$1}++; 488 return 1; 489 } 490 # rejecting[python] 491 if ($left =~ /^rejecting\[python\] <[^>]+> \d+ (.*)/o) { 492 $innd_filter_python{$1}++; 493 return 1; 494 } 495 # closed lost 496 return 1 if $left =~ /^\S+ closed lost \d+/o; 497 # new control command 498 if ($left =~ /^ctlinnd command (\w)(:.*)?/o) { 499 my $command = $1; 500 my $cmd = $ctlinnd{$command}; 501 $cmd = $command unless $cmd; 502 return 1 if $cmd eq 'flush'; # to avoid a double count 503 $innd_control{"$cmd"}++; 504 return 1; 505 } 506 # old control command (by letter) 507 if ($left =~ /^(\w)$/o) { 508 my $command = $1; 509 my $cmd = $ctlinnd{$command}; 510 $cmd = $command unless $cmd; 511 return 1 if $cmd eq 'flush'; # to avoid a double count 512 $innd_control{"$cmd"}++; 513 return 1; 514 } 515 # old control command (letter + reason) 516 if ($left =~ /^(\w):.*$/o) { 517 my $command = $1; 518 my $cmd = $ctlinnd{$command}; 519 $cmd = $command unless $cmd; 520 return 1 if $cmd eq 'flush'; # to avoid a double count 521 $innd_control{"$cmd"}++; 522 return 1; 523 } 524 # opened 525 return 1 if $left =~ /\S+ opened \S+:\d+:file$/o; 526 # buffered 527 return 1 if $left =~ /\S+ buffered$/o; 528 # spawned 529 return 1 if $left =~ /\S+ spawned \S+:\d+:proc:\d+$/o; 530 return 1 if $left =~ /\S+ spawned \S+:\d+:file$/o; 531 # running 532 return 1 if $left =~ /\S+ running$/o; 533 # sleeping 534 if ($left =~ /(\S+):\d+:proc:\d+ sleeping$/o) { 535 my $server = $1; 536 $server = lc $server unless $CASE_SENSITIVE; 537 $innd_blocked{$server}++; 538 return 1; 539 } 540 # blocked sleeping 541 if ($left =~ /(\S+):\d+:proc:\d+ blocked sleeping/o) { 542 my $server = $1; 543 $server = lc $server unless $CASE_SENSITIVE; 544 $innd_blocked{$server}++; 545 return 1; 546 } 547 if ($left =~ /(\S+):\d+ blocked sleeping/o) { 548 my $server = $1; 549 $server = lc $server unless $CASE_SENSITIVE; 550 $innd_blocked{$server}++; 551 return 1; 552 } 553 # restarted 554 return 1 if $left =~ m/^\S+ restarted$/o; 555 # starting 556 return 1 if $left =~ m/^\S+ starting$/o; 557 # readclose 558 return 1 if $left =~ m/^\S+:\d+ readclose+$/o; 559 # rejected 502 560 if ($left =~ m/^(\S+) rejected 502$/) { 561 my $server = $1; 562 $server = lc $server unless $CASE_SENSITIVE; 563 $innd_no_permission{$server}++; 564 return 1; 565 } 566 # rejected 505 567 if ($left =~ m/^(\S+) rejected 505$/) { 568 my $server = $1; 569 $server = lc $server unless $CASE_SENSITIVE; 570 $innd_too_many_connects_per_minute{$server}++; 571 return 1; 572 } 573 # connected 574 # 575 # Record <server>:<channel> instead of just <server> as otherwise we may 576 # miss some persistent connection newsfeeds that in any given innreport 577 # reporting period may not record any connect entries. We'll accumulate 578 # these into totals at the end of processing. 579 if ($left =~ /^(\S+) connected (\d+)/o) { 580 my $server = "$1:$2"; 581 $server = lc $server unless $CASE_SENSITIVE; 582 $innd_connect{$server}++; 583 return 1; 584 } 585 586 # logstatus (information written in inn_status.html) 587 return 1 if ($left =~ /\S+ status seconds \d+ accepted \d+ refused \d+ rejected \d+ duplicate \d+ accepted size \d+ duplicate size \d+(?: rejected size \d+)?$/o); 588 589 # closed/checkpoint (with times) 590 # 591 # Add all checkpoints. They contain stats generated since the last 592 # checkpoint. 593 # On a closed, a checkpoint is generated by innd. It is therefore 594 # useless to take into account a line corresponding to a closed status. 595 if ($left =~ /(\S+:\d+) (checkpoint|closed) seconds (\d+) accepted (\d+) refused (\d+) rejected (\d+) duplicate (\d+) accepted size (\d+) duplicate size (\d+)(?: rejected size (\d+))?$/o) { 596 my ($server, $status, $seconds, $accepted, $refused, $rejected, $duplicate, $accptsize, $dupsize, $rjctsize) = 597 ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10); 598 $server = lc $server unless $CASE_SENSITIVE; 599 600 if ($status eq 'checkpoint') { 601 $innd_seconds{$server} += $seconds; 602 $innd_accepted{$server} += $accepted; 603 $innd_refused{$server} += $refused; 604 $innd_rejected{$server} += $rejected; 605 $innd_stored_size{$server} += $accptsize; 606 $innd_duplicated_size{$server} += $dupsize; 607 $innd_rejected_size{$server} += ($rjctsize || 0); 608 } 609 return 1; 610 } 611 # closed (without times (?)) 612 return 1 if $left =~ m/\S+ closed$/o; 613 # closed (for a cancel feed - MODE CANCEL) 614 return 1 if $left =~ m/localhost:\d+ closed seconds \d+ cancels \d+$/o; 615 # flush 616 if ($left =~ /(\S+) flush$/o) { 617 $innd_control{"flush"}++; 618 return 1; 619 } 620 # flush-file 621 if ($left =~ /flush_file/) { 622 $innd_control{"flush_file"}++; 623 return 1; 624 } 625 # too many connections from site 626 if ($left =~ /too many connections from (\S+)/o) { 627 $innd_max_conn{$1}++; 628 return 1; 629 } 630 # overview exit 0 elapsed 23 pid 28461 631 return 1 if $left =~ m/\S+ exit \d+ .*$/o; 632 # internal rejecting huge article 633 if ($left =~ /(\S+) internal rejecting huge article/o) { 634 my $server = $1; 635 $server =~ s/:\d+$//o; 636 $server = lc $server unless $CASE_SENSITIVE; 637 $innd_huge{$server}++; 638 return 1; 639 } 640 # internal closing free channel 641 if ($left =~ /(\S+) internal closing free channel/o) { 642 $innd_misc{"Free channel"}++; 643 return 1; 644 } 645 # internal (other) 646 return 1 if $left =~ /\S+ internal/o; 647 # wakeup 648 return 1 if $left =~ /\S+ wakeup$/o; 649 # throttle 650 if ($left =~ /(\S+) throttled? /) { 651 $innd_control{"throttle"}++; 652 return 1; 653 } 654 # profile timer 655 # ME time X nnnn X(X) [...] 656 # The exact timers change from various versions of INN, so try to deal 657 # with this in a general fashion. 658 if ($left =~ m/^\S+\s+ # ME 659 time\s(\d+)\s+ # time 660 ((?:\S+\s\d+\(\d+\)\s*)+) # timer values 661 $/ox) { 662 $innd_time_times += $1; 663 my $timers = $2; 664 665 while ($timers =~ /(\S+) (\d+)\((\d+)\)\s*/g) { 666 my $name = $timer_names{$1} || $1; 667 $innd_time_time{$name} += $2; 668 if ($3) { 669 my $average = $2 / $3; 670 $innd_time_num{$name} += $3; 671 my $min = $innd_time_min{$name}; 672 $innd_time_min{$name} = $average 673 if (!defined($min) || $min > $average); 674 my $max = $innd_time_max{$name}; 675 $innd_time_max{$name} = $average 676 if (!defined($max) || $max < $average); 677 } 678 } 679 return 1; 680 } 681 # ME time xx idle xx(xx) [ bug ? a part of timer ?] 682 return 1 if $left =~ m/^ME time \d+ idle \d+\(\d+\)\s*$/o; 683 # ME HISstats x hitpos x hitneg x missed x dne 684 # 685 # from innd/his.c: 686 # HIShitpos: the entry existed in the cache and in history. 687 # HIShitneg: the entry existed in the cache but not in history. 688 # HISmisses: the entry was not in the cache, but was in the history file. 689 # HISdne: the entry was not in cache or history. 690 if ($left =~ m/^ME\ HISstats # ME HISstats 691 \ (\d+)\s+hitpos # hitpos 692 \ (\d+)\s+hitneg # hitneg 693 \ (\d+)\s+missed # missed 694 \ (\d+)\s+dne # dne 695 $/ox) { 696 $innd_his{'Positive hits'} += $1; 697 $innd_his{'Negative hits'} += $2; 698 $innd_his{'Cache misses'} += $3; 699 $innd_his{'Do not exist'} += $4; 700 return 1; 701 } 702 # SERVER history cache final: 388656 lookups, 1360 hits 703 if ($left =~ m/^SERVER history cache final: (\d+) lookups, (\d+) hits$/) { 704 $innd_cache{'Lookups'} += $1; 705 $innd_cache{'Hits'} += $2; 706 return 1; 707 } 708 # bad_hosts (appears after a "cant gesthostbyname" from a feed) 709 return 1 if $left =~ m/\S+ bad_hosts /o; 710 # cant read 711 return 1 if $left =~ m/\S+ cant read/o; 712 # cant write 713 return 1 if $left =~ m/\S+ cant write/o; 714 # cant flush 715 return 1 if $left =~ m/\S+ cant flush/o; 716 # spoolwake 717 return 1 if $left =~ m/\S+ spoolwake$/o; 718 # spooling 719 return 1 if $left =~ m/\S+ spooling/o; 720 # DEBUG 721 return 1 if $left =~ m/^DEBUG /o; 722 # NCmode 723 return 1 if $left =~ m/\S+ NCmode /o; 724 # outgoing 725 return 1 if $left =~ m/\S+ outgoing/o; 726 # inactive 727 return 1 if $left =~ m/\S+ inactive/o; 728 # timeout 729 return 1 if $left =~ m/\S+ timeout/o; 730 # lcsetup 731 return 1 if $left =~ m/\S+ lcsetup/o; 732 # rcsetup 733 return 1 if $left =~ m/\S+ rcsetup/o; 734 # flush_all 735 return 1 if $left =~ m/\S+ flush_all/o; 736 # buffered 737 return 1 if $left =~ m/\S+ buffered$/o; 738 # descriptors 739 return 1 if $left =~ m/\S+ descriptors/o; 740 # ccsetup 741 return 1 if $left =~ m/\S+ ccsetup/o; 742 # renumbering 743 return 1 if $left =~ m/\S+ renumbering/o; 744 # renumber 745 return 1 if $left =~ m/\S+ renumber /o; 746 # ihave from me 747 if ($left =~ m/\S+ ihave_from_me /o) { 748 $controlchan_ihave_site{'ME'}++; 749 return 1; 750 } 751 # sendme from me 752 if ($left =~ m/\S+ sendme_from_me /o) { 753 $controlchan_sendme_site{'ME'}++; 754 return 1; 755 } 756 # newgroup 757 if ($left =~ m/\S+ newgroup (\S+) as (\S)/o) { 758 $innd_newgroup{$1} = $2; 759 return 1; 760 } 761 # rmgroup 762 if ($left =~ m/\S+ rmgroup (\S+)$/o) { 763 $innd_rmgroup{$1}++; 764 return 1; 765 } 766 # changegroup 767 if ($left =~ m/\S+ change_group (\S+) to (\S)/o) { 768 $innd_changegroup{$1} = $2; 769 return 1; 770 } 771 # paused 772 if ($left =~ m/(\S+) paused /o) { 773 $innd_control{"paused"}++; 774 return 1; 775 } 776 # throttled 777 return 1 if $left =~ m/\S+ throttled/o; 778 # reload 779 if ($left =~ m/(\S+) reload/o) { 780 $innd_control{"reload"}++; 781 return 1; 782 } 783 # shutdown 784 if ($left =~ m/(\S+) shutdown/o) { 785 $innd_control{"shutdown"}++; 786 return 1; 787 } 788 # re-executed 789 return 1 if $left =~ m/^SERVER execv /o; 790 # SERVER servermode paused 791 return 1 if ($left =~ /(\S+) servermode paused$/o); 792 # SERVER servermode running 793 return 1 if ($left =~ /(\S+) servermode running$/o); 794 # SERVER flushlogs paused 795 if ($left =~ /(\S+) flushlogs /) { 796 $innd_control{"flushlogs"}++; 797 return 1; 798 } 799 # think it's a dotquad 800 return 1 if $left =~ /think it\'s a dotquad: /o; 801 # bad_ihave 802 if ($left =~ /(\S+) bad_ihave /) { 803 my $server = $1; 804 $server =~ s/:\d+$//o; 805 $server = lc $server unless $CASE_SENSITIVE; 806 $innd_bad_ihave{$server}++; 807 return 1; 808 } 809 # bad_messageid 810 if ($left =~ /(\S+) bad_messageid/o) { 811 my $server = $1; 812 $server =~ s/:\d+$//o; 813 $server = lc $server unless $CASE_SENSITIVE; 814 $innd_bad_msgid{$server}++; 815 return 1; 816 } 817 # bad_sendme 818 if ($left =~ /(\S+) bad_sendme /o) { 819 my $server = $1; 820 $server =~ s/:\d+$//o; 821 $server = lc $server unless $CASE_SENSITIVE; 822 $innd_bad_sendme{$server}++; 823 return 1; 824 } 825 # bad_command 826 if ($left =~ /(\S+) bad_command /o) { 827 my $server = $1; 828 $server =~ s/:\d+$//o; 829 $server = lc $server unless $CASE_SENSITIVE; 830 $innd_bad_command{$server}++; 831 return 1; 832 } 833 # bad_newsgroup 834 if ($left =~ /(\S+) bad_newsgroup /o) { 835 my $server = $1; 836 $server =~ s/:\d+$//o; 837 $innd_bad_newsgroup{$server}++; 838 $server = lc $server unless $CASE_SENSITIVE; 839 return 1; 840 } 841 if ($left =~ m/ cant /o) { 842 # cant select Bad file number 843 if ($left =~ / cant select Bad file number/o) { 844 $innd_misc{"Bad file number"}++; 845 return 1; 846 } 847 # cant gethostbyname 848 if ($left =~ / cant gethostbyname/o) { 849 $innd_misc{"gethostbyname error"}++; 850 return 1; 851 } 852 # cant accept RCreader 853 if ($left =~ / cant accept RCreader /o) { 854 $innd_misc{"RCreader"}++; 855 return 1; 856 } 857 # cant sendto CCreader 858 if ($left =~ / cant sendto CCreader /o) { 859 $innd_misc{"CCreader"}++; 860 return 1; 861 } 862 # cant (other) skipped - not particularly interesting 863 return 1; 864 } 865 # bad_newsfeeds no feeding sites 866 return 1 if $left =~ /\S+ bad_newsfeeds no feeding sites/o; 867 # CNFS: cycbuff rollover - possibly interesting 868 return 1 if $left =~ /CNFS(?:-sm)?: cycbuff \S+ rollover to cycle/o; 869 # CNFS: CNFSflushallheads: flushing - possibly interesting 870 return 1 if $left =~ /CNFS(?:-sm)?: CNFSflushallheads: flushing /o; 871 # CNFS: metacycbuff rollover with SEQUENTIAL 872 return 1 if $left =~ /CNFS(?:-sm)?: metacycbuff \S+ cycbuff is moved to /o; 873 # Cleanfeed status reports 874 return 1 if $left =~ /^filter: status/o; 875 return 1 if $left =~ /^filter: Reloading bad files/o; 876 return 1 if $left =~ /^filter: Saved EMP database/o; 877 return 1 if $left =~ /^filter: Restored EMP database/o; 878 } 879 ######## 880 ## innfeed 881 if ($prog eq "innfeed") { 882 # connected 883 if ($left =~ /(\S+):\d+ connected$/) { 884 my $server = $1; 885 $server = lc $server unless $CASE_SENSITIVE; 886 $innfeed_connect{$server}++; 887 return 1; 888 } 889 # closed periodic 890 return 1 if $left =~ m/\S+:\d+ closed periodic$/o; 891 # periodic close 892 return 1 if $left =~ m/\S+:\d+ periodic close$/o; 893 # checkpoint (child) 894 return 1 if $left =~ m/\S+:\d+ checkpoint seconds \d+ offered \d+ accepted \d+ refused \d+ rejected \d+/o; 895 # final (child) 896 return 1 if $left =~ m/\S+:\d+ final seconds \d+ offered \d+ accepted \d+ refused \d+ rejected \d+/o; 897 # global (real) 898 return 1 if $left =~ m/\S+ global seconds \d+ offered \d+ accepted \d+ refused \d+ rejected \d+ missing \d+/o; 899 # checkpoint (real) (new format) 900 if ($left =~ /(\S+) checkpoint seconds (\d+) offered (\d+) accepted (\d+) refused (\d+) rejected (\d+) missing (\d+) accsize (\d+) rejsize (\d+) spooled (\d+)/o) { 901 my ($server, $seconds, $offered, $accepted, $refused, $rejected, 902 $missing, $accepted_size, $rejected_size, $spooled) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10); 903 $server = lc $server unless $CASE_SENSITIVE; 904 $innfeed_seconds{$server} += $seconds; 905 $innfeed_offered{$server} += $offered; 906 $innfeed_accepted{$server} += $accepted; 907 $innfeed_refused{$server} += $refused; 908 $innfeed_rejected{$server} += $rejected; 909 $innfeed_missing{$server} += $missing; 910 $innfeed_spooled{$server} += $spooled; 911 $innfeed_accepted_size{$server} += $accepted_size; 912 $innfeed_rejected_size{$server} += $rejected_size; 913 return 1; 914 } elsif ($left =~ /(\S+) checkpoint seconds (\d+) offered (\d+) accepted (\d+) refused (\d+) rejected (\d+) missing (\d+) spooled (\d+)/o) { 915 my ($server, $seconds, $offered, $accepted, $refused, $rejected, 916 $missing, $spooled) = ($1, $2, $3, $4, $5, $6, $7, $8); 917 $server = lc $server unless $CASE_SENSITIVE; 918 $innfeed_seconds{$server} += $seconds; 919 $innfeed_offered{$server} += $offered; 920 $innfeed_accepted{$server} += $accepted; 921 $innfeed_refused{$server} += $refused; 922 $innfeed_rejected{$server} += $rejected; 923 $innfeed_missing{$server} += $missing; 924 $innfeed_spooled{$server} += $spooled; 925 return 1; 926 } 927 # checkpoint (only seconds & spooled) 928 if ($left =~ /(\S+) checkpoint seconds (\d+) spooled (\d+)/o) { 929 my ($server, $seconds, $spooled) = ($1, $2, $3); 930 $server = lc $server unless $CASE_SENSITIVE; 931 # Initialize a value for that key (otherwise, it does not appear in the 932 # report, and the total line is wrong). 933 $innfeed_offered{$server} += 0; 934 $innfeed_seconds{$server} += $seconds; 935 $innfeed_spooled{$server} += $spooled; 936 return 1; 937 } 938 939 # final 940 return 1 if $left =~ m/\S+ final seconds/o; 941 942 # ME file xxxx shrunk from yyyy to zzz 943 if ($left =~ /^ME file (.*)\.output shrunk from (\d+) to (\d+)$/) { 944 my ($file, $s1, $s2) = ($1, $2, $3); 945 $file =~ s|^.*/([^/]+)$|$1|; # keep only the server name 946 $innfeed_shrunk{$file} += $s1 - $s2; 947 return 1; 948 } 949 # profile timer 950 # ME time X nnnn X(X) [...] 951 return 1 if $left =~ m/backlogstats/; 952 if ($left =~ m/^\S+\s+ # ME 953 time\s(\d+)\s+ # time 954 ((?:\S+\s\d+\(\d+\)\s*)+) # timer values 955 $/ox) { 956 $innfeed_time_times += $1; 957 my $timers = $2; 958 959 while ($timers =~ /(\S+) (\d+)\((\d+)\)\s*/g) { 960 my $name = $innfeed_timer_names{$1} || $1; 961 $innfeed_time_time{$name} += $2; 962 if ($3) { 963 $innfeed_time_num{$name} += $3; 964 my $average = $2 / $3; 965 my $min = $innfeed_time_min{$name}; 966 $innfeed_time_min{$name} = $average 967 if (!defined($min) || $min > $average); 968 my $max = $innfeed_time_max{$name}; 969 $innfeed_time_max{$name} = $average 970 if (!defined($max) || $max < $average); 971 } 972 } 973 return 1; 974 } 975 # xxx grabbing external tape file 976 return 1 if $left =~ m/ grabbing external tape file/o; 977 # hostChkCxns - maxConnections was 978 return 1 if $left =~ m/hostChkCxns - maxConnections was /o; 979 # cxnsleep 980 return 1 if $left =~ m/\S+ cxnsleep .*$/o; 981 # idle 982 return 1 if $left =~ m/\S+ idle tearing down connection$/o; 983 # remote 984 return 1 if $left =~ m/\S+ remote .*$/o; 985 # spooling 986 return 1 if $left =~ m/\S+ spooling no active connections$/o; 987 # ME articles total 988 return 1 if $left =~ m/(?:SERVER|ME) articles total \d+ bytes \d+/o; 989 # ME articles active 990 return 1 if $left =~ m/(?:SERVER|ME) articles active \d+ bytes \d+/o; 991 # connect : Connection refused 992 return 1 if $left =~ m/connect : Connection refused/o; 993 # connect : Network is unreachable 994 return 1 if $left =~ m/connect : Network is unreachable/o; 995 # connect : Address family not supported by protocol 996 return 1 if $left =~ m/connect : Address family not supported by protocol/o; 997 # connect : No route to host 998 return 1 if $left =~ m/connect : No route to host/o; 999 # connection vanishing 1000 return 1 if $left =~ m/connection vanishing/o; 1001 # can't resolve hostname 1002 return 1 if $left =~ m/can\'t resolve hostname/o; 1003 # new hand-prepared backlog file 1004 return 1 if $left =~ m/new hand-prepared backlog file/o; 1005 # flush re-connect failed 1006 return 1 if $left =~ m/flush re-connect failed/o; 1007 # internal QUIT while write pending 1008 return 1 if $left =~ m/internal QUIT while write pending/o; 1009 # ME source lost . Exiting 1010 return 1 if $left =~ m/(?:SERVER|ME) source lost . Exiting/o; 1011 # ME starting innfeed (+version & date) 1012 return 1 if $left =~ m/(?:SERVER|ME) starting (?:innfeed|at)/o; 1013 # ME finishing at (date) 1014 return 1 if $left =~ m/(?:SERVER|ME) finishing at /o; 1015 # mode no-CHECK entered 1016 return 1 if $left =~ m/mode no-CHECK entered/o; 1017 # mode no-CHECK exited 1018 return 1 if $left =~ m/mode no-CHECK exited/o; 1019 # closed 1020 return 1 if $left =~ m/^(\S+) closed$/o; 1021 # global (+ seconds offered accepted refused rejected missing) 1022 return 1 if $left =~ m/^(\S+) global/o; 1023 # idle connection still has articles 1024 return 1 if $left =~ m/^(\S+) idle connection still has articles$/o; 1025 # missing article for IHAVE-body 1026 return 1 if $left =~ m/^(\S+) missing article for IHAVE-body$/o; 1027 # cannot continue 1028 return 1 if $left =~ m/^cannot continue/o; 1029 if ($left =~ /^(?:SERVER|ME)/o) { 1030 # ME dropping articles into ... 1031 return 1 if $left =~ / dropping articles into /o; 1032 # ME dropped ... 1033 return 1 if $left =~ / dropped /o; 1034 # ME internal bad data in checkpoint file 1035 return 1 if $left =~ m/ internal bad data in checkpoint/o; 1036 # ME two filenames for same article 1037 return 1 if $left =~ m/ two filenames for same article/o; 1038 # ME unconfigured peer 1039 return 1 if $left =~ m/ unconfigured peer/o; 1040 # exceeding maximum article size 1041 return 1 if $left =~ m/ exceeding maximum article byte/o; 1042 # no space left on device errors 1043 return 1 if $left =~ m/ ioerr fclose/o; 1044 return 1 if $left =~ m/ lock failed for host/o; 1045 return 1 if $left =~ m/ lock file pid-write/o; 1046 return 1 if $left =~ m/ locked cannot setup peer/o; 1047 return 1 if $left =~ m/ received shutdown signal/o; 1048 # unconfigured peer 1049 return 1 if $left =~ m/ unconfigured peer/o; 1050 # ME lock 1051 return 1 if $left =~ m/ lock/o; 1052 # ME exception: getsockopt (0): Socket operation on non-socket 1053 return 1 if $left =~ m/ exception: getsockopt /o; 1054 # ME config aborting fopen (...) Permission denied 1055 return 1 if $left =~ m/ config aborting fopen /o; 1056 # ME cant chmod innfeed.pid.... 1057 return 1 if $left =~ m/ cant chmod \S+\/innfeed.pid/o; 1058 return 1 if $left =~ m/ tape open failed /o; 1059 return 1 if $left =~ m/ oserr open checkpoint file:/o; 1060 # ME finishing (quickly) 1061 return 1 if $left =~ m/\(quickly\) /o; 1062 # ME config: value of streaming is not a boolean 1063 return 1 if $left =~ m/config: value of \S+ is not/o; 1064 # innfeed rolling funnel file 1065 return 1 if $left =~ m/ preparing to roll /o; 1066 return 1 if $left =~ m/ reached EOF in /o; 1067 return 1 if $left =~ m/ opened /o; 1068 # when optional parameters are not present in innfeed.conf 1069 return 1 if $left =~ m/ config: adding default value for key /o; 1070 } 1071 # hostChkCxn - now: x.xx, prev: x.xx, abs: xx, curr: x 1072 return 1 if $left =~ m/ hostChkCxn - now/o; 1073 # loading path_to_config_file/innfeed.conf 1074 return 1 if $left =~ m/loading /o; 1075 # Finally, to avoid problems with strange error lines, ignore them. 1076 #return 1 if ($left =~ /ME /); 1077 } 1078 ######## 1079 ## innxmit 1080 if ($prog eq "innxmit") { 1081 # 437 Duplicate article 1082 if ($left =~ /(\S+) rejected [^\s]+ \(.*?\) (?:437|439) Duplicate article$/o) { 1083 my $server = $1; 1084 $server = lc $server unless $CASE_SENSITIVE; 1085 $innxmit_badart{$server}++; 1086 $innxmit_duplicate{$server}++; 1087 return 1; 1088 } 1089 # 437 Unapproved for 1090 if ($left =~ /(\S+) rejected [^\s]+ \(.*\) (?:437|439) Unapproved for \"(.*?)\"$/o) { 1091 my ($server, $group) = ($1, $2); 1092 $server = lc $server unless $CASE_SENSITIVE; 1093 $innxmit_badart{$server}++; 1094 $innxmit_unapproved{$server}++; 1095 $innxmit_unapproved_g{$group}++; 1096 return 1; 1097 } 1098 # 437 Too old -- ... 1099 if ($left =~ /(\S+) rejected [^\s]+ \(.*\) (?:437|439) Too old -- \".*?\"$/o) { 1100 my $server = $1; 1101 $server = lc $server unless $CASE_SENSITIVE; 1102 $innxmit_badart{$server}++; 1103 $innxmit_tooold{$server}++; 1104 return 1; 1105 } 1106 # 437 Unwanted site ... in path 1107 if ($left =~ 1108 /(\S+) rejected [^\s]+ \(.*?\) (?:437|439) Unwanted site (\S+) in path$/o) { 1109 my ($server, $site) = ($1, $2); 1110 $server = lc $server unless $CASE_SENSITIVE; 1111 $innxmit_badart{$server}++; 1112 $innxmit_uw_site{$server}++; 1113 # $innxmit_site_path{$site}++; 1114 return 1; 1115 } 1116 # 437 Unwanted newsgroup "..." 1117 if ($left =~ 1118 /(\S+) rejected [^\s]+ \(.*?\) (?:437|439) Unwanted newsgroup \"(\S+)\"$/o) { 1119 my ($server, $group) = ($1, $2); 1120 $server = lc $server unless $CASE_SENSITIVE; 1121 $innxmit_badart{$server}++; 1122 $innxmit_uw_ng_s{$server}++; 1123 $innxmit_uw_ng{$group}++; 1124 return 1; 1125 } 1126 # 437 Unwanted distribution "..." 1127 if ($left =~ 1128 /(\S+) rejected [^\s]+ \(.*?\) (?:437|439) Unwanted distribution \"(\S+)\"$/o) { 1129 my ($server, $dist) = ($1, $2); 1130 $server = lc $server unless $CASE_SENSITIVE; 1131 $innxmit_badart{$server}++; 1132 $innxmit_uw_dist_s{$server}++; 1133 $innxmit_uw_dist{$dist}++; 1134 return 1; 1135 } 1136 # xx rejected foo.bar/12345 (foo/bar/12345) 437 Unwanted distribution "..." 1137 if ($left =~ /^(\S+) rejected .* (?:437|439) Unwanted distribution \"(\S+)\"$/o) { 1138 my ($server, $dist) = ($1, $2); 1139 $server = lc $server unless $CASE_SENSITIVE; 1140 $innxmit_badart{$server}++; 1141 $innxmit_uw_dist_s{$server}++; 1142 $innxmit_uw_dist{$dist}++; 1143 return 1; 1144 } 1145 # 437 Linecount x != y +- z 1146 if ($left =~ /(\S+) rejected [^\s]+ \(.*?\) (?:437|439) Linecount/o) { 1147 my $server = $1; 1148 $server = lc $server unless $CASE_SENSITIVE; 1149 $innxmit_badart{$server}++; 1150 $innxmit_linecount{$server}++; 1151 return 1; 1152 } 1153 # 437 Newsgroup name illegal -- "xxx" 1154 if ($left =~ /(\S+) rejected .* (?:437|439) Newsgroup name illegal -- "[^\"]*"$/) { 1155 my $server = $1; 1156 $server = lc $server unless $CASE_SENSITIVE; 1157 $innxmit_others{$server}++; 1158 $innxmit_badart{$server}++; 1159 return 1; 1160 } 1161 # Streaming retries 1162 return 1 if ($left =~ /\d+ Streaming retries$/o); 1163 # ihave failed 1164 if ($left =~ /(\S+) ihave failed/o) { 1165 my $server = $1; 1166 $server = lc $server unless $CASE_SENSITIVE; 1167 $innxmit_ihfail{$server} = 1; 1168 if ($left = /436 \S+ NNTP \S+ out of space/o) { 1169 $innxmit_nospace{$server}++; 1170 return 1; 1171 } 1172 if ($left = /400 \S+ space/o) { 1173 $innxmit_nospace{$server}++; 1174 return 1; 1175 } 1176 if ($left = /400 Bad file/o) { 1177 $innxmit_crefused{$server}++; 1178 return 1; 1179 } 1180 if ($left = /480 Transfer permission denied/o) { 1181 $innxmit_crefused{$server}++; 1182 return 1; 1183 } 1184 } 1185 # stats (new format) 1186 if ($left =~ 1187 /(\S+) stats offered (\d+) accepted (\d+) refused (\d+) rejected (\d+) missing (\d+) accsize (\d+) rejsize (\d+)$/o) { 1188 my ($server, $offered, $accepted, $refused, $rejected, $missing, $accbytes, $rejbytes) = 1189 ($1, $2, $3, $4, $5, $6, $7, $8); 1190 $server = lc $server unless $CASE_SENSITIVE; 1191 $innxmit_offered{$server} += $offered; 1192 $innxmit_offered{$server} -= $innxmit_ihfail{$server} 1193 if ($innxmit_ihfail{$server}); 1194 $innxmit_accepted{$server} += $accepted; 1195 $innxmit_refused{$server} += $refused; 1196 $innxmit_rejected{$server} += $rejected; 1197 $innxmit_missing{$server} += $missing; 1198 $innxmit_accepted_size{$server} += $accbytes; 1199 $innxmit_rejected_size{$server} += $rejbytes; 1200 $innxmit_site{$server}++; 1201 $innxmit_ihfail{$server} = 0; 1202 return 1; 1203 } 1204 # stats 1205 if ($left =~ 1206 /(\S+) stats offered (\d+) accepted (\d+) refused (\d+) rejected (\d+)$/o) { 1207 my ($server, $offered, $accepted, $refused, $rejected) = 1208 ($1, $2, $3, $4, $5); 1209 $server = lc $server unless $CASE_SENSITIVE; 1210 $innxmit_offered{$server} += $offered; 1211 $innxmit_offered{$server} -= $innxmit_ihfail{$server} 1212 if ($innxmit_ihfail{$server}); 1213 $innxmit_accepted{$server} += $accepted; 1214 $innxmit_refused{$server} += $refused; 1215 $innxmit_rejected{$server} += $rejected; 1216 $innxmit_site{$server}++; 1217 $innxmit_ihfail{$server} = 0; 1218 return 1; 1219 } 1220 # times 1221 if ($left =~ /(\S+) times user (.+) system (\S+) elapsed (\S+)$/o) { 1222 my ($server, $user, $system, $elapsed) = ($1, $2, $3, $4); 1223 $server = lc $server unless $CASE_SENSITIVE; 1224 $innxmit_times{$server} += $elapsed; 1225 return 1; 1226 } 1227 # connect & no space 1228 if ($left =~ /(\S+) connect \S+ 400 No space/o) { 1229 my $server = $1; 1230 $server = lc $server unless $CASE_SENSITIVE; 1231 $innxmit_nospace{$server}++; 1232 $innxmit_site{$server}++; 1233 return 1; 1234 } 1235 # connect & NNTP no space 1236 if ($left =~ /(\S+) connect \S+ 400 \S+ out of space/o) { 1237 my $server = $1; 1238 $server = lc $server unless $CASE_SENSITIVE; 1239 $innxmit_nospace{$server}++; 1240 $innxmit_site{$server}++; 1241 return 1; 1242 } 1243 # connect & loadav 1244 if ($left =~ /(\S+) connect \S+ 400 loadav/o) { 1245 my $server = $1; 1246 if ($left =~ /expir/i) { 1247 $server = lc $server unless $CASE_SENSITIVE; 1248 $innxmit_expire{$server}++; 1249 $innxmit_site{$server}++; 1250 return 1; 1251 } 1252 } 1253 # connect 400 (other) 1254 if ($left =~ /(\S+) connect \S+ 400/o) { 1255 my $server = $1; 1256 $server = lc $server unless $CASE_SENSITIVE; 1257 $innxmit_crefused{$server}++; 1258 $innxmit_site{$server}++; 1259 return 1; 1260 } 1261 # connect failed 1262 if ($left =~ /(\S+) connect failed/o) { 1263 my $server = $1; 1264 $server = lc $server unless $CASE_SENSITIVE; 1265 $innxmit_cfail_host{$server}++; 1266 $innxmit_site{$server}++; 1267 return 1; 1268 } 1269 # authenticate failed 1270 if ($left =~ /(\S+) authenticate failed/o) { 1271 my $server = $1; 1272 $server = lc $server unless $CASE_SENSITIVE; 1273 $innxmit_afail_host{$server}++; 1274 $innxmit_site{$server}++; 1275 return 1; 1276 } 1277 # xxx ihave failed 400 loadav [innwatch:hiload] yyy gt zzz 1278 if ($left =~ /^(\S+) ihave failed 400 loadav/o) { 1279 my $server = $1; 1280 $server = lc $server unless $CASE_SENSITIVE; 1281 $innxmit_hiload{$server}++; 1282 return 1; 1283 } 1284 # ihave failed 1285 return 1 if ($left =~ /\S+ ihave failed/o); 1286 # requeued (....) 436 No space 1287 return 1 if ($left =~ /\S+ requeued \S+ 436 No space/o); 1288 # requeued (....) 400 No space 1289 return 1 if ($left =~ /\S+ requeued \S+ 400 No space/o); 1290 # requeued (....) 436 Can't write history 1291 return 1 if ($left =~ /\S+ requeued \S+ 436 Can\'t write history/o); 1292 # unexpected response code 1293 return 1 if ($left =~ /unexpected response code /o); 1294 } 1295 1296 ######## 1297 ## nntplink 1298 if ($prog eq "nntplink") { 1299 $left =~ s/^(\S+):/$1/; 1300 # EOF 1301 if ($left =~ /(\S+) EOF /o) { 1302 my $server = $1; 1303 $server = lc $server unless $CASE_SENSITIVE; 1304 $nntplink_site{$server}++; 1305 $nntplink_eof{$server}++; 1306 return 1; 1307 } 1308 # Broken pipe 1309 if ($left =~ /(\S+) Broken pipe$/o) { 1310 my $server = $1; 1311 $server = lc $server unless $CASE_SENSITIVE; 1312 $nntplink_site{$server}++; 1313 $nntplink_bpipe{$server}++; 1314 return 1; 1315 } 1316 # already running - won't die 1317 return 1 if $left =~ /\S+ nntplink.* already running /o; 1318 # connection timed out 1319 if ($left =~ /(\S+) connection timed out/o) { 1320 my $server = $1; 1321 $server = lc $server unless $CASE_SENSITIVE; 1322 $nntplink_site{$server}++; 1323 $nntplink_bpipe{$server}++; 1324 return 1; 1325 } 1326 # greeted us with 400 No space 1327 if ($left =~ /(\S+) greeted us with 400 No space/o) { 1328 my $server = $1; 1329 $server = lc $server unless $CASE_SENSITIVE; 1330 $nntplink_site{$server}++; 1331 $nntplink_nospace{$server}++; 1332 return 1; 1333 } 1334 # greeted us with 400 loadav 1335 if ($left =~ /(\S+) greeted us with 400 loadav/o) { 1336 my $server = $1; 1337 $server = lc $server unless $CASE_SENSITIVE; 1338 $nntplink_site{$server}++; 1339 $nntplink_hiload{$server}++; 1340 return 1; 1341 } 1342 # greeted us with 400 (other) 1343 if ($left =~ /(\S+) greeted us with 400/o) { 1344 my $server = $1; 1345 $server = lc $server unless $CASE_SENSITIVE; 1346 $nntplink_site{$server}++; 1347 if ($left =~ /expir/i) { 1348 $nntplink_expire{$server}++; 1349 } else { 1350 $nntplink_fail{$server}++; 1351 } 1352 return 1; 1353 } 1354 # greeted us with 502 1355 if ($left =~ /(\S+) greeted us with 502/o) { 1356 my $server = $1; 1357 $server = lc $server unless $CASE_SENSITIVE; 1358 $nntplink_site{$server}++; 1359 $nntplink_auth{$server}++; 1360 return 1; 1361 } 1362 # sent authinfo 1363 if ($left =~ /(\S+) sent authinfo/o) { 1364 my $server = $1; 1365 $server = lc $server unless $CASE_SENSITIVE; 1366 $nntplink_site{$server}++; 1367 $nntplink_auth{$server}++; 1368 return 1; 1369 } 1370 # socket() 1371 if ($left =~ /(\S+) socket\(\): /o) { 1372 my $server = $1; 1373 $server = lc $server unless $CASE_SENSITIVE; 1374 $nntplink_site{$server}++; 1375 $nntplink_sockerr{$server}++; 1376 return 1; 1377 } 1378 # select() 1379 if ($left =~ /(\S+) select\(\) /o) { 1380 my $server = $1; 1381 $server = lc $server unless $CASE_SENSITIVE; 1382 $nntplink_site{$server}++; 1383 $nntplink_selecterr{$server}++; 1384 return 1; 1385 } 1386 # sent IHAVE 1387 if ($left =~ /(\S+) sent IHAVE/o) { 1388 my $server = $1; 1389 $server = lc $server unless $CASE_SENSITIVE; 1390 $nntplink_ihfail{$server}++; 1391 if (($left =~ / 436 /) && ($left =~ / out of space /)) { 1392 $nntplink_fake_connects{$server}++; 1393 $nntplink_nospace{$server}++; 1394 } 1395 return 1; 1396 } 1397 # article .... failed(saved): 436 No space 1398 if ($left =~ /(\S+) .* failed\(saved\): 436 No space$/o) { 1399 my $server = $1; 1400 $server = lc $server unless $CASE_SENSITIVE; 1401 $nntplink_nospace{$server}++; 1402 return 1; 1403 } 1404 # article .. 400 No space left on device writing article file -- throttling 1405 if ($left =~ /(\S+) .* 400 No space left on device writing article file -- throttling$/o) { 1406 my $server = $1; 1407 $server = lc $server unless $CASE_SENSITIVE; 1408 $nntplink_nospace{$server}++; 1409 return 1; 1410 } 1411 # stats 1412 if ($left =~ /(\S+) stats (\d+) offered (\d+) accepted (\d+) rejected (\d+) failed (\d+) connects$/o) { 1413 my ($server, $offered, $accepted, $rejected, $failed, $connects) = 1414 ($1, $2, $3, $4, $5, $6); 1415 $server = lc $server unless $CASE_SENSITIVE; 1416 $nntplink_offered{$server} += $offered - $nntplink_ihfail{$server}++; 1417 $nntplink_accepted{$server} += $accepted; 1418 $nntplink_rejected{$server} += $rejected; 1419 $nntplink_failed{$server} += $failed; 1420 $nntplink_connects{$server} += $connects; 1421 $nntplink_ihfail{$server} = 0; 1422 if ($nntplink_fake_connects{$server}) { 1423 $nntplink_site{$server} += $nntplink_fake_connects{$server}; 1424 $nntplink_fake_connects{$server} = 0; 1425 } else { 1426 $nntplink_site{$server}++; 1427 } 1428 return 1; 1429 } 1430 # xmit 1431 if ($left =~ /(\S+) xmit user (.+) system (\S+) elapsed (\S+)$/o) { 1432 my ($server, $user, $system, $elapsed) = ($1, $2, $3, $4); 1433 $server = lc $server unless $CASE_SENSITIVE; 1434 $nntplink_times{$server} += $elapsed; 1435 return 1; 1436 } 1437 # xfer 1438 return 1 if $left =~ /\S+ xfer/o; 1439 # Links down .. x hours 1440 if ($left =~ /(\S+) Links* down \S+ \d+/o) { 1441 # Collected but not used 1442 # my $server = $1; 1443 # $server = lc $server unless $CASE_SENSITIVE; 1444 # $nntplink_down{$server} += $hours; 1445 return 1; 1446 } 1447 # 503 Timeout 1448 if ($left =~ /^(\S+) \S+ \S+ \S+ 503 Timeout/o) { 1449 # Collected but not used 1450 # my $server = $1; 1451 # $server = lc $server unless $CASE_SENSITIVE; 1452 # $nntplink_timeout{$server}++; 1453 return 1; 1454 } 1455 # read() error while reading reply 1456 if ($left =~ /^(\S+): read\(\) error while reading reply/o) { 1457 my $server = $1; 1458 $server = lc $server unless $CASE_SENSITIVE; 1459 $nntplink_failed{$server}++; 1460 return 1; 1461 } 1462 # Password file xxxx not found 1463 return 1 if $left =~ /^\S+ Password file \S+ not found/; 1464 # No such 1465 return 1 if $left =~ /^\S+ \S+ \S+ No such/; 1466 # already running 1467 return 1 if $left =~ /^\S+ \S+ already running/; 1468 # error reading version from datafile 1469 return 1 if $left =~ /error reading version from datafile/; 1470 } 1471 ######## 1472 ## nnrpd 1473 if ($prog =~ /^nnrpd(?:-ssl)?$/) 1474 { 1475 # Fix a small bug of nnrpd (inn 1.4*) 1476 $left =~ s/^ /\? /o; 1477 # Another bug (in INN 1.5b1) 1478 return 1 if $left =~ /^\020\002m$/o; # ^P^Bm 1479 # bad_history at num for <ref> 1480 return 1 if $left =~ /bad_history at \d+ for /o; 1481 # timeout short 1482 return 1 if $left =~ /\S+ timeout short$/o; 1483 # < or > + (blablabla) 1484 return 1 if $left =~ /^\S+ [\<\>] /o; 1485 # cant opendir ... I/O error 1486 return 1 if $left =~ /\S+ cant opendir \S+ I\/O error$/o; 1487 # perl filtering enabled 1488 return 1 if $left =~ /perl filtering enabled$/o; 1489 # Python filtering enabled 1490 return 1 if $left =~ /Python filtering enabled$/o; 1491 return 1 if $left =~ /^python interpreter initialized OK$/o; 1492 return 1 if $left =~ /^python method \S+ not found$/o; 1493 return 1 if $left =~ /^python authenticate method succeeded, return code \d+, error string /o; 1494 return 1 if $left =~ /^python access method succeeded$/o; 1495 return 1 if $left =~ /^python dynamic method \(\w+ access\) succeeded, refuse string: /o; 1496 return 1 if $left =~ /^python: .+ module successfully hooked into nnrpd$/o; 1497 return 1 if $left =~ /^python: nnrpd .+ class instance created$/o; 1498 return 1 if $left =~ /^python: n_a authenticate\(\) invoked: hostname \S+, ipaddress \S+, interface \S+, user /o; 1499 return 1 if $left =~ /^python: n_a access\(\) invoked: hostname \S+, ipaddress \S+, interface \S+, user /o; 1500 return 1 if $left =~ /^python: n_a dynamic\(\) invoked against type \S+, hostname \S+, ipaddress \S+, interface \S+, user /o; 1501 return 1 if $left =~ /^python: authentication by username succeeded$/o; 1502 return 1 if $left =~ /^python: authentication by username failed$/o; 1503 return 1 if $left =~ /^python: authentication access by IP address succeeded$/o; 1504 return 1 if $left =~ /^python: authentication access by IP address failed$/o; 1505 return 1 if $left =~ /^python: dynamic access module successfully hooked into nnrpd$/o; 1506 return 1 if $left =~ /^python: dynamic authorization access for read access granted$/o; 1507 return 1 if $left =~ /^python: dynamic authorization access type is not known: /o; 1508 # during scanlogs 1509 return 1 if $left =~ /^\S+ rejected Flushing log and syslog files$/o; 1510 return 1 if $left =~ /^\S+ rejected Snapshot log and syslog files$/o; 1511 # other logs that should not be reported as errors 1512 return 1 if $left =~ /^\S+ auth also-log: /o; 1513 return 1 if $left =~ /^\S+ res also-log: /o; 1514 return 1 if $left =~ /^\S+ rejected by rule /o; 1515 # connect 1516 if ($left =~ /(\S+) (\([0-9a-fA-F:.]*\) )?connect(?: - port \d+)?$/o) { 1517 my $cust = $1; 1518 $cust = lc $cust unless $CASE_SENSITIVE; 1519 my $dom = &host2dom($cust); 1520 $nnrpd_dom_connect{$dom}++; 1521 $nnrpd_connect{$cust}++; 1522 return 1; 1523 } 1524 # group 1525 if ($left =~ /(\S+) group (\S+) (\d+)$/o) { 1526 my ($cust, $group, $num) = ($1, $2, $3); 1527 $cust = lc $cust unless $CASE_SENSITIVE; 1528 my $dom = &host2dom($cust); 1529 1530 if ($num) { 1531 $nnrpd_group{$group} += $num; 1532 $nnrpd_groups{$cust}++; 1533 $nnrpd_dom_groups{$dom}++; 1534 1535 my ($hierarchy) = $group =~ /^([^\.]+).*$/o; 1536 $nnrpd_hierarchy{$hierarchy} += $num; 1537 } 1538 return 1; 1539 } 1540 # post/ihave failed 1541 if ($left =~ /(\S+) (post|ihave) failed (.*)$/o) { 1542 my ($cust, $error) = ($1, $3); 1543 $cust = lc $cust unless $CASE_SENSITIVE; 1544 my $dom = &host2dom($cust); 1545 $nnrpd_dom_post_error{$dom}++; 1546 $nnrpd_post_error{$cust}++; 1547 return 1; 1548 } 1549 # post ok 1550 return 1 if $left =~ /\S+ post ok/o; 1551 # ihave ok 1552 return 1 if $left =~ /\S+ ihave ok/o; 1553 # posts 1554 if ($left =~ /(\S+) posts received (\d+) rejected (\d+)$/o) { 1555 my ($cust, $received, $rejected) = ($1, $2, $3); 1556 $cust = lc $cust unless $CASE_SENSITIVE; 1557 my $dom = &host2dom($cust); 1558 $nnrpd_dom_post_ok{$dom} += $received; 1559 $nnrpd_dom_post_rej{$dom} += $rejected; 1560 $nnrpd_post_ok{$cust} += $received; 1561 $nnrpd_post_rej{$cust} += $rejected; 1562 return 1; 1563 } 1564 # noperm post without permission 1565 if ($left =~ /(\S+) noperm post without permission/o) { 1566 my $cust = $1; 1567 $cust = lc $cust unless $CASE_SENSITIVE; 1568 my $dom = &host2dom($cust); 1569 $nnrpd_dom_post_rej{$dom} ++; 1570 $nnrpd_post_rej{$cust} ++; 1571 return 1; 1572 } 1573 # no_permission 1574 if ($left =~ /(\S+) no_(permission|access)$/o) { 1575 my $cust = $1; 1576 $cust = lc $cust unless $CASE_SENSITIVE; 1577 my $dom = &host2dom($cust); 1578 $nnrpd_no_permission{$cust}++; 1579 $nnrpd_dom_no_permission{$dom}++; 1580 return 1; 1581 } 1582 # bad_auth 1583 if ($left =~ /(\S+) bad_auth$/o) { 1584 my $cust = $1; 1585 $cust = lc $cust unless $CASE_SENSITIVE; 1586 my $dom = &host2dom($cust); 1587 $nnrpd_dom_no_permission{$dom}++; 1588 $nnrpd_no_permission{$cust}++; 1589 return 1; 1590 } 1591 # Authentication failure 1592 # User not known to the underlying authentication module 1593 return 1 if $left =~ / ckpasswd: pam_authenticate failed: /o; 1594 return 1 if $left =~ / ckpasswd: user .+ unknown$/o; 1595 # AUTHINFO (a username is a bytes string) 1596 if (($left =~ /\S+ user (.+)$/o) && 1597 ($left !~ /\S+ times user .+ system \S+ idle \S+ elapsed \S+$/o)) { 1598 my $user = $1; 1599 $nnrpd_auth{$user}++; 1600 return 1; 1601 } 1602 # unrecognized + command 1603 if ($left =~ /(\S+) unrecognized (.*)$/o) { 1604 my ($cust, $error) = ($1, $2); 1605 $cust = lc $cust unless $CASE_SENSITIVE; 1606 my $dom = &host2dom($cust); 1607 $error = "_null command_" if ($error !~ /\S/); 1608 $error =~ s/^(xmotd) .*$/$1/i if ($error =~ /^xmotd .*$/i); 1609 $nnrpd_dom_unrecognized{$dom}++; 1610 $nnrpd_unrecognized{$cust}++; 1611 $nnrpd_unrecogn_cmd{$error}++; 1612 return 1; 1613 } 1614 # exit (also called when using STARTTLS) 1615 if ($left =~ /(\S+) (?:exit|exit for STARTTLS|exit for AUTHINFO SASL) articles (\d+) groups (\d+)$/o) { 1616 my ($cust, $articles, $groups) = ($1, $2, $3); 1617 $cust = lc $cust unless $CASE_SENSITIVE; 1618 my $dom = &host2dom($cust); 1619 if ($cust eq '?') { 1620 $nnrpd_connect{$cust}++; 1621 $nnrpd_dom_connect{$dom}++; 1622 } 1623 $nnrpd_articles{$cust} += $articles; 1624 $nnrpd_dom_articles{$dom} += $articles; 1625 return 1; 1626 } 1627 # times 1628 if ($left =~ /(\S+) times user (.+) system (\S+) idle (\S+) elapsed (\S+)$/o) { 1629 my ($cust, $user, $system, $idle, $elapsed) = ($1, $2, $3, $4, $5); 1630 $cust = lc $cust unless $CASE_SENSITIVE; 1631 my $dom = &host2dom($cust); 1632 $nnrpd_times{$cust} += $elapsed; 1633 $nnrpd_resource_user{$cust} += $user; 1634 $nnrpd_resource_system{$cust} += $system; 1635 $nnrpd_resource_idle{$cust} += $idle; 1636 $nnrpd_resource_elapsed{$cust} += $elapsed; 1637 $nnrpd_dom_times{$dom} += $elapsed; 1638 return 1; 1639 } 1640 # artstats 1641 if ($left =~ /(\S+) artstats get (\d+) time (\d+) size (\d+)$/o) { 1642 my ($cust, $articles, $time, $bytes) = ($1, $2, $3, $4); 1643 $cust = lc $cust unless $CASE_SENSITIVE; 1644 my $dom = &host2dom($cust); 1645 $nnrpd_bytes{$cust} += $bytes; 1646 $nnrpd_dom_bytes{$dom} += $bytes; 1647 return 1; 1648 } 1649 # timeout 1650 if ($left =~ /(\S+) timeout$/o) { 1651 my $cust = $1; 1652 $cust = lc $cust unless $CASE_SENSITIVE; 1653 my $dom = &host2dom($cust); 1654 $nnrpd_dom_timeout{$dom}++; 1655 $nnrpd_timeout{$cust}++; 1656 return 1; 1657 } 1658 # timeout in post 1659 if ($left =~ /(\S+) timeout in post$/o) { 1660 my $cust = $1; 1661 $cust = lc $cust unless $CASE_SENSITIVE; 1662 my $dom = &host2dom($cust); 1663 $nnrpd_dom_timeout{$dom}++; 1664 $nnrpd_timeout{$cust}++; 1665 return 1; 1666 } 1667 # can't read: Connection timed out 1668 if ($left =~ /(\S+) can\'t read: Connection timed out$/o) { 1669 my $cust = $1; 1670 $cust = lc $cust unless $CASE_SENSITIVE; 1671 my $dom = &host2dom($cust); 1672 $nnrpd_dom_timeout{$dom}++; 1673 $nnrpd_timeout{$cust}++; 1674 return 1; 1675 } 1676 # can't read: Operation timed out 1677 if ($left =~ /(\S+) can\'t read: Operation timed out$/o) { 1678 my $cust = $1; 1679 $cust = lc $cust unless $CASE_SENSITIVE; 1680 my $dom = &host2dom($cust); 1681 $nnrpd_dom_timeout{$dom}++; 1682 $nnrpd_timeout{$cust}++; 1683 return 1; 1684 } 1685 # can't read: Connection reset by peer 1686 if ($left =~ /(\S+) can\'t read: Connection reset by peer$/o) { 1687 my $cust = $1; 1688 $cust = lc $cust unless $CASE_SENSITIVE; 1689 my $dom = &host2dom($cust); 1690 $nnrpd_dom_reset_peer{$dom}++; 1691 $nnrpd_reset_peer{$cust}++; 1692 return 1; 1693 } 1694 # can't read: Network is unreachable 1695 return 1 if $left =~ /(\S+) can\'t read: Network is unreachable$/o; 1696 # gethostbyaddr: xxx.yyy.zzz != a.b.c.d 1697 if ($left =~ /^gethostbyaddr: (.*)$/o) { 1698 my $msg = $1; 1699 $nnrpd_gethostbyaddr{$msg}++; 1700 return 1; 1701 } 1702 # can't gethostbyaddr 1703 if ($left =~ /\? can\'t gethostbyaddr (\S+) .*$/o) { 1704 my $ip = $1; 1705 $nnrpd_gethostbyaddr{$ip}++; 1706 return 1; 1707 } 1708 # can't getpeername 1709 if ($left =~ /\? can\'t getpeername/o) { 1710 $nnrpd_gethostbyaddr{"? (can't getpeername)"}++; 1711 return 1; 1712 } 1713 # can't getsockname 1714 return 1 if $left =~ /^\S+ can\'t getsockname$/o; 1715 # can't initialize TLS session 1716 return 1 if $left =~ /^\S+ failure to negotiate TLS session$/o; 1717 # reverse lookup failed 1718 return 1 if $left =~ /^\? reverse lookup for \S+ failed: .* -- using IP address for access$/o; 1719 # profile timer 1720 # ME time X nnnn X(X) [...] 1721 # The exact timers change from various versions of INN, so try to deal 1722 # with this in a general fashion. 1723 if ($left =~ m/^\S+\s+ # ME 1724 time\s(\d+)\s+ # time 1725 ((?:\S+\s\d+\(\d+\)\s*)+) # timer values 1726 $/ox) { 1727 $nnrpd_time_times += $1; 1728 my $timers = $2; 1729 1730 while ($timers =~ /(\S+) (\d+)\((\d+)\)\s*/g) { 1731 my $name = $nnrpd_timer_names{$1} || $1; 1732 $nnrpd_time_time{$name} += $2; 1733 if ($3) { 1734 my $average = $2 / $3; 1735 $nnrpd_time_num{$name} += $3; 1736 my $min = $nnrpd_time_min{$name}; 1737 $nnrpd_time_min{$name} = $average 1738 if (!defined($min) || $min > $average); 1739 my $max = $nnrpd_time_max{$name}; 1740 $nnrpd_time_max{$name} = $average 1741 if (!defined($max) || $max < $average); 1742 } 1743 } 1744 return 1; 1745 } 1746 # ME dropping articles into ... 1747 return 1 if $left =~ /ME dropping articles into /o; 1748 # newnews (interesting but ignored till now) 1749 return 1 if $left =~ /^\S+ newnews /o; 1750 # cant fopen (ignored too) 1751 return 1 if $left =~ /^\S+ cant fopen /o; 1752 # can't read: No route to host 1753 return 1 if $left =~ /can\'t read: No route to host/o; 1754 # can't read: Broken pipe 1755 return 1 if $left =~ /can\'t read: Broken pipe/o; 1756 # eof in post 1757 return 1 if $left =~ /^\S+ EOF in post$/o; 1758 # ioctl: ... 1759 return 1 if $left =~ /^ioctl: /o; 1760 # other stats 1761 return 1 if $left =~ /^\S+ overstats count \d+ hit \d+ miss \d+ time \d+ size \d+ dbz \d+ seek \d+ get \d+ artcheck \d+$/o; 1762 # starttls 1763 return 1 if $left =~ /^starttls: \S+ with cipher \S+ \(\d+\/\d+ bits\) no authentication$/o; 1764 } 1765 ######## 1766 ## overchan 1767 if ($prog eq "overchan") { 1768 # times 1769 if ($left =~ /timings (\d+) arts (\d+) of (\d+) ms$/o) { 1770 my ($articles, $work_time, $run_time) = ($1, $2, $3); 1771 # ??? What to do with numbers 1772 return 1; 1773 } 1774 } 1775 ######## 1776 ## batcher 1777 if ($prog eq "batcher") { 1778 # times 1779 if ($left =~ /(\S+) times user (.+) system (\S+) elapsed (\S+)$/o) { 1780 my ($server, $user, $system, $elapsed) = ($1, $2, $3, $4); 1781 $server = lc $server unless $CASE_SENSITIVE; 1782 # $batcher_user{$server} += $user; 1783 # $batcher_system{$server} += $system; 1784 $batcher_elapsed{$server} += $elapsed; 1785 return 1; 1786 } 1787 # stats 1788 if ($left =~ /(\S+) stats batches (\d+) articles (\d+) bytes (\d+)$/o) { 1789 my ($server, $batches, $articles, $bytes) = ($1, $2, $3, $4); 1790 $server = lc $server unless $CASE_SENSITIVE; 1791 $batcher_offered{$server} += $batches; 1792 $batcher_articles{$server} += $articles; 1793 $batcher_bytes{$server} += $bytes; 1794 return 1; 1795 } 1796 } 1797 ######## 1798 ## rnews 1799 if ($prog eq "rnews") { 1800 # rejected connection 1801 if ($left =~ /rejected connection (.*)$/o) { 1802 $rnews_rejected{$1}++; 1803 return 1; 1804 } 1805 # cant open_remote 1806 if ($left =~ /(cant open_remote .*)$/o) { 1807 $rnews_rejected{$1}++; 1808 return 1; 1809 } 1810 # rejected 437 Unwanted newsgroup 1811 if ($left =~ /rejected (?:437|439) Unwanted newsgroup \"(.*)\"$/o) { 1812 $rnews_bogus_ng{$1}++; 1813 return 1; 1814 } 1815 # rejected 437 Unapproved for "xx" 1816 if ($left =~ /rejected (?:437|439) Unapproved for \"(.*)\"$/o) { 1817 $rnews_unapproved{$1}++; 1818 return 1; 1819 } 1820 # rejected 437 Unwanted distribution 1821 if ($left =~ /rejected (?:437|439) Unwanted distribution (.*)$/o) { 1822 $rnews_bogus_dist{$1}++; 1823 return 1; 1824 } 1825 # rejected 437 Bad "Date" 1826 if ($left =~ /rejected (?:437|439) Bad \"Date\" (.*)$/o) { 1827 $rnews_bogus_date{$1}++; 1828 return 1; 1829 } 1830 # rejected 437 Bad "Injection-Date" 1831 if ($left =~ /rejected (?:437|439) Bad \"Injection-Date\" (.*)$/o) { 1832 $rnews_bogus_date{$1}++; 1833 return 1; 1834 } 1835 # rejected 437 Article injected or posted in the future 1836 if ($left =~ /rejected (?:437|439) Article injected or posted in the future -- \"(.*)\"$/o) { 1837 $rnews_bogus_date{"(future) $1"}++; 1838 return 1; 1839 } 1840 # rejected 437 Too old -- "..." 1841 if ($left =~ /rejected (?:437|439) Too old -- (.*)$/o) { 1842 $rnews_too_old++; 1843 return 1; 1844 } 1845 # rejected 437 Linecount... 1846 if ($left =~ /rejected (?:437|439) Linecount \d+ \!= \d+/o) { 1847 $rnews_linecount++; 1848 return 1; 1849 } 1850 # rejected 437 Duplicate 1851 if ($left =~ /rejected (?:437|439) Duplicate$/o) { 1852 $rnews_duplicate++; 1853 return 1; 1854 } 1855 # rejected 437 Duplicate article 1856 if ($left =~ /rejected (?:437|439) Duplicate article/o) { 1857 $rnews_duplicate++; 1858 return 1; 1859 } 1860 # rejected 437 No colon-space ... 1861 if ($left =~ /rejected (?:437|439) No colon-space in \"(.*)\" header$/o) { 1862 $rnews_no_colon_space++; 1863 return 1; 1864 } 1865 # duplicate <msg-id> path.. 1866 if ($left =~ /^duplicate /o) { 1867 $rnews_duplicate++; 1868 return 1; 1869 } 1870 # offered <msg-id> feed 1871 if ($left =~ /^offered \S+ (\S+)/o) { 1872 my $host = $1; 1873 $host = lc $host unless $CASE_SENSITIVE; 1874 # Small hack used to join article spooled when innd is throttle. 1875 # In this situation, the hostname is a 8 hex digits string 1876 # To avoid confusions with real feeds, the first character is forced 1877 # to be a '3' or a '4' (will work between 9/7/1995 and 13/7/2012). 1878 $host = "Local postings" if $host =~ /^[34][0-9a-f]{7}$/; 1879 $rnews_host{$host}++; 1880 return 1; 1881 } 1882 # rejected 437 "Subject" header too long 1883 return 1 if $left =~ m/header too long/o; 1884 # rejected 437 Reason... 1885 return 1 if $left =~ m/rejected (?:437|439)/o; 1886 # bad_article missing (Message-ID|Path|...) 1887 return 1 if $left =~ m/bad_article missing /o; 1888 # cant unspool saving to xxx 1889 return 1 if $left =~ m/cant unspool saving to/o; 1890 } 1891 1892 ########### 1893 ## ncmspool 1894 if ($prog eq "ncmspool") { 1895 # <article> good signature from foo@bar.com 1896 if ($left =~ /good signature from (.*)/o) { 1897 $nocem_goodsigs{$1}++; 1898 $nocem_totalgood++; 1899 $nocem_lastid = $1; 1900 return 1; 1901 } 1902 # <article> bad signature from foo@bar.com 1903 if ($left =~ /bad signature from (.*)/o) { 1904 $nocem_badsigs{$1}++; 1905 $nocem_goodsigs{$1} = 0 unless ($nocem_goodsigs{$1}); 1906 $nocem_totalbad++; 1907 $nocem_lastid = $1; 1908 return 1; 1909 } 1910 # <article> contained 123 new 456 total ids 1911 if ($left =~ /contained (\d+) new (\d+) total ids/o) { 1912 $nocem_newids += $1; 1913 $nocem_newids{$nocem_lastid} += $1; 1914 $nocem_totalids += $2; 1915 $nocem_totalids{$nocem_lastid} += $2; 1916 return 1; 1917 } 1918 return 1; 1919 } 1920 1921 ######## 1922 ## nocem 1923 if ($prog eq "nocem") { 1924 if ($left =~ /processed notice .* by (.*) \((\d+) ids,/o) { 1925 $nocem_goodsigs{$1}++; 1926 $nocem_totalgood++; 1927 $nocem_lastid = $1; 1928 $nocem_newids += $2; 1929 $nocem_newids{$nocem_lastid} += $2; 1930 $nocem_totalids += $2; 1931 $nocem_totalids{$nocem_lastid} += $2; 1932 return 1; 1933 } 1934 if ($left =~ /Article <[^>]*>: (.*) \(ID [[:xdigit:]]*\) not in keyring/o) { 1935 $nocem_badsigs{$1}++; 1936 $nocem_goodsigs{$1} = 0 unless ($nocem_goodsigs{$1}); 1937 $nocem_totalids{$1} = 0 unless ($nocem_totalids{$1}); 1938 $nocem_totalbad++; 1939 $nocem_lastid = $1; 1940 return 1; 1941 } 1942 if ($left =~ /Article <[^>]*>: bad signature from (.*)/o) { 1943 $nocem_badsigs{$1}++; 1944 $nocem_goodsigs{$1} = 0 unless ($nocem_goodsigs{$1}); 1945 $nocem_totalids{$1} = 0 unless ($nocem_totalids{$1}); 1946 $nocem_totalbad++; 1947 $nocem_lastid = $1; 1948 return 1; 1949 } 1950 if ($left =~ /Article <[^>]*>: malformed signature/o) { 1951 $nocem_badsigs{'N/A'}++; 1952 $nocem_goodsigs{'N/A'} = 0 unless ($nocem_goodsigs{'N/A'}); 1953 $nocem_totalids{'N/A'} = 0 unless ($nocem_totalids{'N/A'}); 1954 $nocem_totalbad++; 1955 $nocem_lastid = 'N/A'; 1956 return 1; 1957 } 1958 1959 return 1; 1960 } 1961 1962 ########### 1963 ## controlchan 1964 if ($prog eq "controlchan") { 1965 # loaded /x/y/z/foo.pl 1966 return 1 if $left =~ m/^loaded /; 1967 # starting 1968 return 1 if $left =~ m/^starting/; 1969 # skipping rmgroup x@y (pgpverify failed) in <foo@bar> 1970 if ($left =~ m/^skipping \S+ (\S+) \(pgpverify failed\) in /) { 1971 $controlchan_skippgp{$1}++; 1972 $controlchan_who{$1}++; 1973 return 1; 1974 } 1975 if ($left =~ m/^control_(sendme|ihave), [^,]+, (\S+), doit,/o) { 1976 if ($1 eq "sendme") { 1977 $controlchan_sendme_site{$2}++; 1978 } else { 1979 $controlchan_ihave_site{$2}++; 1980 } 1981 return 1; 1982 } 1983 # control_XXgroup, foo.bar [moderated] who who token, [pattern], [pattern], encoding, peer, action, 1 1984 # 1985 # Various other random junk can end up in the moderated field, like y, 1986 # unmoderated, m, etc. depending on what the control message says. It 1987 # can even have multiple words, which we still don't handle. 1988 if ($left =~ m/^control_(\S+), # type of msg 1989 \s(?:\S+)? # newsgroup name 1990 (\s\S+)? # optional 1991 \s(\S+) # e-mail 1992 \s\S+ # e-mail 1993 \s\S+, # storage token 1994 \s(?:\S+)?, # exclusion pattern 1995 \s(?:\S+)?, # drop pattern 1996 \s\S+, # local encoding 1997 \s\S+, # server 1998 \s([^=,]+(?:=\S+)?), # action 1999 \s*(.*) # 1 if message approved and first logged in the file 2000 /x) { 2001 if ($1 eq 'newgroup') { 2002 $controlchan_new{$3}++; 2003 } elsif ($1 eq 'rmgroup') { 2004 $controlchan_rm{$3}++; 2005 } else { 2006 $controlchan_other{$3}++ if $5 >= 0; 2007 } 2008 $controlchan_who{$3}++; 2009 $controlchan_ok{$3} += $5 if $5 > 0; 2010 my $action = $4; 2011 my $email = $3; 2012 $action =~ s/=.*//; 2013 $controlchan_doit{$email}++ if $action eq 'doit'; 2014 return 1; 2015 } 2016 # checkgroups processed or not (with no change or not) 2017 return 1 if $left =~ /^checkgroups by \S+/o; 2018 } 2019 2020 ########### 2021 ## cnfsstat 2022 if ($prog eq "cnfsstat") { 2023 # Class ALT for groups matching "alt.*" article size min/max: 0/1048576 2024 # Buffer T3, len: 1953 Mbytes, used: 483.75 Mbytes (24.8%) 0 cycles 2025 if ($left =~ m|^Class\ (\S+)\ for\ groups\ matching\ \S+ 2026 (\ article\ size\ min/max:\ \d+/\d+)? 2027 \ Buffer\ (\S+), 2028 \ len:\ ([\d.]+)\s+Mbytes, 2029 \ used:\ ([\d.]+)\ Mbytes\ \(\s*[\d.]+%\) 2030 \s+(\d+)\ cycles\s* 2031 $|ox) { 2032 my ($class, $buffer, $size, $used, $cycles) = ($1, $3, $4, $5, $6); 2033 my ($h, $m, $s) = $hour =~ m/^(\d+):(\d+):(\d+)$/; 2034 my $time = $h * 3600 + $m * 60 + $s; 2035 $size *= 1024 * 1024; 2036 $used *= 1024 * 1024; 2037 $cnfsstat{$buffer} = $class; 2038 2039 # If the size changed, invalidate all of our running fill rate stats. 2040 if (!exists($cnfsstat_size{$buffer}) || $size != $cnfsstat_size{$buffer}) { 2041 delete $cnfsstat_rate{$buffer}; 2042 delete $cnfsstat_samples{$buffer}; 2043 delete $cnfsstat_time{$buffer}; 2044 $cnfsstat_size{$buffer} = $size; 2045 } 2046 elsif ($cnfsstat_time{$buffer}) { 2047 # We want to gather the rate at which cycbuffs fill. Store a 2048 # running total of bytes/second and a total number of samples. 2049 # Ideally we'd want a weighted average of those samples by the 2050 # length of the sample period, but we'll ignore that and assume 2051 # cnfsstat runs at a roughly consistent interval. 2052 my ($period, $added); 2053 $period = $time - $cnfsstat_time{$buffer}; 2054 $period = 86400 - $cnfsstat_time{$buffer} + $time if $period <= 0; 2055 $added = $used - $cnfsstat_used{$buffer}; 2056 if ($cycles > $cnfsstat_cycles{$buffer}) { 2057 $added += $size * ($cycles - $cnfsstat_cycles{$buffer}); 2058 } 2059 if ($added > 0) { 2060 $cnfsstat_rate{$buffer} += $added / $period; 2061 $cnfsstat_samples{$buffer}++; 2062 } 2063 } 2064 $cnfsstat_used{$buffer} = $used; 2065 $cnfsstat_cycles{$buffer} = $cycles; 2066 $cnfsstat_time{$buffer} = $time; 2067 return 1; 2068 } 2069 } 2070 2071 # Ignore following programs : 2072 return 1 if ($prog eq "uxfxn"); 2073 return 1 if ($prog eq "beverage"); 2074 return 1 if ($prog eq "newsx"); 2075 return 1 if ($prog eq "demmf"); 2076 return 1 if ($prog eq "nnnn"); 2077 return 1 if ($prog eq "slurp"); 2078 return 0; 2079} 2080 2081################################# 2082# Adjust some values.. 2083 2084sub adjust($$) { 2085 my ($first_date, $last_date) = @_; 2086 2087 my $nnrpd_doit = 0; 2088 my $curious; 2089 2090 { 2091 my $serv; 2092 if (%nnrpd_connect) { 2093 my @keys = keys (%nnrpd_connect); 2094 my $c = @keys; 2095 foreach my $serv (@keys) { 2096 if ($nnrpd_no_permission{$serv}) { 2097 my $dom = &host2dom($serv); 2098 $nnrpd_dom_connect{$dom} -= $nnrpd_connect{$serv} 2099 if defined $nnrpd_dom_connect{$dom}; 2100 $nnrpd_dom_times{$dom} -= $nnrpd_times{$serv} 2101 if defined $nnrpd_dom_times{$dom}; 2102 2103 # The message "bad_auth" can occur more than once per session. 2104 # Subtracting nnrpd_no_permission from nnrpd_connect is 2105 # broken and can yield negative values for nnrpd_connect. 2106 $nnrpd_connect{$serv} -= $nnrpd_no_permission{$serv}; 2107 2108 # Perl considers negative values to be true. Previously the 2109 # hash entry was deleted only if the value was exactly 0. 2110 delete $nnrpd_connect{$serv} unless $nnrpd_connect{$serv} > 0; 2111 2112 delete $nnrpd_groups{$serv} unless $nnrpd_groups{$serv}; 2113 delete $nnrpd_times{$serv} unless $nnrpd_times{$serv}; 2114 delete $nnrpd_usr_times{$serv} unless $nnrpd_usr_times{$serv}; 2115 delete $nnrpd_sys_times{$serv} unless $nnrpd_sys_times{$serv}; 2116 delete $nnrpd_dom_connect{$dom} unless $nnrpd_dom_connect{$dom} > 0; 2117 delete $nnrpd_dom_groups{$dom} unless $nnrpd_dom_groups{$dom}; 2118 delete $nnrpd_dom_times{$dom} unless $nnrpd_dom_times{$dom}; 2119 $c--; 2120 } 2121 $nnrpd_doit++ 2122 if $nnrpd_groups{$serv} || $nnrpd_post_ok{$serv}; 2123 } 2124 undef %nnrpd_connect unless $c; 2125 } 2126 foreach my $serv (keys (%nnrpd_groups)) { 2127 $curious = "ok" unless $nnrpd_groups{$serv} || $nnrpd_post_ok{$serv} || 2128 $nnrpd_articles{$serv}; 2129 } 2130 } 2131 2132 # Fill some hashes 2133 { 2134 my ($key, $hostname, $channel); 2135 2136 # Since the checkpoint counts include entries for all server 2137 # connections, check to see if any checkpoint server entries are not also 2138 # in %innd_connect. Add any missing servers (persistant servers with no 2139 # connected log lines) to %innd_connect so that incoming totals will be 2140 # properly computed. 2141 foreach $server (keys (%innd_accepted)) { 2142 if (! defined($innd_connect{$server})) { 2143 $innd_connect{$server} = 0; 2144 } 2145 } 2146 2147 foreach $key (keys (%innd_connect)) { 2148 $innd_offered{$key} = ($innd_accepted{$key} || 0) 2149 + ($innd_refused{$key} || 0) 2150 + ($innd_rejected{$key} || 0); 2151 $innd_offered_size{$key} = ($innd_stored_size{$key} || 0) 2152 + ($innd_duplicated_size{$key} || 0) + ($innd_rejected_size{$key} || 0); 2153 } 2154 2155 # Sum all incoming traffic for each full server. 2156 foreach $key (keys (%innd_connect)) { 2157 if ($key =~ /^(\S+):\d+$/) { 2158 $innd_seconds_sum{$1} += ($innd_seconds{$key} || 0); 2159 $innd_connect_sum{$1} += ($innd_connect{$key} || 0); 2160 $innd_offered_sum{$1} += ($innd_offered{$key} || 0); 2161 $innd_accepted_sum{$1} += ($innd_accepted{$key} || 0); 2162 $innd_refused_sum{$1} += ($innd_refused{$key} || 0); 2163 $innd_rejected_sum{$1} += ($innd_rejected{$key} || 0); 2164 $innd_stored_size_sum{$1} += ($innd_stored_size{$key} || 0); 2165 $innd_duplicated_size_sum{$1} += ($innd_duplicated_size{$key} || 0); 2166 $innd_offered_size_sum{$1} += ($innd_offered_size{$key} || 0); 2167 $innd_rejected_size_sum{$1} += ($innd_rejected_size{$key} || 0); 2168 } 2169 } 2170 2171 # adjust min/max of innd timer stats. 2172 if (%innd_time_min) { 2173 foreach $key (keys (%innd_time_min)) { 2174 $innd_time_min{$key} = 0 if ($innd_time_min{$key} == $MIN); 2175 $innd_time_max{$key} = 0 if ($innd_time_max{$key} == $MAX); 2176 2177 #$innd_time_min{$key} /= 1000; 2178 #$innd_time_max{$key} /= 1000; 2179 } 2180 } 2181 if (%innfeed_time_min) { 2182 foreach $key (keys (%innfeed_time_min)) { 2183 $innfeed_time_min{$key} = 0 if ($innfeed_time_min{$key} == $MIN); 2184 $innfeed_time_max{$key} = 0 if ($innfeed_time_max{$key} == $MAX); 2185 } 2186 } 2187 if (%nnrpd_time_min) { 2188 foreach $key (keys (%nnrpd_time_min)) { 2189 $nnrpd_time_min{$key} = 0 if ($nnrpd_time_min{$key} == $MIN); 2190 $nnrpd_time_max{$key} = 0 if ($nnrpd_time_max{$key} == $MAX); 2191 } 2192 } 2193 # remove the innd timer stats if not used. 2194 unless ($innd_time_times) { 2195 undef %innd_time_min; 2196 undef %innd_time_max; 2197 undef %innd_time_num; 2198 undef %innd_time_time; 2199 } 2200 # same thing for innfeed timer 2201 unless ($innfeed_time_times) { 2202 undef %innfeed_time_min; 2203 undef %innfeed_time_max; 2204 undef %innfeed_time_num; 2205 undef %innfeed_time_time; 2206 } 2207 # same thing for nnrpd timer 2208 unless ($nnrpd_time_times) { 2209 undef %nnrpd_time_min; 2210 undef %nnrpd_time_max; 2211 undef %nnrpd_time_num; 2212 undef %nnrpd_time_time; 2213 } 2214 } 2215 2216 if (%inn_flow) { 2217 my ($prev_dd, $prev_d, $prev_h) = ("", -1, -1); 2218 my $day; 2219 foreach $day (sort datecmp keys (%inn_flow)) { 2220 my ($r, $h) = $day =~ /^(.*) (\d+)$/; 2221 my $d = index ("JanFebMarAprMayJunJulAugSepOctNovDec", 2222 substr ($r,0,3)) / 3 * 31 + substr ($r, 4, 2); 2223 $prev_h = $h if ($prev_h == -1); 2224 if ($prev_d == -1) { 2225 $prev_d = $d; 2226 $prev_dd = $r; 2227 } 2228 if ($r eq $prev_dd) { # Same day and same month ? 2229 if ($h != $prev_h) { 2230 if ($h == $prev_h + 1) { 2231 $prev_h++; 2232 } 2233 else { 2234 my $j; 2235 for ($j = $prev_h + 1; $j < $h; $j++) { 2236 my $t = sprintf "%02d", $j; 2237 $inn_flow{"$r $t"} = 0; 2238 } 2239 $prev_h = $h; 2240 } 2241 } 2242 } 2243 else { 2244 my $j; 2245 # then end of the first day... 2246 for ($j = ($prev_h == 23) ? 24 : $prev_h + 1; $j < 24; $j++) { 2247 my $t = sprintf "%02d", $j; 2248 $inn_flow{"$prev_dd $t"} = 0; 2249 } 2250 2251 # all the days between (if any) 2252 # well, we can forget them as it is supposed to be a tool 2253 # launched daily. 2254 2255 # the beginning of the last day.. 2256 for ($j = 0; $j < $h; $j++) { 2257 my $t = sprintf "%02d", $j; 2258 $inn_flow{"$r $t"} = 0; 2259 } 2260 $prev_dd = $r; 2261 $prev_d = $d; 2262 $prev_h = $h; 2263 } 2264 } 2265 my $first = 1; 2266 my (%hash, %hash_time, %hash_size, $date, $delay); 2267 foreach $day (sort datecmp keys (%inn_flow)) { 2268 my ($r, $h) = $day =~ /^(.*) (\d+)$/o; 2269 if ($first) { 2270 $first = 0; 2271 my ($t) = $first_date =~ m/:(\d\d:\d\d)$/o; 2272 $date = "$day:$t - $h:59:59"; 2273 $t =~ m/(\d\d):(\d\d)/o; 2274 $delay = 3600 - $1 * 60 - $2; 2275 } 2276 else { 2277 $date = "$day:00:00 - $h:59:59"; 2278 $delay = 3600; 2279 } 2280 $hash{$date} = $inn_flow{$day}; 2281 $hash_size{$date} = $inn_flow_size{$day}; 2282 $inn_flow_labels{$date} = $h; 2283 $hash_time{$date} = $delay; 2284 } 2285 my ($h, $t) = $last_date =~ m/ (\d+):(\d\d:\d\d)$/o; 2286 my ($h2) = $date =~ m/ (\d+):\d\d:\d\d /o; 2287 my $date2 = $date; 2288 $date2 =~ s/$h2:59:59$/$h:$t/; 2289 $hash{$date2} = $hash{$date}; 2290 delete $hash{"$date"}; 2291 $hash_size{$date2} = $hash_size{$date}; 2292 delete $hash_size{"$date"}; 2293 $t =~ m/(\d\d):(\d\d)/o; 2294 $hash_time{$date2} = $hash_time{$date} - ($h2 == $h) * 3600 + $1 * 60 + $2; 2295 delete $hash_time{"$date"}; 2296 $inn_flow_labels{$date2} = $h; 2297 %inn_flow = %hash; 2298 %inn_flow_time = %hash_time; 2299 %inn_flow_size = %hash_size; 2300 } 2301 2302 if (%innd_bad_ihave) { 2303 my $key; 2304 my $msg = 'Bad ihave control messages received'; 2305 foreach $key (keys %innd_bad_ihave) { 2306 $innd_misc_stat{$msg}{$key} = $innd_bad_ihave{$key}; 2307 } 2308 } 2309 if (%innd_bad_msgid) { 2310 my $key; 2311 my $msg = 'Bad Message-ID\'s offered'; 2312 foreach $key (keys %innd_bad_msgid) { 2313 $innd_misc_stat{$msg}{$key} = $innd_bad_msgid{$key}; 2314 } 2315 } 2316 if (%innd_bad_sendme) { 2317 my $key; 2318 my $msg = 'Ignored sendme control messages received'; 2319 foreach $key (keys %innd_bad_sendme) { 2320 $innd_misc_stat{$msg}{$key} = $innd_bad_sendme{$key}; 2321 } 2322 } 2323 if (%innd_bad_command) { 2324 my $key; 2325 my $msg = 'Bad command received'; 2326 foreach $key (keys %innd_bad_command) { 2327 $innd_misc_stat{$msg}{$key} = $innd_bad_command{$key}; 2328 } 2329 } 2330 if (%innd_bad_newsgroup) { 2331 my $key; 2332 my $msg = 'Bad newsgroups received'; 2333 foreach $key (keys %innd_bad_newsgroup) { 2334 $innd_misc_stat{$msg}{$key} = $innd_bad_newsgroup{$key}; 2335 } 2336 } 2337 if (%innd_posted_future) { 2338 my $key; 2339 my $msg = 'Article posted in the future'; 2340 foreach $key (keys %innd_posted_future) { 2341 $innd_misc_stat{$msg}{$key} = $innd_posted_future{$key}; 2342 } 2343 } 2344 if (%innd_no_colon_space) { 2345 my $key; 2346 my $msg = 'No colon-space in header'; 2347 foreach $key (keys %innd_no_colon_space) { 2348 $innd_misc_stat{$msg}{$key} = $innd_no_colon_space{$key}; 2349 } 2350 } 2351 if (%innd_huge) { 2352 my $key; 2353 my $msg = 'Huge articles'; 2354 foreach $key (keys %innd_huge) { 2355 $innd_misc_stat{$msg}{$key} = $innd_huge{$key}; 2356 } 2357 } 2358 if (%innd_blocked) { 2359 my $key; 2360 my $msg = 'Blocked server feeds'; 2361 foreach $key (keys %innd_blocked) { 2362 $innd_misc_stat{$msg}{$key} = $innd_blocked{$key}; 2363 } 2364 } 2365 if (%innd_strange_strings) { 2366 my $key; 2367 my $msg = 'Including strange strings'; 2368 foreach $key (keys %innd_strange_strings) { 2369 $innd_misc_stat{$msg}{$key} = $innd_strange_strings{$key}; 2370 } 2371 } 2372 if (%rnews_bogus_ng) { 2373 my $key; 2374 my $msg = 'Unwanted newsgroups'; 2375 foreach $key (keys %rnews_bogus_ng) { 2376 $rnews_misc{$msg}{$key} = $rnews_bogus_ng{$key}; 2377 } 2378 } 2379 if (%rnews_bogus_dist) { 2380 my $key; 2381 my $msg = 'Unwanted distributions'; 2382 foreach $key (keys %rnews_bogus_dist) { 2383 $rnews_misc{$msg}{$key} = $rnews_bogus_dist{$key}; 2384 } 2385 } 2386 if (%rnews_unapproved) { 2387 my $key; 2388 my $msg = 'Articles unapproved'; 2389 foreach $key (keys %rnews_unapproved) { 2390 $rnews_misc{$msg}{$key} = $rnews_unapproved{$key}; 2391 } 2392 } 2393 if (%rnews_bogus_date) { 2394 my $key; 2395 my $msg = 'Bad Date'; 2396 foreach $key (keys %rnews_bogus_date) { 2397 $rnews_misc{$msg}{$key} = $rnews_bogus_date{$key}; 2398 } 2399 } 2400 2401 $rnews_misc{'Too old'}{'--'} = $rnews_too_old if $rnews_too_old; 2402 $rnews_misc{'Bad linecount'}{'--'} = $rnews_linecount if $rnews_linecount; 2403 $rnews_misc{'Duplicate articles'}{'--'} = $rnews_duplicate 2404 if $rnews_duplicate; 2405 $rnews_misc{'No colon-space'}{'--'} = $rnews_no_colon_space 2406 if $rnews_no_colon_space; 2407 2408 if (%nnrpd_groups) { 2409 foreach my $key (keys (%nnrpd_connect)) { 2410 unless ($nnrpd_groups{$key} || $nnrpd_post_ok{$key} || 2411 $nnrpd_post_rej{$key} || $nnrpd_post_error{$key} || 2412 $nnrpd_articles{$key}) { 2413 $nnrpd_curious{$key} = $nnrpd_connect{$key}; 2414 delete $nnrpd_connect{$key}; 2415 } 2416 } 2417 } 2418} 2419 2420sub report_unwanted_ng($) { 2421 my $file = shift; 2422 open (FILE, "$file") && do { 2423 while (<FILE>) { 2424 my ($c, $n) = $_ =~ m/^\s*(\d+)\s+(.*)$/; 2425 next unless defined $n; 2426 $n =~ s/^newsgroup //o; # for pre 1.8 logs 2427 $inn_uw_ng{$n} += $c; 2428 } 2429 close (FILE); 2430 }; 2431 2432 unlink ("${file}.old"); 2433 rename ($file, "${file}.old"); 2434 2435 open (FILE, "> $file") && do { 2436 my $g; 2437 foreach $g (sort {$inn_uw_ng{$b} <=> $inn_uw_ng{$a}} (keys (%inn_uw_ng))) { 2438 printf FILE "%d %s\n", $inn_uw_ng{$g}, $g; 2439 } 2440 close (FILE); 2441 chmod(0660, "$file"); 2442 }; 2443 unlink ("${file}.old"); 2444} 2445 2446########################################################################### 2447 2448# Compare 2 dates (+hour), used with sort (arguments $a and $b) 2449sub datecmp() { 2450 # ex: "May 12 06" for May 12, 6:00am 2451 # The 2 dates are near. The range is less than a few days that's why we 2452 # can cheat to determine the order. It is only important if one date 2453 # is in January and the other in December. 2454 2455 my($date1) = substr($a, 4, 2) * 24; 2456 my($date2) = substr($b, 4, 2) * 24; 2457 $date1 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($a,0,3)) * 288; 2458 $date2 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($b,0,3)) * 288; 2459 if ($date1 - $date2 > 300 * 24) { 2460 $date2 += 288 * 3 * 12; 2461 } 2462 elsif ($date2 - $date1 > 300 * 24) { 2463 $date1 += 288 * 3 * 12; 2464 } 2465 $date1 += substr($a, 7, 2); 2466 $date2 += substr($b, 7, 2); 2467 $date1 - $date2; 2468} 2469 2470sub host2dom($) { 2471 my $host = shift; 2472 2473 $host =~ m/^[^\.]+(.*)/; 2474 $host =~ m/^[\d\.]+$/ ? "unresolved" : $1 ? "*$1" : "?"; 2475} 2476 24771; 2478