Включение имени хоста в отчеты Apache LogWatch

При размещении нескольких доменов с помощью Apache полезно видеть вывод Apache logwatch с включенным именем виртуального хоста, но я получаю только:

 --------------------- httpd Begin ------------------------

 Requests with error response codes
   400 Bad Request
      /: 1 Time(s)
      /robots.txt: 1 Time(s)

в то время как я хотел бы что-то вроде

 --------------------- httpd Begin ------------------------

 Requests with error response codes
   400 Bad Request
      example.com/: 1 Time(s)
      example.org/robots.txt: 1 Time(s)

Как я могу добиться этого с logwatch?

6 ответов

Решение

Попробуйте это (работает для меня): Определите LogFormat в вашем httpd.conf как

LogFormat "%h %t [%V] \"%r\" %>s \"%{Referer}i\""

В этом конкретном случае у вас будет удаленный_адрес, дата / время, [имя сервера в соответствии с настройкой UseCanonicalName], запрос, код satus и Referer (это мой желаемый формат), а затем помещено

$LogFormat "%h %t %V \"%r\" %>s \"%{Referer}i\""

в ваших сервисах /http.conf файл LogWatch. Что будет

  1. заставить apache поставить имя хоста (каноническое или нет, зависит, используете ли вы%v или%V)
  2. заставить LogWatch понять ваш журнал Apache Access

Вот пример строки в выводе журнала с этим конкретным набором директив:

172.3.20.11 [01 / Jun / 2011: 21: 00: 52 +0200] joomla.local "GET /images/tabs_back.png HTTP / 1.1" 404 " http://joomla.local/templates/beez_20/css/personal.css "

Если мы сосредоточимся на кодах ошибок и на том, как они обрабатываются в LogWatch, вот некоторые изменения, которые вы можете внести в / usr / share / logwatch / scripts / services / http: Add:

my $ my_host = ""; my $ my_url = "";

Затем, около строки 462, добавьте эту строку, чтобы сохранить наш 4-й столбец (HOST):

$ field {my_host} = $ field {$ log_fields [3]};

И в строке 560, после fmt_url сокращен (if (length($field{url}) > 60) {...}) добавлять:

$my_host = $field{$log_fields[3]};
$my_host = substr($my_host,1);
$my_url=$my_host . $fmt_url;

Наконец, измените:

$needs_exam{$field{http_rc}}{$fmt_url}++;

от

$needs_exam{$field{http_rc}}{$my_url}++;

сделав это, вы получите это в своем Logwatch:

Requests with error response codes
404 Not Found
joomla.local/images/tabs_back.png: 3 Time(s)

Надеюсь, это поможет вам

