lilalo
diff l3-agent @ 27:098664cf339c
Выполнены шаги 4,5 в плане N05 по построению распределённой системы lilalo.
Шаг <6> в настоящее время не является необходимым.
Введено понятие сеанса.
Сеансом считается процедура работы с системой, начинающаяся с регистрации
в ней и зазаканчивающаяся разрегистрацией, и сопровождающаяся ведением одного
файла скрипта.
Одновременно с созданием скрипта (.script) создаётся соответствующий ему
файл с информацией о сеансе (.info).
Каждый сеанс имеет уникальный в пределах хоста идентификатор,
~local_session_id~, который впоследствии позволяет определить,
какие команды относятся к какому сеансу.
Добавлен backend-сервер, который получает данные от агентов и записывает
из в backend (в настойщий момент - в XML-файл).
Данные передаются по tcp-соединениям.
(Одновременно может работать несколько серверов.
Блокировка файла при записи пока что не выполняется ОСТОРОЖНО!!!!!!)
Агент периодически пытается отправить backend-серверу содержимое своего кэш-файла,
и если ему это удаётся, кэш файл очищается -- данные теперь хранятся в backend'е.
Взаимодействие агентов, backend-сервера и frontend'а
сейчас выполнеятся так:
+-------+
| |
| cache |
| |
+-^---+-+
| |
. ^ v . ^^ . +---------+ . ^^ .
/ \ tcp / \ | | / \ CGI
( agent )----->( backend- )-->| backend |-->( frontend )----->
\ / \ сервер / | | \ /
' . ' ' .. ' +---------+ ' .. '
^
|
+----+----+
| |
|*.script |
| *.info |
| |
+---------+
l3-frontend:
Теперь может выдавать результат работы на стандартный поток вывода.
Вместо имени файла нужно указать символ -
Добавлены файлы:
l3-backend - backend-сервер
l3-cgi - CGI-обвязка для l3-frontend'а
Новые конфигурационные параметры:
frontend_css Путь к файлу CSS, используемому в HTML-странице, которую генерирует frontend
frontend_google_ico Путь к иконке google
frontend_linux_ico Путь к иконке linux
frontend_freebsd_ico Путь к иконке freebsd
frontend_opennet_ico Путь к иконке opennet
frontend_local_ico Путь к иконке локальной документации
backend_address IP-адрес интерфейса, на котором работает backend-сервер
backend_port Порт, который слушает backend-сервер
backend_pidfile Путь к файлу, который хранит идентификатор процесса backend-сервера
backend_datafile Путь к файлу хранилищу (файлу backend)
Шаг <6> в настоящее время не является необходимым.
Введено понятие сеанса.
Сеансом считается процедура работы с системой, начинающаяся с регистрации
в ней и зазаканчивающаяся разрегистрацией, и сопровождающаяся ведением одного
файла скрипта.
Одновременно с созданием скрипта (.script) создаётся соответствующий ему
файл с информацией о сеансе (.info).
Каждый сеанс имеет уникальный в пределах хоста идентификатор,
~local_session_id~, который впоследствии позволяет определить,
какие команды относятся к какому сеансу.
Добавлен backend-сервер, который получает данные от агентов и записывает
из в backend (в настойщий момент - в XML-файл).
Данные передаются по tcp-соединениям.
(Одновременно может работать несколько серверов.
Блокировка файла при записи пока что не выполняется ОСТОРОЖНО!!!!!!)
Агент периодически пытается отправить backend-серверу содержимое своего кэш-файла,
и если ему это удаётся, кэш файл очищается -- данные теперь хранятся в backend'е.
Взаимодействие агентов, backend-сервера и frontend'а
сейчас выполнеятся так:
+-------+
| |
| cache |
| |
+-^---+-+
| |
. ^ v . ^^ . +---------+ . ^^ .
/ \ tcp / \ | | / \ CGI
( agent )----->( backend- )-->| backend |-->( frontend )----->
\ / \ сервер / | | \ /
' . ' ' .. ' +---------+ ' .. '
^
|
+----+----+
| |
|*.script |
| *.info |
| |
+---------+
l3-frontend:
Теперь может выдавать результат работы на стандартный поток вывода.
Вместо имени файла нужно указать символ -
Добавлены файлы:
l3-backend - backend-сервер
l3-cgi - CGI-обвязка для l3-frontend'а
Новые конфигурационные параметры:
frontend_css Путь к файлу CSS, используемому в HTML-странице, которую генерирует frontend
frontend_google_ico Путь к иконке google
frontend_linux_ico Путь к иконке linux
frontend_freebsd_ico Путь к иконке freebsd
frontend_opennet_ico Путь к иконке opennet
frontend_local_ico Путь к иконке локальной документации
backend_address IP-адрес интерфейса, на котором работает backend-сервер
backend_port Порт, который слушает backend-сервер
backend_pidfile Путь к файлу, который хранит идентификатор процесса backend-сервера
backend_datafile Путь к файлу хранилищу (файлу backend)
author | devi |
---|---|
date | Mon Nov 07 11:24:49 2005 +0200 (2005-11-07) |
parents | ba4d6515b8fd |
children | 450b6ac9b657 |
line diff
1.1 --- a/l3-agent Thu Nov 03 17:49:56 2005 +0200 1.2 +++ b/l3-agent Mon Nov 07 11:24:49 2005 +0200 1.3 @@ -10,6 +10,7 @@ 1.4 use Text::Iconv; 1.5 use Data::Dumper; 1.6 use Time::Local 'timelocal_nocheck'; 1.7 +use IO::Socket; 1.8 1.9 use lib "."; 1.10 use l3config; 1.11 @@ -18,6 +19,7 @@ 1.12 our @Command_Lines; 1.13 our @Command_Lines_Index; 1.14 our @Diffs; 1.15 +our %Sessions; 1.16 1.17 our %Commands_Stat; # Statistics about commands usage 1.18 our %Files_Stat; # Statistics about commands usage 1.19 @@ -44,7 +46,7 @@ 1.20 1.21 sub save_cache_stat; 1.22 sub load_cache_stat; 1.23 - 1.24 +sub print_session; 1.25 1.26 sub load_diff_files 1.27 { 1.28 @@ -224,22 +226,50 @@ 1.29 1.30 print "Loading lm-scripts...\n" if $Config{"verbose"} =~ /y/; 1.31 1.32 - my @lab_scripts = <$lab_scripts_path/$lab_scripts_mask>; 1.33 my $file; 1.34 - my $files_number = $#lab_scripts; 1.35 - my $ii = 0; 1.36 my $skip_info; 1.37 1.38 my $commandlines_loaded =0; 1.39 my $commandlines_processed =0; 1.40 1.41 + my @lab_scripts = <$lab_scripts_path/$lab_scripts_mask>; 1.42 for $file (@lab_scripts){ 1.43 - #printf "\t%i %3.2f\n", $ii, (100*$ii++/$files_number) if $Config{"verbose"} =~ /y/; 1.44 1.45 # Пропускаем файл, если он не изменялся со времени нашего предудущего прохода 1.46 my $size = (stat($file))[7]; 1.47 next if ($Script_Files{$file} && $Script_Files{$file}->{size} && $Script_Files{$file}->{size} >= $size); 1.48 1.49 + 1.50 + my $local_session_id; 1.51 + # Начальное значение идентификатора текущего сеанса определяем из имени скрипта 1.52 + # Впоследствии оно может быть уточнено 1.53 + $file =~ /.*\/(.*)\.script$/; 1.54 + $local_session_id = $1; 1.55 + 1.56 + #Если файл только что появился, 1.57 + #пытаемся найти и загрузить информацию о соответствующей ему сессии 1.58 + if (!$Script_Files{$file}) { 1.59 + my $session_file = $file; 1.60 + $session_file =~ s/\.script/.info/; 1.61 + if (open(SESSION, $session_file)) { 1.62 + local $/; 1.63 + my $data = <SESSION>; 1.64 + close(SESSION); 1.65 + 1.66 + for my $session_data ($data =~ m@<session>(.*?)</session>@sg) { 1.67 + my %session; 1.68 + while ($session_data =~ m@<([^>]*?)>(.*?)</\1>@sg) { 1.69 + $session{$1} = $2; 1.70 + } 1.71 + $local_session_id = $session{"local_session_id"} if $session{"local_session_id"}; 1.72 + $Sessions{$session_id}=\%session; 1.73 + } 1.74 + 1.75 + #Загруженную информацию сразу же отправляем в поток 1.76 + print_session($Config{cache}, $local_session_id); 1.77 + } 1.78 + } 1.79 + 1.80 open (FILE, "$file"); 1.81 binmode FILE; 1.82 1.83 @@ -278,7 +308,8 @@ 1.84 1.85 =cut 1.86 1.87 -ТАБЛИЦА КОМАНД 1.88 +Атрибуты cline 1.89 +Список полей, характеризующих командную строку 1.90 1.91 uid 1.92 Идентификатор пользователя 1.93 @@ -338,6 +369,7 @@ 1.94 Текстовый комментарий к команде. 1.95 Может генерироваться из самого лога с помощью команд 1.96 #^ Комментарий 1.97 + #= Комментарий 1.98 #v Комментарий 1.99 в том случае, если для комментирования достаточно одной строки, 1.100 или с помощью команд 1.101 @@ -348,9 +380,11 @@ 1.102 В последнем случае комментарий может содержать 1.103 заголовок, абзацы и несложное форматирование. 1.104 1.105 - Символ ^ или v после знака комментария # обозначает, 1.106 + Символы ^, v или = после знака комментария # обозначает, 1.107 к какой команде относится комментарий: 1.108 - к предыдущей (^) или последующей (v) 1.109 + к предыдущей (^), последующей (v) 1.110 + или это общий комментарий по тексту, не относящийся непосредственно 1.111 + ни к одной из них (=) 1.112 1.113 err 1.114 Код завершения командной строки 1.115 @@ -397,22 +431,22 @@ 1.116 1.117 1 - версия использующаяся в lilalo 1.118 1.119 - raw_file (*) 1.120 + raw_file 1.121 Имя файла, в котором находится бинарное представление журнала. 1.122 Может содержать ключевое слово HERE, 1.123 обозначающее что бинарное представление хранится 1.124 непосредственно в базе данных в атрибуте raw_data 1.125 1.126 - raw_start (*) 1.127 + raw_start 1.128 Начало блока командной строки в файле бинарного представления 1.129 1.130 - raw_output_start (*) 1.131 + raw_output_start 1.132 Начало блока вывода 1.133 1.134 - raw_end (*) 1.135 + raw_end 1.136 Конец блока командной строки в файле бинарного представления 1.137 1.138 - raw_cline (*) 1.139 + raw_cline 1.140 Необработанная командная строка (без приглашения) в бинарном виде 1.141 1.142 raw_data (*) 1.143 @@ -425,11 +459,12 @@ 1.144 1.145 Информация о сеансах 1.146 1.147 - 1.148 + (см. lm-install) 1.149 1.150 1.151 =cut 1.152 1.153 + $cl{"local_session_id"} = $local_session_id; 1.154 # Parse new command 1.155 $cl{"uid"} = $3; 1.156 $cl{"euid"} = $cl{"uid"}; # Если в команде обнаружится sudo, euid поменяем на 0 1.157 @@ -751,6 +786,7 @@ 1.158 1.159 # Начинаем вывод команды 1.160 print OUT "<command>\n"; 1.161 + print OUT "<local_session_id>",$cl->{session_id},"</local_session_id>\n"; 1.162 print OUT "<time>",$cl->{time},"</time>\n"; 1.163 print OUT "<raw_start>",$cl->{raw_start},"</raw_start>\n"; 1.164 print OUT "<raw_output_start>",$cl->{raw_output_start},"</raw_output_start>\n"; 1.165 @@ -789,7 +825,54 @@ 1.166 1.167 #print OUT "</livelablog>\n"; 1.168 close(OUT); 1.169 - save_cache_stat(); 1.170 +} 1.171 + 1.172 +sub print_session 1.173 +{ 1.174 + my $output_filename = $_[0]; 1.175 + my $local_session_id = $_[1]; 1.176 + return if not defined($Sessions{$local_session_id}); 1.177 + 1.178 + open(OUT, ">>", $output_filename) 1.179 + or die "Can't open $output_filename for writing\n"; 1.180 + print OUT "<session>\n"; 1.181 + my %session = %{$Sessions{$local_session_id}}; 1.182 + for my $key (keys %session) { 1.183 + print OUT "<$key>".$session{$key}."</$key>\n" 1.184 + } 1.185 + print OUT "</session>\n"; 1.186 + close(OUT); 1.187 +} 1.188 + 1.189 +sub send_cache 1.190 +{ 1.191 + `logger "step 0"`; 1.192 + `logger "step 1"`; 1.193 + 1.194 + # Если в кэше что-то накопилось, 1.195 + # попытаемся отправить это на сервер 1.196 + # 1.197 + my $cache_was_sent=0; 1.198 + 1.199 + if (open(CACHE, $Config{cache})) { 1.200 + local $/; 1.201 + my $cache = <CACHE>; 1.202 + close(CACHE); 1.203 + 1.204 + my $socket = IO::Socket::INET->new( 1.205 + PeerAddr => $Config{backend_address}, 1.206 + PeerPort => $Config{backend_port}, 1.207 + proto => "tcp", 1.208 + Type => SOCK_STREAM 1.209 + ); 1.210 + 1.211 + if ($socket) { 1.212 + print $socket $cache; 1.213 + close($socket); 1.214 + $cache_was_sent = 1; 1.215 + } 1.216 + } 1.217 + return $cache_was_sent; 1.218 } 1.219 1.220 sub save_cache_stat 1.221 @@ -805,6 +888,7 @@ 1.222 { 1.223 if (open (CACHE, "$Config{cache_stat}")) { 1.224 while(<CACHE>) { 1.225 + chomp; 1.226 my ($f, $size, $tell) = split /\t/; 1.227 $Script_Files{$f}->{size} = $size; 1.228 $Script_Files{$f}->{tell} = $tell; 1.229 @@ -813,65 +897,6 @@ 1.230 }; 1.231 } 1.232 1.233 -=cut 1.234 -sub print_command_lines2 1.235 -{ 1.236 - my $output_filename=$_[0]; 1.237 - open(OUT, ">", $output_filename) 1.238 - or die "Can't open $output_filename for writing\n"; 1.239 - 1.240 - 1.241 - print OUT <<OUT; 1.242 -<log> 1.243 -OUT 1.244 - 1.245 - my $cl; 1.246 - for my $i (@Command_Lines_Index) { 1.247 - 1.248 - 1.249 - $cl = $Command_Lines[$i]; 1.250 - 1.251 - 1.252 -# Printing out 1.253 - print OUT <<OUT; 1.254 - <command> 1.255 - <day>$cl->{day}</day> 1.256 - <hour>$cl->{hour}</hour> 1.257 - <min>$cl->{min}</min> 1.258 - <sec>$cl->{sec}</sec> 1.259 - <tty>$cl->{tty}</tty> 1.260 - <uid>$cl->{uid}</uid> 1.261 - <euid>$cl->{euid}</euid> 1.262 - <prompt>$cl->{prompt}</prompt> 1.263 - <cline>$cl->{cline}</cline> 1.264 - <status>$cl->{err}</cline> 1.265 - <output> 1.266 -$cl->{output}</output> 1.267 - </command> 1.268 -OUT 1.269 - } 1.270 - 1.271 - for my $diff (@Diffs) { 1.272 - 1.273 - print OUT <<OUT; 1.274 - <diff> 1.275 - <path>$diff->{path}</path> 1.276 - <uid>$diff->{uid}</uid> 1.277 - <day>$diff->{day}</day> 1.278 - <hour>$diff->{hour}</hour> 1.279 - <min>$diff->{min}</min> 1.280 - <sec>$diff->{sec}</sec> 1.281 - <text> 1.282 -$diff->{text}</text> 1.283 - </diff> 1.284 -OUT 1.285 - } 1.286 - 1.287 - print OUT <<OUT; 1.288 -</log> 1.289 -OUT 1.290 -} 1.291 -=cut 1.292 1.293 main(); 1.294 1.295 @@ -882,73 +907,85 @@ 1.296 1.297 sub main 1.298 { 1.299 -$| = 1; 1.300 1.301 -init_variables(); 1.302 -init_config(); 1.303 + $| = 1; 1.304 1.305 -for my $lab_log (split (/\s+/, $Config{"diffs"} || $Config{"input"})) { 1.306 - load_diff_files($lab_log); 1.307 -} 1.308 + init_variables(); 1.309 + init_config(); 1.310 1.311 -if ($Config{"mode"} ne "daemon") { 1.312 - load_command_lines($Config{"input"}, $Config{"input_mask"}); 1.313 - sort_command_lines; 1.314 - process_command_lines; 1.315 - print_command_lines($Config{"cache"}); 1.316 -} 1.317 -else { 1.318 - if (open(PIDFILE, $Config{agent_pidfile})) { 1.319 - my $pid = <PIDFILE>; 1.320 - close(PIDFILE); 1.321 - if ( ! -e "/proc/$pid" || !`grep $Config{"l3-agent"} /proc/$pid/cmdline && grep "uid:.*\b$<\b" /proc/$pid/status`) { 1.322 - print "Removing stale pidfile\n"; 1.323 - unlink $Config{agent_pidfile}; 1.324 - or die "Can't remove stale pidfile ". $Config{agent_pidfile}. " : $!"; 1.325 + for my $lab_log (split (/\s+/, $Config{"diffs"} || $Config{"input"})) { 1.326 + load_diff_files($lab_log); 1.327 + } 1.328 + 1.329 + if ($Config{"mode"} ne "daemon") { 1.330 + 1.331 +=cut 1.332 + В нормальном режиме работы нужно 1.333 + считать скрипты, обработать их и записать 1.334 + результат выполнения в результриующий файл. 1.335 + После этого завершить работу. 1.336 +=cut 1.337 + load_command_lines($Config{"input"}, $Config{"input_mask"}); 1.338 + sort_command_lines; 1.339 + process_command_lines; 1.340 + print_command_lines($Config{"cache"}); 1.341 + } 1.342 + else { 1.343 + if (open(PIDFILE, $Config{agent_pidfile})) { 1.344 + my $pid = <PIDFILE>; 1.345 + close(PIDFILE); 1.346 + if ( ! -e "/proc/$pid" || !`grep $Config{"l3-agent"} /proc/$pid/cmdline && grep "uid:.*\b$<\b" /proc/$pid/status`) { 1.347 + print "Removing stale pidfile\n"; 1.348 + unlink $Config{agent_pidfile} 1.349 + or die "Can't remove stale pidfile ". $Config{agent_pidfile}. " : $!"; 1.350 + } 1.351 + else { 1.352 + print "l3-agent is already running\n"; 1.353 + exit(0); 1.354 + } 1.355 } 1.356 - else { 1.357 - print "l3-agent is already running\n"; 1.358 - exit(0); 1.359 + if ($Config{detach} =~ /^y/i) { 1.360 + #$Config{verbose} = "no"; 1.361 + my $pid = fork; 1.362 + exit if $pid; 1.363 + die "Couldn't fork: $!" unless defined ($pid); 1.364 + 1.365 + open(PIDFILE, ">", $Config{agent_pidfile}) 1.366 + or die "Can't open pidfile ". $Config{agent_pidfile}. " for wrting: $!"; 1.367 + print PIDFILE $$; 1.368 + close(PIDFILE); 1.369 + 1.370 + for my $handle (*STDIN, *STDOUT, *STDERR) { 1.371 + open ($handle, "+<", "/dev/null") 1.372 + or die "can't reopen $handle to /dev/null: $!" 1.373 + } 1.374 + 1.375 + POSIX::setsid() 1.376 + or die "Can't start a new session: $!"; 1.377 + 1.378 + $0 = $Config{"l3-agent"}; 1.379 + 1.380 + $SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&process_was_killed; 1.381 } 1.382 + while (not $Killed) { 1.383 + @Command_Lines = (); 1.384 + @Command_Lines_Index = (); 1.385 + load_cache_stat(); 1.386 + load_command_lines($Config{"input"}, $Config{"input_mask"}); 1.387 + if (@Command_Lines) { 1.388 + sort_command_lines; 1.389 + process_command_lines; 1.390 + print_command_lines($Config{"cache"}); 1.391 + } 1.392 + save_cache_stat(); 1.393 + if (-e $Config{cache} && (stat($Config{cache}))[7]) { 1.394 + send_cache() && unlink($Config{cache}); 1.395 + } 1.396 + sleep($Config{"daemon_sleep_interval"} || 1); 1.397 + } 1.398 + 1.399 + unlink $Config{agent_pidfile}; 1.400 } 1.401 - if ($Config{detach} =~ /^y/i) { 1.402 - #$Config{verbose} = "no"; 1.403 - my $pid = fork; 1.404 - exit if $pid; 1.405 - die "Couldn't fork: $!" unless defined ($pid); 1.406 - 1.407 - open(PIDFILE, ">", $Config{agent_pidfile}) 1.408 - or die "Can't open pidfile ". $Config{agent_pidfile}. " for wrting: $!"; 1.409 - print PIDFILE $$; 1.410 - close(PIDFILE); 1.411 - 1.412 - for my $handle (*STDIN, *STDOUT, *STDERR) { 1.413 - open ($handle, "+<", "/dev/null") 1.414 - or die "can't reopen $handle to /dev/null: $!" 1.415 - } 1.416 - 1.417 - POSIX::setsid() 1.418 - or die "Can't start a new session: $!"; 1.419 - 1.420 - $0 = $Config{"l3-agent"}; 1.421 - 1.422 - $SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&process_was_killed; 1.423 - } 1.424 - while (not $Killed) { 1.425 - @Command_Lines = (); 1.426 - @Command_Lines_Index = (); 1.427 - load_cache_stat(); 1.428 - load_command_lines($Config{"input"}, $Config{"input_mask"}); 1.429 - if (@Command_Lines) { 1.430 - sort_command_lines; 1.431 - process_command_lines; 1.432 - print_command_lines($Config{"cache"}); 1.433 - } 1.434 - sleep($Config{"daemon_sleep_interval"} || 1); 1.435 - } 1.436 - 1.437 - unlink $Config{agent_pidfile}; 1.438 -} 1.439 1.440 } 1.441