Schrift
[thread]4432[/thread]

Zeitüberwachung für ein Script

Leser: 4


<< >> 9 Einträge, 1 Seite
Gast Gast
 2006-07-24 12:29
#37321 #37321
Hallo,

ich habe folgendes Problem:

für mein Programm möchte ich eine Zeitüberwachung realisieren, diese soll aber nicht im Programm stattfinden.

dazu habe ich mir folgendes überlegt:

- ich programmiere einen kleinen "Zeitüberwachungsserver od. Daemon"
- wenn mein Programm gestartet wird, sendet es die max. Laufzeitdauer an den "Zeitüberwachungsserver", dieser soll dann nach der Zeit prüfen, ob das Programm noch läuft
- Der "Zeitüberwachungsserver" soll mehrer Programme überwachen können.

Hat jemand eine Idee wie das geht? Oder kleine Beispiele dazu?

MfG
schuetze09
GwenDragon
 2006-07-24 14:46
#37322 #37322
User since
2005-01-17
14748 Artikel
Admin1
[Homepage]
user image
Dieser Server soll auf dem lokalen Rechner sein und die Programme auch?
schuetze09
 2006-07-24 15:04
#37323 #37323
User since
2006-07-24
15 Artikel
BenutzerIn
[default_avatar]
der Server soll auf einem Rechner (UNIX) im Netzwerk laufen und das Programm auch.
topeg
 2006-07-25 00:34
#37324 #37324
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
das Ding ist aus dem stehgreif und unerprobt. Es soll dir nur einen Anhalt/Basis bieten wie es gehen könnte:
Code: (dl )
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
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/perl
use strict;
use Fcntl;

my %conf=(timerstep=>5, fifo=>"./watchdog.add");

my @joblist=();

sub start_app($)
{
my $app_str=shift(@_);
my $pid=fork()
exec($app_str) unless($pid);
print "$0: Programm \"$app_str\" wurde mit der PID: \"$pid\" gestartet\n";
return $pid;
}

sub add_job($$$)
{
my ($app_str,$timeout,$pid);
push(@joblist,{app=>$app_str, time=>time(), timeout=>$timeout pid=>$pid, running=1});
}

sub kill_job($)
{
my $pid=shift(@_);
for my $job (@joblist)
{
if($job->{pid} == $pid)
{
$job->{running}=0;
last;
}
}
}

sub test_jobs()
{
my $time=time();
for my $job (@joblist)
{
if($job->{time}+$job->{timeout} >= $time)
{
if(`ps -o "%c" -p $job->{pid}` eq $job->{$app_str})
{
print "$0: \"$job->{$app_str}\" läuft noch nach $job->{timeout} Sekunden.\n";
}
else
{
print "$0: \"$job->{$app_str}\" wurde vorzeitzig beendet.\n";
}
kill_job($job->{pid});
}
}
}

sub timeout()
{
test_jobs();
}

### Programm ###

# fifo erzeugen
unless(-p $conf{fifo})
{
# kein FiFo
if (-e $conf{fifo})
{
die "$0: Werde $conf{fifo} nicht veändern!\n";
}
else
{
require POSIX;
POSIX::mkfifo($conf{fifo}, 0666) or die "mkfifo $conf{fifo} schlug fehl ($!)\n";
warn "$0: $conf{fifo} ist jetzt die Eingabedatei\n";
}
}

# timeout initialisieren
$SIG{ALRM}=&timeout();
# timeout Zyklus setzen
alarm $conf{timerstep};

# Eingaben lesen
while(1)
{
sysopen(FIFO, $conf{fifo}, O_RDONLY) or die "kann $conf{fifo} nicht lesen ($!)\n";
my $in=join("",<FIFO>);
close FIFO;

exit(0) if($in=~/^exit\s*$/s);

my ($pid,$timeout,$app_str)=split(':',$in,3);
if( $app_str ne '' && int($timeout)>0 )
{
$pid=start_app($app_str) if($pid<=0);
add_job($app_str,$timeout,$pid);
}
}

Wenn das Programm startet wird eine datei (fifo) angelet in die man die zu starten/beobachtenden wünscht. Das Format ist "<Prozessid>:<Timeout in Sekunden>:<Konandozeilenaufruf des Programmes>"
Wenn eine Prozessi< kleinergelich 0 übergeben wird startet das Script das Programm mit dem letzten übergeben Argument selber.
GwenDragon
 2006-07-25 16:21
#37325 #37325
User since
2005-01-17
14748 Artikel
Admin1
[Homepage]
user image
@topeg
So lassen sich aber nur Lokale Prozesse überwachen, oder täusche ich mich.

