Hmmm, du stellst aber Fragen ... ;)
Also ich würde monitor.pl nur zum Starten verwenden.
Nehmen wir die Beispielstruktur aus einem vorherigen Thread:
bin/monitor.pl
etc/monitor.conf
lib/Linux/Monitor.pm
lib/Linux/Monitor/Memory.pm
lib/Linux/Monitor/CPU.pm
lib/Linux/Monitor/Disk.pm
lib/Linux/Monitor/Net.pm
Dann könnte monitor.pl so ausssehen:
#!/usr/bin/perl
use strict;
use warnings;
my $BASEDIR; # danke @pq für den Tipp
BEGIN {
use FindBin;
$BASEDIR = $FindBin::Bin;
$BASEDIR =~ s@/bin$@@;
}
use lib "$BASE_DIR/lib";
use Linux::Monitor;
Linux::Monitor->run($BASEDIR);
Die gesamte Steuerung wird dann in Linux/Monitor.pm erledigt.
Wenn die Config (etc/monitor.conf) wie folgt aussieht:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
interval = 60
<check>
name = Linux::Monitor::Memory
active = 1
<set_options>
foo = 1
bar = 2
baz = 3
</set_options>
</check>
<check>
name = Linux::Monitor::Net
active = 1
<set_options>
foo = 1
bar = 2
baz = 3
</set_options>
</check>
Könnte lib/Linux/Monitor.pm so aussehen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package Linux::Monitor;
use strict;
use warnings;
use Config::General;
use UNIVERSAL::require;
use Carp;
# Falls der Interval nicht in der Config
# gesetzt oder auf 0 steht, nehmen
# wir INTERVAL als Default
use constant INTERVAL => 60;
sub run {
my ($class, $basedir) = @_;
my $self = bless {
basedir => $basedir,
loaded => { },
}, $class;
my $config = $self->get_config("$basedir/etc/monitor.conf");
$self->{config} = $config;
while ( 1 ) {
$self->run_monitor();
sleep $config->{interval};
}
}
sub run_monitor {
my $self = shift;
my $config = $self->{config};
my $loaded = $self->{loaded};
my %status = ();
foreach my $check (@{$config->{check}}) {
# next wenn der Check nicht aktiv ist
next unless $check->{active};
my $module = $check->{name};
# Nur require ausführen, wenn das Modul
# noch nicht geladen wurde
if (!exists $loaded->{$module}) {
$module->require or croak "Unable to require '$module'";
$loaded->{$module} = 1;
}
# Das Checkmodul muss die Routinen
# new(), set_options() und get() besitzen!
my $obj = $module->new();
if (exists $check->{set_options}) {
$obj->set_options($check->{set_options});
}
$status{$module} = $obj->get();
}
# Die Daten verarbeiten....
$self->process_status(\%status);
}
sub get_config {
my ($self, $config_file) = @_;
my $config = Config::General->new($config_file);
my %config = $config->getall();
# Check sollte immer ein Array sein, damit
# wir dies später nicht mehr prüfen müssen
if (exists $config{check}) {
if (ref($config{check}) eq 'HASH') {
$config{check} = [ $config{check} ];
}
} else {
croak "Nothing to do!";
}
# Interval setzen
if (!$config{interval}) {
$config{interval} = INTERVAL;
}
return \%config;
}
1;
Das habe ich eben schnell zusammen gehackt... debuggen, erweitern,
verschönern, verbessern und den ganzen $foo musst du selber, aber
es sollte ein Ansatz sein.
Wenn du dich mit Modulen etc. noch nicht so gut auskennst, dann solltest
du dir die Perldoc durchlesen. :)
Gruss
bloonix
Edit: pq's Einwand berücksichtigt + einige diverse Änderungen
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.