diff options
Diffstat (limited to 'perl-install/standalone/logdrake')
| -rwxr-xr-x | perl-install/standalone/logdrake | 720 |
1 files changed, 377 insertions, 343 deletions
diff --git a/perl-install/standalone/logdrake b/perl-install/standalone/logdrake index 2b43eb087..562d91144 100755 --- a/perl-install/standalone/logdrake +++ b/perl-install/standalone/logdrake @@ -1,8 +1,7 @@ #! /usr/bin/perl -# $Id$ -# Copyright (C) 2001 MandrakeSoft -# Yves Duret <yduret at mandrakesoft.com> +# Copyright (C) 2001-2008 Mandriva +# Yves Duret <yduret at mandriva.com> # some code is Copyright: (C) 1999, Michael T. Babcock <mikebabcock@pobox.com> # # This program is free software; you can redistribute it and/or modify @@ -18,366 +17,361 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# TODO: consider switching from TreeView to gtkhtml - -use POSIX; -use Gtk; +use strict; use lib qw(/usr/lib/libDrakX); use standalone; #- warning, standalone must be loaded very first, for 'explanations' - +use c; +use common; use interactive; -use any; -use Config; -init Gtk; -Gtk->set_locale; -use my_gtk qw(:helpers :wrappers); -use ugtk qw(:helpers); - -use MDK::Common; -use Data::Dumper; -#------------------------------------------------------------- -# i18n routines -# IMPORTANT: next two routines have to be redefined here to -# get correct namespace (drakconf instead of libDrakX) -# (This version is now UTF8 compliant - Sg 2001-08-18) -#------------------------------------------------------------- - -#{ -# no warnings; -# sub _ { -# my $s = shift @_; my $t = translate($s); -# sprintf $t, @_; -# } - -# no warnings; -# sub translate { -# my ($s) = @_; -#$s ? c::dgettext('libDrakX', $s) : ''; -# } -#} +use do_pkgs; +use mygtk3 qw(gtknew); #- do not import gtkadd which conflicts with ugtk3 version +use ugtk3 qw(:create :dialogs :helpers :wrappers); -$::isInstall and die "Not supported during install.\n"; +$ugtk3::wm_icon = "/usr/share/mcc/themes/default/logdrake-mdk.png"; +my $in = 'interactive'->vnew('su'); -my $in = 'interactive'->vnew('su', 'default'); -my $cron_hourly = "/etc/cron.hourly/logdrake_service"; - -if ($::isEmbedded) { - print "EMBED\n"; - print "parent XID\t$::XID\n"; - print "mcc pid\t$::CCPID\n"; -} +my ($isExplain, $Explain, $isFile, $File, $isWord, $Word); #- parse arguments list. -for (@ARGV) { - /^--version$/ and die 'version: $Id$ '."\n"; - /^--help$/ and die 'logdrake [--version] [--file=myfyle] [--word=myword] [--explain=regexp] [--alert]'; - /^--explain=(.*)$/ and do { $::isExplain = ($::Explain) = $1; $::isFile = 1; $::File = "/var/log/explanations"; next }; - /^--file=(.*)$/ and do { $::isFile = ($::File) = $1; next }; - /^--word=(.*)$/ and do { $::isWord = ($::Word) = $1; next }; +foreach (@ARGV) { + /^--explain=(.*)$/ and do { $isExplain = ($Explain) = $1; $isFile = 1; $File = "/var/log/explanations"; next }; + /^--file=(.*)$/ and do { $isFile = ($File) = $1; next }; + /^--word=(.*)$/ and do { $isWord = ($Word) = $1; next }; /^--alert$/ and do { alert_config(); quit() }; } -$::isTail = 1 if ($::isFile); -$| = 1 if ($::isTail); +if (!$::testing) { + do_pkgs_standalone->new($in)->ensure_is_installed("syslog-daemon", "/etc/systemd/system/syslog.service") or exit(0); +} + +my $isTail = $isFile; +$| = 1 if $isTail; my $h = chomp_(`hostname -s`); -my $window = $::isEmbedded ? new Gtk::Plug ($::XID) : new Gtk::Window -toplevel; -$window->signal_connect(delete_event => sub { $::isEmbedded ? kill('USR1', $::CCPID) : Gtk->exit(0) }); -$window->set_title(N("logdrake")); -$window->set_policy(1, 1, 1); -$window->border_width (5) unless ($::isEmbedded); -#$window->set_default_size(540,460); +$ugtk3::wm_icon = "logdrake"; +my $explain_title = N("%s Tools Logs", N("Mageia")); +my $my_win = ugtk3->new($isExplain ? $explain_title : N("Logs")); -my $cal = gtkset_sensitive(new Gtk::Calendar(),0); -my (undef,undef,undef,$mday) = localtime(time); +unless ($::isEmbedded) { + $my_win->{window}->set_border_width(5); + #$my_win->{window}->set_default_size(540,460); +} +$my_win->{window}->signal_connect(delete_event => \&quit); + +my $cal = gtkset_sensitive(Gtk3::Calendar->new, 0); +my $mday = (localtime(time()))[3]; $cal->select_day($mday); my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); my $cal_mode = 0; -my $cal_butt = gtksignal_connect(new Gtk::CheckButton(N("Show only for the selected day")), clicked =>sub{ $cal_mode =!$cal_mode; gtkset_sensitive($cal,$cal_mode) }); +my $cal_butt = gtksignal_connect(Gtk3::CheckButton->new(N("Show only for the selected day")), clicked => sub { $cal_mode = !$cal_mode; gtkset_sensitive($cal,$cal_mode) }); ### menus definition # the menus are not shown -# but they provides shiny shortcut like C-q -my @menu_items = ( - { path => N("/_File"), type => '<Branch>' }, - { path => N("/File/_New"), accelerator => N("<control>N"), callback => \&print_hello }, - { path => N("/File/_Open"), accelerator => N("<control>O"),callback => \&print_hello }, - { path => N("/File/_Save"), accelerator => N("<control>S"),callback => \&save }, - { path => N("/File/Save _As") }, - { path => N("/File/-"),type => '<Separator>' }, - { path => N("/File/_Quit"), accelerator => N("<control>Q"), callback => \&quit }, - { path => N("/_Options"), type => '<Branch>' }, - { path => N("/Options/Test") }, - { path => N("/_Help"),type => '<LastBranch>' }, - { path => N("/Help/_About...") } - ); -my $menubar = ugtk::create_factory_menu($window, @menu_items); +# but they provides shiny shortcut like C-q (Broken: FIXME) +if ($::isEmbedded) { + my $ui = gtknew('UIManager', actions => [ + # [name, stock_id, value, label, accelerator, tooltip, callback] + [ 'FileMenu', undef, N("_File") ], + [ 'Save', undef, N("_Quit"), N("<control>S"), undef, \&save ], + [ 'Quit', undef, N("_Quit"), N("<control>Q"), undef, \&quit ], + ], + string => qq(<ui> + <menubar name='MenuBar'> + <menu action='FileMenu'> + <menuitem action='Save'/> + <menuitem action='Quit'/> + </menu> + </menubar> +</ui>)); + $my_win->{rwindow}->add_accel_group($ui->get_accel_group); +} ######### menus end ########## font and colors -my $n = Gtk::Gdk::Font->fontset_load(N("-misc-fixed-medium-r-*-*-*-100-*-*-*-*-*-*,*")); -my $b = Gtk::Gdk::Font->fontset_load(N("-misc-fixed-bold-r-*-*-*-100-*-*-*-*-*-*,*")); - -#$black = "\033[30m"; -#$red = "\033[31m"; -#$green = "\033[32m"; -#$yellow = "\033[33m"; -#$blue = "\033[34m"; -#$magenta = "\033[35m"; -#$purple = "\033[35m"; -#$cyan = "\033[36m"; -#$white = "\033[37m"; -#$darkgray = "\033[30m"; -#$col_norm = "\033[00m"; -#$col_background = "\033[07m"; -#$col_brighten = "\033[01m"; -#$col_underline = "\033[04m"; -#$col_blink = "\033[05m"; - -my $white = my_gtk::gtkcolor(50400, 655, 20000); -my $black = my_gtk::gtkcolor(0, 0, 0); -my $red = my_gtk::gtkcolor(0xFFFF, 655, 655); -my $green = my_gtk::gtkcolor(0x0, 0x9898,0x0); -my $yellow = my_gtk::gtkcolor(0xFFFF, 0xD7D7, 0); -my $blue = my_gtk::gtkcolor(655, 655, 0xFFFF); -my $magenta = my_gtk::gtkcolor(0xFFFF, 655, 0xFFFF); -my $purple = my_gtk::gtkcolor(0xA0A0, 0x2020, 0xF0F0); -my $cyan = my_gtk::gtkcolor(0x0, 0x9898, 0x9898); -my $darkgray = my_gtk::gtkcolor(0x2F2F, 0x4F4F, 0x4F4F); # Define global terms: # Define good notables: my @word_good = ("starting\n", "Freeing", "Detected", "starting.", "accepted.\n", "authenticated.\n", "Ready", "active", "reloading", "saved;", "restarting", "ONLINE\n"); my @word_warn = ("dangling", "closed.\n", "Assuming", "root", "root\n", "exiting\n", "missing", "Ignored", "adminalert:", "deleting", "OFFLINE\n"); -my @word_bad = ("bad"); +my @word_bad = "bad"; my @word_note = ("LOGIN", "DHCP_OFFER", "optimized", "reset:", "unloaded", "disconnected", "connect", "Successful", "registered\n"); -my @line_good = ("up", "DHCP_ACK", "Cleaned", "Initializing", "Starting", "success", "successfully", "alive", "found", "ONLINE\n"); -my @line_warn = ("warning:", "WARNING:", "invalid", "obsolete", "bad", "Password", "detected", "timeout", "timeout:", "attackalert:", "wrong", "Lame", "FAILED", "failing", "unknown", "obsolete", "stopped.\n", "terminating.", "disabled\n", "disabled", "Lost"); -my @line_bad = ("DENY", "lost", "shutting", "dead", "DHCP_NAK", "failure;", "Unable", "inactive", "terminating", "refused", "rejected", "down", "OFFLINE\n", "error\n", "ERROR\n", "ERROR:", "error", "ERROR", "error:", "failed:"); - -# Define specifics: -my @daemons = ("named"); +#my @line_good = ("up", "DHCP_ACK", "Cleaned", "Initializing", "Starting", "success", "successfully", "alive", "found", "ONLINE\n"); +#my @line_warn = ("warning:", "WARNING:", "invalid", "obsolete", "bad", "Password", "detected", "timeout", "timeout:", "attackalert:", "wrong", "Lame", "FAILED", "failing", "unknown", "obsolete", "stopped.\n", "terminating.", "disabled\n", "disabled", "Lost"); +#my @line_bad = ("DENY", "lost", "shutting", "dead", "DHCP_NAK", "failure;", "Unable", "inactive", "terminating", "refused", "rejected", "down", "OFFLINE\n", "error\n", "ERROR\n", "ERROR:", "error", "ERROR", "error:", "failed:"); # Now define what we want to use when: -my $col_good = $green; -my $col_warn = $yellow; -my $col_bad = $red; -my $col_note = $purple; -my $col = $cyan; +my $col_good = 'green4'; +my $col_warn = 'yellow4'; +my $col_bad = 'red'; +my $col_note = 'purple'; +my $col = 'darkcyan'; ######### font and colors end my %files = ( - "auth" => { file => "/var/log/auth.log", desc => N("Authentication") }, - "user" => { file => "/var/log/user.log", desc => N("User") }, - "messages" => { file => "/var/log/messages", desc => N("Messages") }, - "syslog" => { file => "/var/log/syslog", desc => N("Syslog") }, - "explanations" => { file => "/var/log/explanations", desc => N("Mandrake Tools Explanations") } + "auth" => { file => "/var/log/auth.log", desc => N("_:this is the auth.log log file\nAuthentication") }, + "user" => { file => "/var/log/user.log", desc => N("_:this is the user.log log file\nUser") }, + "messages" => { file => "/var/log/messages", desc => N("_:this is the /var/log/messages log file\nMessages") }, + "syslog" => { file => "/var/log/syslog", desc => N("_:this is the /var/log/syslog log file\nSyslog") }, + "explanations" => { file => "/var/log/explanations", desc => $explain_title } ); -my $yy = gtkset_sensitive(gtksignal_connect(new Gtk::Button(N("search")) , clicked => \&search),0); -my $log_text = new Gtk::Text(undef, undef); +my $yy = gtkset_sensitive(gtksignal_connect(Gtk3::Button->new(N("search")) , clicked => \&search),0); + +my $log_text = gtktext_insert(Gtk3::TextView->new, [ [ '' ] ]); + +my $log_buf = $log_text->get_buffer; my $refcount_search; #### far from window -gtkadd($window, - gtkpack_(new Gtk::VBox(0,0), - if_(!$::isExplain && !$::isEmbedded, 0, N("A tool to monitor your logs")), - if_(!$::isFile, 0, gtkadd(new Gtk::Frame(N("Settings")), - gtkpack__(new Gtk::VBox(0,2), - gtkpack__(new Gtk::VBox(0,2), - # N("Show lines"), - gtkpack__(new Gtk::HBox(0,0), - " " . N("matching") . " ", $e_yes = new Gtk::Entry(), - " " . N("but not matching") . " ", $e_no = new Gtk::Entry() - ) - ), - gtkpack_(new Gtk::HBox(0,0), - 1, gtkadd(gtkset_border_width(new Gtk::Frame(N("Choose file")),2), - gtkpack (gtkset_border_width(new Gtk::VBox(0,0),0), - map { ${ "b_". $_ } = gtksignal_connect(new Gtk::CheckButton($files{ $_ }{desc}), clicked => sub{ $refcount_search++; gtkset_sensitive($yy,$refcount_search) }) } keys %files, + +my %toggle; + +gtkadd($my_win->{window}, + gtkpack_(Gtk3::VBox->new(0,0), + if_(!$::isEmbedded, 0, gtknew('Title1', label => N("A tool to monitor your logs"))), + if_(!$isFile, 0, gtkpack__(Gtk3::VBox->new(0,2), + gtknew('Title2', label => N("Settings")), + # N("Show lines"), + gtkpack__(Gtk3::HBox->new(0,0), + " " . N("Matching") . " ", my $e_yes = Gtk3::Entry->new, + " " . N("but not matching") . " ", my $e_no = Gtk3::Entry->new + ), + gtkpack_(Gtk3::HBox->new(0,0), + 1, gtkadd(gtkset_border_width(Gtk3::Frame->new(N("Choose file")),2), + gtkpack(gtkset_border_width(Gtk3::VBox->new(0,0),0), + map { $toggle{$_} = gtksignal_connect(Gtk3::CheckButton->new($files{$_}{desc}), + clicked => sub { + $refcount_search++; + gtkset_sensitive($yy, $refcount_search); + }); + $toggle{$_}->set_sensitive(0) if !-f $files{$_}{file}; + $toggle{$_}; + } sort keys %files, ) ), - 0, gtkadd(gtkset_border_width(new Gtk::Frame(N("Calendar")),2), - gtkpack__(gtkset_border_width(new Gtk::VBox(0,0),5), - $cal_butt, $cal + 0, gtkadd(gtkset_border_width(Gtk3::Frame->new(N("Calendar")),2), + gtkpack__(gtkset_border_width(Gtk3::VBox->new(0,0),5), + $cal_butt, $cal ) ) - ), - $yy, + ), + $yy, ) - ) - ), - !$::isExplain ? (1, gtkadd(new Gtk::Frame(N("Content of the file")), - createScrolledWindow($log_text) - )) : (1, createScrolledWindow($log_text)), - if_(!$::isExplain, 0, gtkadd (gtkset_border_width(gtkset_layout(new Gtk::HButtonBox,-end), 5), - if_(!$::isFile, gtksignal_connect(new Gtk::Button (N("Mail alert")), - clicked => sub { eval { alert_config() }; - if ($@ =~ /wizcancel/) { - $::Wizard_no_previous = 1; - $::Wizard_no_cancel = 1; - $::WizardWindow->destroy if defined $::WizardWindow; - undef $::WizardWindow; - } })), - gtksignal_connect(new Gtk::Button (N("Save")), clicked => \&save), - gtksignal_connect(new Gtk::Button ($::isEmbedded ? N("Cancel") : N("Quit")), clicked => \&quit) - ) - ) - ) - - ); - -$::isFile and gtkset_usize($log_text,400,500); -$window->realize; -$window->show_all(); -search() if ($::isFile); -#Gtk->main_iteration while Gtk->events_pending; -$::isEmbedded and kill 'USR2', $::CCPID; -Gtk->main; - -sub quit { -$::isEmbedded ? kill('USR1', $::CCPID) : Gtk->exit(0); -} + ), + !$isExplain ? (0, gtknew('Title2', label => N("Content of the file")), + 1, create_scrolled_window($log_text) + ) : (1, create_scrolled_window($log_text)), + 0, gtkadd(gtkset_border_width(gtkset_layout(Gtk3::HButtonBox->new, 'end'), 5), + if_(!$isFile, gtksignal_connect(Gtk3::Button->new(N("Mail alert")), + clicked => sub { + eval { alert_config() }; + my $err = $@; + $::WizardWindow->destroy if defined $::WizardWindow; + undef $::WizardWindow; + if ($err && $err !~ /wizcancel/) { + err_dialog(N("Error"), N("The alert wizard has failed unexpectedly:") + . "\n\n" . $err); + } + })), + gtksignal_connect(Gtk3::Button->new(N("Save")), clicked => \&save), + gtksignal_connect(Gtk3::Button->new($::isEmbedded ? N("Cancel") : N("Quit")), clicked => \&quit) + ) + ) + ); + +$isFile && !$::isEmbedded and gtkset_size_request($log_text, 400, 500); + +$my_win->{window}->show_all; +search() if $isFile; +$my_win->main; + +sub quit() { ugtk3->exit(0) } #------------------------------------------------------------- # search functions #------------------------------------------------------------- -sub search { - $log_text->backward_delete($log_text->get_length()); - $log_text->freeze(); - if ($::isFile) { - parse_file($::File); +sub search() { + my $window = $log_text->get_window('widget'); + return if !$window; + $window->freeze_updates; + $log_buf->set_text(''); + if ($isFile) { + parse_file($File, $File); } else { foreach (keys %files) { - parse_file($files{ $_ }{file}) if ${ $::{ "b_". $_ }}->active - }; + parse_file($files{$_}{file}, $files{$_}{desc}) if $toggle{$_}->get_active; + } } - $log_text->thaw(); - Gtk->main_iteration while Gtk->events_pending; + $window->thaw_updates; + $log_text->show; + gtkflush(); } +my $timer; + +my @logs; + +my $F; + sub parse_file { - my $file = $_[0]; + my ($file, $descr) = @_; $file =~ s/\.gz$//; - my $i = 0; - gtkadd(my $win_pb = (gtkset_modal new Gtk::Window(), 1), - gtkpack(new Gtk::VBox(5,0), - " " . N("please wait, parsing file: %s", $files{ $_ }{desc}) . " ", - my $pbar = new Gtk::ProgressBar() - ) - ); - $win_pb->set_position('center'); - $win_pb->realize(); - $win_pb->show_all(); + my ($pbar, $win_pb); + unless ($::isEmbedded && $isExplain) { + local $::main_window = $my_win->{real_window}; + gtkadd($win_pb = gtkset_modal(Gtk3::Window->new('toplevel'), 1), + gtkpack(Gtk3::VBox->new(2,0), + Gtk3::Label->new(" " . N("please wait, parsing file: %s", $descr) . " "), + $pbar = Gtk3::ProgressBar->new + ) + ); + $win_pb->set_transient_for($my_win->{real_window}); + $win_pb->set_position('center'); + $win_pb->realize; + $win_pb->show_all; + gtkflush(); + } my $ey = $e_yes->get_chars(0, -1); my $en = $e_no->get_chars(0, -1); - $ey =~ s/ OR /\|/; + $ey =~ s/ OR /|/; $ey =~ s/^\*$//; $en =~ s/^\*$/.*/; - $ey = $ey .($::Word) if ($::isWord); + $ey = $ey . $Word if $isWord; if ($cal_mode) { - my ($year, $month, $day) = $cal->get_date(); - $ey = $months[$month]."\\s{1,2}$day\\s.*$ey.*\n"; + my (undef, $month, $day) = $cal->get_date; + $ey = $months[$month] . "\\s{1,2}$day\\s.*$ey.*\n"; } - my @all = catMaybeCompressed ($file); + my @all = -e $file ? catMaybeCompressed($file) : N("Sorry, log file isn't available!"); - if ($::isExplain) { + if ($isExplain) { my (@t, $t); while (@all) { $t = pop @all; - next if ($t =~ /logdrake/); - last if !($t =~ /$::Explain/); + next if $t =~ /logdrake/; + last if $t !~ /$Explain/; push @t, $t; } @all = reverse @t; } my $taille = @all; + my $i = 0; + my $test; + if ($en && !$ey) { + $test = sub { $_[0] !~ /$en/ }; + } elsif ($ey && !$en) { + $test = sub { $_[0] =~ /$ey/ }; + } else { + $test = sub { $_[0] =~ /$ey/ && $_[0] !~ /$en/ }; + } + foreach (@all) { $i++; - if ($i % 10) { - $pbar->update($i/$taille); - Gtk->main_iteration while Gtk->events_pending; + if ($pbar && $i % 10) { + $pbar->set_fraction($i/$taille); + $win_pb->get_window->process_updates(1); # no gtkflush() because we do not want to refresh the TextView } - if (($en eq "") and /$ey/i) { logcolorize($_); next } - if ((! /$en/i) and /$ey/i) { logcolorize($_); next } - if ((! /$en/i) and ($ey eq "")) { logcolorize($_); next } + logcolorize($_) if $test->($_); } - $win_pb->destroy(); - - if ($::isTail) { - open F, $file or die "E: $!"; - while (<F>) {}; #to prevent to output the file twice.. - $log_text->set_point($log_text->get_length()); - my $timer = Gtk->timeout_add(1000, \&input_callback); + $win_pb->destroy if !$::isEmbedded || !$isExplain; + + if ($isTail) { + close $F if $F; + if (open $F, $file) { + local $_; + while (<$F>) {} #to prevent to output the file twice.. + # $log_text->set_point($log_text->get_length()); + $timer ||= Glib::Timeout->add(1000, sub { + logcolorize($_) while <$F>; + seek $F, 0, 1; + }); + } else { + my $error = $!; + my $string = chomp_(`LC_ALL=C date '+%b %d %T'`) . " " . + N("Error while opening \"%s\" log file: %s\n", $file, $error); + # `` return non utf8 and concat of non utf8 & utf8 is non utf8: + c::set_tagged_utf8($string); + logcolorize($string); + } } -} - -sub input_callback { - logcolorize($_) while <F>; - seek F, 0, 1; + insert_text_n_scroll(); } ########################################################################################## sub logcolorize { - + my ($string) = @_; # we get date & time if it is date & time (dmesg) - s/(\D{3} .. (\d\d:\d\d:\d\d ))//; - $timestamp = $::isExplain ? $2 : $1; - @rec = split; - - log_output($cyan,$timestamp,$b); # date & time if any... - $::isExplain or log_output(($rec[0] eq $h) ? $blue : $col,"$rec[0] ",$b); # hostname + $string =~ s/(\D{3} .. (\d\d:\d\d:\d\d ))//; + my $timestamp = $isExplain ? $2 : $1; + my @rec = split(/\s/, $string); + @rec = map { c::set_tagged_utf8($_); $_ } @rec if utf8::is_utf8($string); + + log_output($timestamp, 'Bold', 'darkcyan'); # date & time if any... + # BUG: $col hasn't yet be reseted + $isExplain or log_output("$rec[0] ", 'Bold', $rec[0] eq $h ? 'blue' : $col); # hostname if ($rec[1] eq "last") { - log_output($green," last message repeated ",$n); - log_output($green, $rec[4], $b); - log_output($green," times\n",$n); + log_output(" last message repeated ", undef, 'green'); + log_output($rec[4], 'Bold', 'green'); + log_output(" times\n", undef, 'green'); return; } # Extract PID if present - if ($rec[1] =~ /\[(\d+)\]\:/) { - my($pid) = $1; - $rec[1] =~s/\[$1\]\:// ; - log_output ($green, $rec[1] ."[",$n); - log_output ($black, $pid,$b); - log_output ($green, "]: ",$n); + if ($rec[1] =~ /\[(\d+)\]:/) { + my $pid = $1; + $rec[1] =~ s/\[$1\]://; + log_output($rec[1] . "[", undef, 'green'); + log_output($pid, 'Bold', 'black'); + log_output("]: ", undef, 'green'); } else { - log_output($green, $rec[1] ." ",$n); + log_output($rec[1] . " ", undef, 'green'); } - - for ($therest = (2); $therest<= $#rec; $therest++) { - $col = $cyan; + foreach my $therest (2 .. $#rec) { + $col = 'darkcyan'; # Check for keywords to highlight - foreach (@word_good) { $col = $col_good if ($_ eq $rec[$therest]) } - foreach (@word_warn) { $col = $col_warn if ($_ eq $rec[$therest]) } - foreach (@word_bad) { $col = $col_bad if ($_ eq $rec[$therest]) } - foreach (@word_note) { $col = $col_note if ($_ eq $rec[$therest]) } + foreach (@word_good) { $col = $col_good if $_ eq $rec[$therest] } + foreach (@word_warn) { $col = $col_warn if $_ eq $rec[$therest] } + foreach (@word_bad) { $col = $col_bad if $_ eq $rec[$therest] } + foreach (@word_note) { $col = $col_note if $_ eq $rec[$therest] } # Watch for words that indicate entire lines should be highlighted - #foreach (@line_good) { $col = $col_good if ($_ eq $rec[$therest]) } - #foreach (@line_warn) { $col = $col_warn if ($_ eq $rec[$therest]) } - #foreach (@line_bad) { $col = $col_bad if ($_ eq $rec[$therest]) } + #foreach (@line_good) { $col = $col_good if $_ eq $rec[$therest] } + #foreach (@line_warn) { $col = $col_warn if $_ eq $rec[$therest] } + #foreach (@line_bad) { $col = $col_bad if $_ eq $rec[$therest] } - log_output($col,"$rec[$therest] ",$n); + log_output("$rec[$therest] ", undef, $col); } - log_output($black,"\n",$n); + log_output("\n", undef, 'black'); + insert_text_n_scroll() if $isExplain; } +# log_output (Gtk3::TextView, [ [ ... ] ]) sub log_output { - $log_text->insert($_[2],$_[0], undef,$_[1]); + my ($text, $font, $col) = @_; + my $tag = join('', $font, $col); + push @logs, [ $text, $tag ]; + $log_buf->{tags}{$tag} ||= { foreground => $col }; # if_($font, font => $font), +} + +sub insert_text_n_scroll() { + ugtk3::gtktext_insert($log_text, \@logs, append => 1); + $log_text->scroll_to_iter($log_buf->get_end_iter, 0, 1, 0.5, 0.5); + undef @logs; } @@ -385,34 +379,16 @@ sub log_output { # mail/sms alert #------------------------------------------------------------- -sub alert_config { - - $::isWizard = 1; - $::Wizard_pix_up = "wiz_logdrake.png"; # FIXME - $::Wizard_title = N("Mail alert"); +sub alert_config() { + local $::isEmbedded = 0; + undef $::WizardTable; + undef $::WizardWindow; + my $conffile = "/etc/sysconfig/mail_alert"; + my %options = getVarsFromSh($conffile); + $options{LOAD} ||= 3; + $options{MAIL} ||= "root"; + $options{SMTP} ||= "localhost"; - my $cron = q(#!/usr/bin/perl -# generated by logdrake -use MDK::Common; -my $r = "*** ". chomp_(`date`) . " ***\n"; - -); - -my $initdir = "/etc/init.d"; - - my ($load,$mail,$email,$smtp,); - $load = 3; - - begin: - $::Wizard_finished = 0; - $::Wizard_no_previous = 1; - $in->ask_okcancel(N("Mail alert configuration"), - N("Welcome to the mail configuration utility.\n\nHere, you'll be able to set up the alert system.\n"), - 1) or quit(); - - step_service: - undef $::Wizard_no_previous; - undef $::Wizard_finished; my $service = { httpd => N("Apache World Wide Web Server"), bind => N("Domain Name Resolver"), @@ -423,68 +399,124 @@ my $initdir = "/etc/init.d"; webmin => N("Webmin Service"), xinetd => N("Xinetd Service") }; - my @installed_d = (); - foreach $serv (keys %$service) { - -e "$initdir/$serv" && push (@installed_d,$serv); - } - - $in->ask_from(N("service setting"), - N("You will receive an alert if one of the selected services is no more running"), - [ map { { label => "$_", val => \${ $_ }, type => "bool", text => "$service->{ $_ }" } } @installed_d - ]) or goto begin; - - $cron .= "#- check services\n"; - foreach (@installed_d) { - if(!-e "/var/lock/subsys/$_") { $r .= "Service $_ ($service->{$_} is not running\n" }; -# $cron .= "$r" if ${ $_ }; # take a look at this, don't know what is done here - } + my @installed_d = grep { -e "/etc/init.d/$_" } sort keys %$service; + my %services_to_check = map { $_ => 1 } split(':', $options{SERVICES}); - step_load: - undef $::Wizard_finished; - $in->ask_from(N("load setting"), - N("You will receive an alert if the load is higher than this value"), - [ - { label => "load ", val => \$load, type => 'range', min => 1, max => 50 }, - ]) or goto step_service; + $::isWizard = 1; + my $mode; + my $cron_file = "/etc/cron.hourly/logdrake_service"; + my %modes = ( + configure => N("Configure the mail alert system"), + disable => N("Stop the mail alert system"), + ); + require wizards; + my $wiz = wizards->new({ + defaultimage => "logdrake.png", + name => N("Mail alert"), + pages => { + welcome => { + name => N("Mail alert configuration") . "\n\n" . + N("Welcome to the mail configuration utility.\n\nHere, you'll be able to set up the alert system.\n"), + no_back => 1, + data => [ + { val => \$mode, label => N("What do you want to do?"), + list => [ keys %modes ], format => sub { $modes{$_[0]} }, }, + ], + + post => sub { $mode eq 'configure' ? 'services' : 'stop' }, + }, + services => { + name => N("Services settings") . "\n\n" . + N("You will receive an alert if one of the selected services is no longer running"), + data => [ map { { label => $_, val => \$services_to_check{$_}, + type => "bool", text => $service->{$_} } } @installed_d ], + next => "load", + }, + load => { + #PO- Here "load" is a noun; that is load refers to the system/CPU) load + name => N("Load setting") . "\n\n" . + N("You will receive an alert if the load is higher than this value"), + data => [ { label => N("_: load here is a noun, the load of the system\nLoad"), + val => \$options{LOAD}, type => 'range', min => 1, max => 50 } ], + next => "email", + }, + email => { + name => N("Alert configuration") . "\n\n" . + N("Please enter your email address below ") . "\n" . + N("and enter the name (or the IP) of the SMTP server you wish to use"), + data => [ + { label => N("Email address"), val => \$options{MAIL} }, + { label => N("Email server"), val => \$options{SMTP} }, + ], + complete => sub { + if ($options{MAIL} !~ /[\w.-]*\@[\w.-]/ && !member($options{MAIL}, map { $_->[0] } list_passwd())) { + err_dialog(N("Error"), N("\"%s\" neither is a valid email nor is an existing local user!", + $options{MAIL})); + return 1; + } + if (member($options{MAIL}, map { $_->[0] } list_passwd()) && $options{SMP} !~ /localhost/) { + err_dialog(N("Error"), N("\"%s\" is a local user, but you did not select a local smtp, so you must use a complete email address!", $options{MAIL})); + return 1; + } + }, + next => "end", + }, + end => { + name => N("Congratulations") . "\n\n" . N("The wizard successfully configured the mail alert."), + end => 1, + no_back => 1, + }, + stop => { + pre => sub { eval { rm_rf($cron_file) } }, + name => N("Congratulations") . "\n\n" . N("The wizard successfully disabled the mail alert."), + end => 1, + no_back => 1, + }, + }, + }); + $wiz->process($in); + return if $mode eq 'disable'; + + $options{SERVICES} = join ':', grep { $services_to_check{$_} } sort keys %services_to_check; + + use Data::Dumper; + output_with_perm $cron_file, 0755, q(#!/usr/bin/perl +# generated by logdrake +use MDK::Common; +my $r; +my %options = getVarsFromSh("/etc/sysconfig/mail_alert"); + +#- check services +my ) . Data::Dumper->Dump([ $service ], [qw(*services)]) . q( +foreach (split(':', $options{SERVICES})) { + next unless $services{$_}; + $r .= "Service $_ ($services{$_} is not running)\\n" unless -e "/var/lock/subsys/$_"; +} - $cron .= q@ #- load my ($load) = split ' ', first(cat_("/proc/loadavg")); -$r .= "Load is huge: $load\n" if ($load >@ . "$load);\n\n"; - - step_output: -# $::Wizard_no_previous = 1; - $::Wizard_finished = 1; - $in->ask_from(N("alert configuration"), - N("Please enter your email address below "), - [ - { label => "" }, - { label => "Email", val => \$email}, - ]) or goto step_load; - - $cron .= q@#- report it@; - $cron .= q@ -$email = @. "'" . "$email" . "'" . ";\n\n"; - - $cron .= q! -open F, '|/usr/sbin/sendmail -oi -t'; - -print F -q(Subject: logdrake Mail Alert -From: root@localhost -To: ), "$email\n"; -print F $r; - -# EOF!; - output "$cron_hourly", $cron; - chmod 0755, $cron_hourly; - - print ("whole cron is ****** $cron *******\n"); - - undef $::isWizard; - $::WizardWindow->destroy if defined $::WizardWindow; - undef $::WizardWindow; +$r .= "Load is huge: $load\n" if $load > $options{LOAD}; + +#- report it +if ($r) { + use Mail::Mailer; + my $mailer = Mail::Mailer->new('smtp', Server => $options{SMTP}); + $mailer->open({ From => 'root@localhost', + To => $options{MAIL}, + Subject => "DrakLog Mail Alert", + }) + or die "Cannot open: $!\n"; + print $mailer $r; + $mailer->close; +} +# EOF); + setVarsInSh($conffile, \%options); + + if (defined $::WizardWindow) { + $::WizardWindow->destroy; + undef $::WizardWindow; + } } @@ -493,8 +525,10 @@ print F $r; #------------------------------------------------------------- -sub save { - $::isWizard=0; - $yy = $in->ask_file(N("Save as.."),"/root") or return; - output($yy,$log_text->get_chars(0,$log_text->get_length())); +sub save() { + $::isWizard = 0; + my $y = $in->ask_filename({ title => N("Save as.."), directory => "/root", save => 1 }) or return; + my $buf = $log_text->get_buffer; + my ($start, $end) = $buf->get_bounds; + output($y, $buf->get_text($start, $end, 0)); } |