Schuetze09 wollte doch im Netzwerk, also auf entfernten Rechnern überwachen. Oder versteh ich das falsch?
Puh, diese Hitze heute, 36°C. :cool:
schuetze09
 2006-07-25 17:08
#37326 #37326
User since
2006-07-24
15 Artikel
BenutzerIn
[default_avatar]
genau so ist es.
aber für ein locales System ist das ein guter Ansatzt.
leider bricht das Script aber nach dem Alarm ab...

Code: (dl )
1
2
3
4
5
6
my %conf=(timerstep=>5, fifo=>"./watchdog.add")

# timeout initialisieren
$SIG{ALRM}=&timeout();
# timeout Zyklus setzen
alarm $conf{timerstep};
topeg
 2006-07-25 22:19
#37327 #37327
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Das Script war auch nur als Anregung gedacht und steckte voller Fehler, ich hatte es hier im Editorfenster kurz zuammengetippt, ohne es zu testen.
Hier ist eine funktionsfähige Version:
Code: (dl )
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/perl
use strict;
use Fcntl;

my %conf=(timerstep=>5, fifo=>"./watchdog.add");

my @joblist=();

sub start_app($)
{
my $app_str=shift(@_);
my $pid=fork();
exec($app_str) unless($pid);
print "$0: Programm \"$app_str\" wurde mit der PID: \"$pid\" gestartet\n";
return $pid;
}

sub add_job($$$)
{
my ($app_str,$timeout,$pid)=@_;
print "$0: Job hinzugefügt: \"$app_str\" PID=$pid, Timeout=$timeout\n";
push(@joblist,{app=>$app_str, time=>time(), timeout=>$timeout, pid=>$pid, running=>1});
}

sub kill_job($)
{
my $pid=shift(@_);
for my $job (@joblist)
{
if($job->{pid} == $pid)
{
$job->{running}=0;
last;
}
}
}

sub test_jobs()
{
my $time=time();
for my $job (@joblist)
{
if($job->{time}+$job->{timeout} <= $time && $job->{running}>0)
{
my $ps=`ps -o "%c" --no-headers -p $job->{pid}`;
chomp($ps);
print "PS: $ps\n";
if( $ps eq $job->{app})
{
print "$0: \"$job->{app}\" läuft noch nach $job->{timeout} Sekunden.\n";
}
else
{
print "$0: \"$job->{app}\" wurde vorzeitzig beendet.\n";
}
kill_job($job->{pid});
}
}
}

### Programm ###

# fifo erzeugen
unless(-p $conf{fifo})
{
# kein FiFo
if (-e $conf{fifo})
{
die "$0: Werde $conf{fifo} nicht veändern!\n";
}
else
{
require POSIX;
POSIX::mkfifo($conf{fifo}, 0666) or die "mkfifo $conf{fifo} schlug fehl ($!)\n";
warn "$0: $conf{fifo} ist jetzt die Eingabedatei\n";
}
}

# Eingaben lesen
while(1)
{
my $time=time();
my $in="";
eval
{
local $SIG{ALRM} = sub { die };
# timeout Zyklus setzen
alarm($conf{timerstep});
eval
{
sysopen(FIFO, $conf{fifo}, O_RDONLY) or die "kann $conf{fifo} nicht lesen ($!)\n";
$in=join("",<FIFO>);
chomp($in);
close FIFO;
};
# timeout aus.
alarm(0);
};
exit(0) if($in=~/^exit\s*$/s);
print "IN: $in\n" if($in ne "");
my ($pid,$timeout,$app_str)=split(':',$in,3);
if( $app_str ne '' && int($timeout)>0 )
{
$pid=start_app($app_str) if($pid<=0);
add_job($app_str,$timeout,$pid);
}

&test_jobs() if( $time+$conf{timerstep} <= time() );
}


Was die funktion übers netzwerk betrifft log dich über ssh ein und benutze das script darüber. Ansonsten müßte ich einen Client und Server schreiben, mit allem was dazugehört wie login, authentifikation usw. Aber niemand hindert dich daran es selber zu schreiben. :-)
schuetze09
 2006-07-26 09:42
#37328 #37328
User since
2006-07-24
15 Artikel
BenutzerIn
[default_avatar]
da hast du recht, ich habe bereits damit angefangen deine Anregung in ein Client-Server-System einzubauen...
Besten Dank!

MfG
schuetze09
Strat
 2006-07-26 14:11
#37329 #37329
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
perldoc -f alarm gibt dir ein schoenes Beispiel, wie ein Script ein $SIG{ALRM} ueberleben kann
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
<< >> 9 Einträge, 1 Seite



View all threads created 2006-07-24 12:29.