
Наличие различных серверов Apache в среде с низкой нагрузкойраnet с почти исключительно DHCP-клиентами, нам нужно регистрировать имена хостов вместо IP-адресов. Поскольку среда DHCP довольно динамична, любая последующая попытка переназначить IP-адреса на имена хостов, скорее всего, даст ложные результаты.
Хотя у нас есть " HostnameLookups On
", только журнал доступа послушно регистрирует имена хостов, а ErrorLog этого не делает.
Читая о ErrorLogFormat
, я замечаю, что нет%час, но просто%а(что означает «IP-адрес и порт клиента»).
Так неужели нет способа заставить Apache также регистрировать имена хостов в журнале ошибок...?
решение1
Несовместимо с директивой ErrorLog.
Я бы написал скрипт, который решает для вас проблему, и передал бы ErrorLog через него. В вашей конфигурации Apache что-то вроде этого:
Errorlog "|/usr/local/bin/errorlog_resolver.pl"
А теперь пример скрипта на Perl:
#!/usr/bin/perl -w
# errorlog_resolver.pl
# Give apache ErrorLog on STDIN, outputs them with numeric IP addresses
# in the likely (host) field converted to hostnames (where possible).
# based on clf_lookup.plx from "Perl for Web Site Management"
# http://oreilly.com/catalog/perlwsmng/chapter/ch08.html
#
use strict;
use Socket;
open LOGFILE, ">>/tmp/my_error_log" or die "Couldn't open file: $!";
my %hostname;
while (<>) {
my $line = $_;
my($day, $month, $dayn, $hour, $year, $err, $client, $host, $rest) = split / /, $line, 9;
if ( $client ~~ "[client" ) {
# remove the ] trailing the likely ip-address.
my $chr = chop($host);
if ($host =~ /^\d+\.\d+\.\d+\.\d+$/) {
# looks vaguely like an IP address
unless (exists $hostname{$host}) {
# no key, so haven't processed this IP before
$hostname{$host} = gethostbyaddr(inet_aton($host), AF_INET);
}
if ($hostname{$host}) {
# only processes IPs with successful lookups
$line = "$day $month $dayn $hour $year $err $client $hostname{$host}\($host\)\] $rest)";
}
}
}
print LOGFILE $line;
}