У меня была та же проблема, и я решил ее, изменив LogFormat в apache.conf ( http://httpd.apache.org/docs/2.2/mod/mod_log_config.html)

# LogFormat "%h %l %u %t \"%r\" %>s %O" common

# The default output has no info about the server name (%v).
# %m %U%q %H is strictly equivalent to %r.
LogFormat "%h %l %u %t \"%m %v%U%q %H\" %>s %O" common

Это создает тот же вывод, что и по умолчанию, добавляя каноническое имя сервера в качестве префикса. Например:

... "GET www.example.com/apache_pb.gif HTTP/1.0" 200 2326 ... 

Преимущество в том, что вам не нужны никакие другие настройки (например, на стороне logwatch). Суть в том, что вы получаете несколько дополнительных символов для каждой записанной строки.

Я нашел сообщение в блоге, детализирующее эту проблему и как кто-то решил ее. Не знаю, как это повлияет на анализ журналов, но я заметил это здесь, так как я нашел это полезным.

Я не думаю, что это возможно, если вы регистрируете все виртуальные домены в один файл журнала... Журнал apache не будет различать между ними.

Я также хотел бы предложить вам взглянуть на OSSEC с открытым исходным кодом. Мы перешли от logwatch к нему, потому что он в режиме реального времени и позволяет централизованную корреляцию (корреляция таких вещей, как ssh fail login с ошибками apache 400).

Вы можете получить имя хоста, используя директиву LogFormat в конфигурации apache. Вы можете использовать следующую опцию

%{Host}i

Я нашел эту информацию в этой ссылке. Logwatch должен уметь анализировать пользовательскую информацию.

Большое спасибо @Syquus, который поставил меня на правильный путь к изменению /usr/share/logwatch/scripts/services/http файл.

Мой файл и решение было другим, но я думал, что поделюсь тем же.

Я использую стандарт vhost_combined LogFormat, который предоставляет Apache, выглядит так:

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined

который выводит что-то вроде:

example.org:80 1.1.1.1 - - [08/Oct/2013:16:55:01 +0000] "GET / HTTP/1.1" 200 6094 "-" "Opera/9.80 (X11; Linux x86_64; Edition Linux Mint) Presto/2.12.388 Version/12.16"

Я положил это в переопределении конфигурации службы в /etc/logwatch/conf/services/http.conf:

$logformat = "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\""

После нахождения приблизительно правильных мест для внесения изменений в решение @ Syquus в /usr/share/logwatch/scripts/services/httpЯ думал, что простое изменение индекса с [3] на [0] сработает - это не сработало. Я получил неправильные сегменты пути и даже после обхода всего хеша / массива я не нашел имя хоста. Отладка была разочаровывающей, потому что я новичок в Perl, но мое решение было добавить в соответствие для %v который был отброшен, а затем изменил URL далее вниз, чтобы включить доменное имя.

Diff для моего решения (я также удалил усечение URL), YMMV:

--- __http.2013-10-09   2013-10-09 13:11:48.000000000 +0000
+++ http        2013-10-09 14:36:59.000000000 +0000
@@ -132,6 +132,8 @@
 #  Build tables of the log format to parse it and determine whats what
 #

+my $my_url = "";
+
 my $detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
 my $ignoreURLs = $ENV{'http_ignore_urls'};
 my $ignoreIPs = $ENV{'http_ignore_ips'};
@@ -379,7 +381,10 @@
 $logformat =~ s/%[\d,!]*/%/g;
 while ($end_loop) {

-   if ($logformat =~ /\G%h/gc) {
+   if ($logformat =~ /\G%v/gc) {
+      $parse_string[$parse_index] .= "(\\S*?)";
+      $parse_field[$parse_index][$parse_subindex++] = "my_host";
+   } elsif ($logformat =~ /\G%h/gc) {
       $parse_string[$parse_index] .= "(\\S*?)";
       $parse_field[$parse_index][$parse_subindex++] = "client_ip";
    } elsif ($logformat =~ /\G%l/gc) {
@@ -437,7 +442,6 @@
 #
 #  Process log file on stdin
 #
-
 while (my $line = <STDIN>) {
    chomp($line);

@@ -580,11 +584,12 @@
          !((defined $ignoreURLs) && ($field{url} =~ /$ignoreURLs/)) &&
          !((defined $ignoreIPs) && ($field{client_ip} =~ /$ignoreIPs/)) ) {
       my $fmt_url = $field{url};
-      if (length($field{url}) > 60) {
-         $fmt_url = substr($field{url},0,42) . " ... " .
-                    substr($field{url},-15,15);
-      }
-      $needs_exam{$field{http_rc}}{$fmt_url}++;
+      #if (length($field{url}) > 60) {
+      #   $fmt_url = substr($field{url},0,42) . " ... " .
+      #              substr($field{url},-15,15);
+      #}
+      $my_url = $field{my_host} . $fmt_url;
+      $needs_exam{$field{http_rc}}{$my_url}++;
    }
    if (defined $field{userid} && $field{userid} ne "-" &&
          (eval $user_display) &&

Если я решу подать защищенный контент или контент на порт, отличный от:80, я мог бы включить его в будущем. Теперь должно быть очевидно, как.

Надеюсь это поможет!

ОБНОВИТЬ

Сделано еще несколько изменений, исправлена ​​ошибка. Вместо того, чтобы продолжать редактировать этот ответ, вы можете найти мои модификации здесь: https://bitbucket.org/ubiquitypress/logwatch

Другие вопросы по тегам