Committer: ldoolan
add --host optionU trunk/bin/schwartzmon
Modified: trunk/bin/schwartzmon =================================================================== --- trunk/bin/schwartzmon 2010-06-30 20:53:59 UTC (rev 154) +++ trunk/bin/schwartzmon 2010-10-13 14:52:40 UTC (rev 155) @@ -7,6 +7,8 @@ my $user = "root"; my $pass = ""; my $job = ""; +my $host = ''; +my $dsn = ''; my $max_age = 0; my $max_count = 0; @@ -17,15 +19,15 @@ Possible commands: queues View past-due job queue depths. (default cmd) errors View errors. - drop-jobs Drop specified jobs from DB Global options: - --job|func=<JOBNAME> Only look at one specific job name. Else all are considered. + --job=<JOBNAME> Only look at one specific job name. Else all are considered. --user=<user> Connect to the database as this user --pass=<pass> Connect to the database with this password --database=<db> Connect to this database + --host=<host> Connect to this host --dsn=<dsn> Connect to the database using this DSN - + Options for 'queues' command: --maxage=<n> Don't complain if age of overdue job queue is <= 'n' --maxcount=<n> Don't complain if depth of overdue job queue is <= 'n' @@ -35,12 +37,20 @@ --last=n Show last 'n' errors from log --inlast=n Show errors in last 'n' seconds -Options for 'drop-jobs' command: - --limit=n Drop no more than N jobs at once - Verbosity: if no alerts, nothing is printed, and exit status is 0. +host,dsn: + --host is like 'bil1-schdb01' + --dsn is like 'DBI:mysql:theschwartz_livejournal;host=172.21.8.192' + or like 'DBI:mysql:theschwartz_livejournal;host=bil1-schdb01' + + if both of --host and --dsn are specified then --host is silently + ignored. This need not necessarily be the case, of course, but we + would have to establish some kind of convetion for what happens + when both are specified and that is just out of the question right + now. + Exit status: 0 if no alerts, non-zero if there are alerts, in which case the alerts are printed. @@ -50,9 +60,9 @@ } my $opt_help = 0; -my ($opt_follow, $opt_last, $opt_inlast, $dsn, $limit); -usage() unless GetOptions("job|func=s" => \$job, - "maxage=i" => \$max_age, +my ($opt_follow, $opt_last, $opt_inlast, $opt_func); +usage() unless GetOptions("job=s" => \$job, + "maxage=i" => \$max_age, "maxcount=i" => \$max_count, "help" => \$opt_help, "follow|f" => \$opt_follow, @@ -60,18 +70,24 @@ "inlast=i" => \$opt_inlast, "user=s" => \$user, "pass=s" => \$pass, + "host=s" => \$host, "dsn=s" => \$dsn, "database=s" => \$dbname, - "limit=i" => \$limit, + "func=s" => \$opt_func, ); usage() if $opt_help; +## if both of --host and --dsn are specified, then --host is silently ignored +$host= '' if (length($host) && length($dsn)); + my $cmd = shift || "queues"; usage() unless $cmd =~ /^queues|errors|drop-jobs$/; my $dbset = DBSet->new; -$dsn ||= "DBI:mysql:$dbname"; +$dsn= "DBI:mysql:$dbname" unless $dsn; +$dsn .= ";host=$host" if $host; +print "\$user= $user, \$pass= $pass, \$dsn=$dsn\n"; $dbset->add(DBHandle->new({ dsn => $dsn, user => $user, pass => $pass})); @@ -94,23 +110,19 @@ sub queues { my $dbs = shift; my $some_alert = 0; - $dbs->foreach(sub { my $db = shift; my $dbh = $db->dbh or next; - my $prefix = _get_prefix($dbh); - my $funcmap = _get_funcmap($dbh); - - foreach my $funcname (sort keys %$funcmap) { + my $funcmap = $dbh->selectall_hashref("SELECT funcid, funcname FROM funcmap", "funcid"); + + foreach my $funcid (sort { $funcmap->{$a}{funcname} cmp $funcmap->{$b}{funcname} } keys %$funcmap) { + my $funcname = $funcmap->{$funcid}{funcname}; next if $job && $funcname ne $job; - my $funcid = $funcmap->{$funcname}; - + my $now = time(); - my $inf = $dbh->selectrow_hashref( - "SELECT COUNT(*) as 'ct', MIN(run_after) 'oldest' FROM ${prefix}job WHERE funcid=? AND run_after <= $now", - undef, $funcid - ); + my $inf = $dbh->selectrow_hashref("SELECT COUNT(*) as 'ct', MIN(run_after) 'oldest' FROM job WHERE funcid=? AND run_after <= $now", + undef, $funcid); my $behind = $inf->{ct} ? ($now - $inf->{oldest}) : 0; # okay by default, then we apply rules: @@ -143,32 +155,29 @@ my $dbh = $db->dbh or next; - my $prefix = _get_prefix($dbh); - my $funcmap = _get_funcmap($dbh); + my $funcmap = $dbh->selectall_hashref("SELECT funcid, funcname FROM funcmap", "funcid"); my $extra_where = ''; - if ($job) { - my $funcid = $funcmap->{$job}; - die "unknown functions $job" unless defined $funcid; + if ($opt_func) { + my $funcid = $db->funcid_of_func($opt_func) || 0; $extra_where = "AND funcid=$funcid"; } my $sql; if ($opt_last) { - $sql = "SELECT error_time, jobid, message, funcid FROM ${prefix}error WHERE 1=1 $extra_where " . + $sql = "SELECT error_time, jobid, message, funcid FROM error WHERE 1=1 $extra_where " . "ORDER BY error_time DESC LIMIT $opt_last"; } elsif ($opt_inlast) { my $since = time() - $opt_inlast; - $sql = "SELECT error_time, jobid, message, funcid FROM ${prefix}error WHERE error_time >= $since $extra_where " . + $sql = "SELECT error_time, jobid, message, funcid FROM error WHERE error_time >= $since $extra_where " . "ORDER BY error_time LIMIT 50000"; } my $sth = $dbh->prepare($sql); $sth->execute; - my %reverse_funcmap = reverse %$funcmap; while (my $r = $sth->fetchrow_hashref) { - $r->{funcname} = $reverse_funcmap{ $r->{funcid} }; + $r->{funcname} = $funcmap->{$r->{funcid}}{funcname}; push @rows, $r; } }); @@ -198,9 +207,8 @@ my $seen = $notes->{seen} ||= {}; my $extra_where = ''; - if ($job) { - my $funcid = $db->funcid_of_func($job); - die "Unknown job $job" unless defined $funcid; + if ($opt_func) { + my $funcid = $db->funcid_of_func($opt_func) || 0; $extra_where = "AND funcid=$funcid"; } @@ -243,53 +251,42 @@ sub drop_jobs { my $dbs = shift; - unless ($job) { + unless ($opt_func){ ## we need to know what to remove. - print "drop-jobs command needs defined job. Use --job option for this.\n"; + print "drop-jobs command needs defined func. use --func option for this.\n"; exit 0; } $dbs->foreach(sub { my $db = shift; my $dbh = $db->dbh or next; - - my $prefix = _get_prefix($dbh); - my $funcid = _get_funcmap($dbh)->{$job}; - die "Unknown job $job" unless defined $funcid; - + + ## On dev servers TheSchwartz tables have 'sch_' prefix. On production they don't. + my $prefix = ''; + # show tables like 'sch_%'; + my $tables = $dbh->selectall_arrayref("show tables like 'sch_%'"); + if (grep { $_->[0] =~ /^(sch_job|sch_funcmap)$/} @$tables and not ## there are dev tables + grep { $_->[0] =~ /^(job|funcmap)$/ } @$tables ## and no production tables + ){ + $prefix = "sch_"; + } + + ## func -> funcid + my ($funcid) = $dbh->selectrow_array("SELECT funcid FROM ${prefix}funcmap WHERE funcname=?", undef, $opt_func); + unless ($funcid){ + print "Unknown func '$opt_func' \n"; + return; + } + ## remove jobs with this funcid - my $limit_clause = ($limit) ? "LIMIT $limit" : ''; - my $res = $dbh->do("DELETE FROM ${prefix}job WHERE funcid=? $limit_clause", undef, $funcid); + my $res = $dbh->do("DELETE FROM ${prefix}job WHERE funcid=?", undef, $funcid); $res = 0 if $res eq "0E0"; print "Removed: $res job(s)\n"; + }); } -sub _get_prefix { - my $dbh = shift; - - ## On dev servers TheSchwartz tables have 'sch_' prefix. On production they don't. - my $tables = $dbh->selectall_arrayref("show tables like 'sch_%'"); - if (grep { $_->[0] =~ /^(sch_job|sch_funcmap)$/} @$tables) { - return "sch_"; - } else { - return ''; - } -} -sub _get_funcmap { - my $dbh = shift; - - my $prefix = _get_prefix($dbh); - - ## func -> funcid - my %map; - foreach my $r (@{$dbh->selectall_arrayref("SELECT funcname, funcid FROM ${prefix}funcmap")}) { - $map{ $r->[0] } = $r->[1]; - } - return \%map; -} - package DBSet; sub new { @@ -324,7 +321,7 @@ sub dbh { my $self = shift; return $self->{_dbh} ||= - DBI->connect($self->{dsn}, $self->{user}, $self->{pass}, {RaiseError => 1}) + DBI->connect($self->{dsn}, $self->{user}, $self->{pass}) }