summaryrefslogtreecommitdiffstats
path: root/perl-install/standalone/logdrake
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/standalone/logdrake')
-rwxr-xr-xperl-install/standalone/logdrake720
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));
}