Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1820775
  • 博文数量: 473
  • 博客积分: 13997
  • 博客等级: 上将
  • 技术积分: 5953
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-22 11:52
文章分类

全部博文(473)

文章存档

2014年(8)

2013年(38)

2012年(95)

2011年(181)

2010年(151)

分类: LINUX

2012-09-19 17:16:10



This page describes how to get some network services to log nicely with syslog-ng by. For your reference, in all the examples I use the following standard snippet in my 'syslog-ng.conf':

options {
        chain_hostnames(no);
        check_hostname(yes);
        create_dirs(yes);
        dir_group(adm);
        dir_owner(root);
        dir_perm(0750);
#       flush_lines(0);
#       flush_timeout(10000);
        keep_hostname(yes);
        normalize_hostnames(yes); # <-- pre-3.1.4 set this to 'no'
        use_fqdn(yes);
        long_hostnames(yes);
        use_dns(yes);
        use_fqdn(yes);
#       dns_cache_hosts(/etc/hosts);
        owner(root);
        group(adm);
        perm(0640);
#       time_sleep(0);
        ts_format(iso);
};

source s_net { udp6(); tcp6(); };

template t_standard {
        template("$ISODATE $FULLHOST <$FACILITY.$PRIORITY> $MSGHDR$MSGONLY\n");
};

The general approach is to reformat the message as much as we can and loop it back (typically over a UNIX stream socket) in a format syslog-ng can parse. For example with Cisco logs, this can be done all solely with syslog-ng but in the case of Squid we send the log entry over to a Perl script via it's STDIN (using the destination 'program()' driver), the send it back to syslog-ng via a FIFO (using the source 'pipe()' driver).

N.B. as it is syslog-ng that creates the FIFO/socket, you have to place the reader first in your 'syslog-ng.conf' file otherwise a potential race condition is set up that could result.
Squid Proxy Server

When it comes to logging your Squid access logs, when you look at what is stored on disk, you will see something like:

Feb  1 11:51:27 proxy0 (squid): 1296561087.508    413 1.2.3.4 TCP_MISS/400 1124 GET - DIRECT/4.3.2.1 application/json

The problem with this is that you have the timestamp both in the syslog:

    header: with accuracy to the second
    message: represented as an UNIX epoch with milliseconds appended as a decimal componment

This is a bit wasteful so it would be nice to discard the timestamp in the syslog header and use the epoch field alone but expanded instead in the ISO standard format of 'YYYY-MM-DDThh:mm:ss.123+00:00' like so:

2011-02-01T11:51:27.508+00:00 proxy0 squid: 413 1.2.3.4 TCP_MISS/400 1124 GET - DIRECT/4.3.2.1 application/json

syslog-ng does not support this type of rewriting functionality, but fortunately we can palm the problem off to a Perl script and then read back the amended log entries over a FIFO and store that in a local file. The Perl script I have made available, you will need to place it in '/usr/local/sbin':

    syslog.squid

You should configure squid to syslog it's access log by adding the following to it's configuration:

acl syslog url_regex ^*?:3128/squid-internal-static/
access_log syslog:local4 squid !localhost !syslog

The bits that are to go into your syslog-ng configuration are:

# unfortunately 'perm(0600)' gives a syntax error for pipe()
source s_squid_processed {
        pipe("/var/run/syslog.squid");
};
destination d_acl_proxy {
        file("/var/log/remote/acl-proxy/$HOST/$YEAR$MONTH$DAY.log"
                template(t_standard)
                frac_digits(3));
};
log {
        source(s_squid_processed);
        destination(d_acl_proxy);
        flags(final);
};

filter f_squid {
        program("squid");
};
filter f_squid_hosts {
        match("proxy0.example.com" value("HOST_FROM") type("string"))
                or
        match("proxy1.example.com" value("HOST_FROM") type("string"));
};
destination d_squid_process {
        program("/usr/local/sbin/syslog.squid"
                template("<$PRI>$ISODATE $FULLHOST $MSGHDR$MSGONLY\n")
                flags("no-multi-line"));
};
log {
        source(s_net);
        filter(f_squid);
        filter(f_squid_hosts);
        destination(d_squid_process);
        flags(final);
};

Cisco

N.B. this is a work in progress
Cisco IOS

service timestamps log datetime msec
logging origin-id hostname
logging 1.2.3.4

15194: 103-1: Feb  7 13:52:35.293: %PARSER-5-CFGLOG_LOGGEDCMD: User:bob  logged command:logging host 192.0.2.1 transport tcp port 514

2011-02-07T13:52:35.293 host-1.infra.example.com %PARSER-5-CFGLOG_LOGGEDCMD: User:bob  logged command:logging host 192.0.2.1 transport tcp port 514

source s_cisco_processed {
        unix-stream("/var/run/syslog.cisco"
                perm(0600));
};
destination d_infra_edge {
        file("/var/log/remote/infra/$HOST/$YEAR$MONTH$DAY.log"
                fsync(yes)
                template(t_standard)
                frac_digits(3));
};
log {
        source(s_cisco_processed);
        destination(d_infra_edge);
        flags(final);
};

filter f_infra {
        match("*.infra.example.com" value(HOST_FROM) type(glob));
};
destination d_cisco_process {
        unix-stream("/var/run/syslog.cisco"
                template("<$PRI>${CISCO.TS1}:${CISCO.TS2}:${CISCO.TS3} $FULLHOST ${CISCO.APP}:${CISCO.MSG}\n")
                flags(no-multi-line));
};
rewrite r_cisco_ts1 {
        subst("^[*.]", "", value(CISCO.TS1));
};
# cisco ios
filter f_cisco_ios {
        # as well as being poorly formatted, occasionally puts a '.'/'*' before the month
        # N.B. seqnum is digested as 'hostname'
        # 54767: host-1: Feb 23 16:41:54.821: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet4/0/6, changed state to down
        # 282438: host-2: .Feb 22 20:45:30.632: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet1/0/6, changed state to down
        match("^[^ :]+: [*.]?[a-z]+ +[0-9]+ [0-9:.]+: %" value(MSGONLY)
                flags(ignore-case));
};
filter f_cisco_ios_hostless {
        # legacy hostless format ('logging origin-id hostname' not supported)
        # 299: Mar  7 11:11:04.530: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/8, changed state to down
        match("^[*.]?[a-z]+ +[0-9]+ [0-9:.]+: %" value(MSGONLY)
                flags(ignore-case));
};
parser p_cisco_ios {
        # sequence number is eaten by the time we get to $MSG
        csv-parser(columns("CISCO.HOST", "CISCO.TS1", "CISCO.TS2", "CISCO.TS3", "CISCO.APP", "CISCO.MSG")
                delimiters(":")
                flags(strip-whitespace greedy));
};
parser p_cisco_ios_hostless {
        # sequence number is eaten by the time we get to $MSG
        csv-parser(columns("CISCO.TS1", "CISCO.TS2", "CISCO.TS3", "CISCO.APP", "CISCO.MSG")
                delimiters(":")
                flags(strip-whitespace greedy));
};
log {
        source(s_net);
        filter(f_infra);
        filter(f_cisco_ios);
        parser(p_cisco_ios);
        rewrite(r_cisco_ts1);
        destination(d_cisco_process);
        flags(final);
};
log {
        source(s_net);
        filter(f_infra);
        filter(f_cisco_ios_hostless);
        parser(p_cisco_ios_hostless);
        rewrite(r_cisco_ts1);
        destination(d_cisco_process);
        flags(final);
};

Cisco WLC4400

N.B. disable 'trace' logging

wlc-01: *Feb 14 16:44:21.959: %DOT1X-4-INVALID_MSG_TYPE: authlib.c:85 Invalid message type 9 received from AAA

2011-02-14T16:44:21.959 wlc-01.infra.example.com %DOT1X-4-INVALID_MSG_TYPE: authlib.c:85 Invalid message type 9 received from AAA

Additionally to the above Cisco IOS approach:

# cisco wlc
filter f_cisco_wlc {
        # as well as being poorly formatted, it places a '*' before the month
        # wlc-01: *Feb 23 16:47:19.541: %DOT1X-3-MAX_EAP_RETRIES: 1x_auth_pae.c:2872 Max EAP identity request retries (3) exceeded for client 00:11:22:33:54:55
        match("^\\*[a-z]+ +[0-9]+ " value(MSGONLY)
                flags(ignore-case));
};
parser p_cisco_wlc {
        csv-parser(columns("CISCO.TS1", "CISCO.TS2", "CISCO.TS3", "CISCO.APP", "CISCO.MSG")
                delimiters(":")
                flags(strip-whitespace greedy));
};
log {
        source(s_net);
        filter(f_infra);
        filter(f_cisco_wlc);
        parser(p_cisco_wlc);
        rewrite(r_cisco_ts1);
        destination(d_cisco_process);
        flags(final);
};

PostgreSQL Functions

N.B. this is a work in progress

destination d_sql_mac2addr {
#       program("sh -c 'PGPASSFILE=/etc/syslog-ng/pgpass psql --no-readline --quiet --no-password --host=sql.example.com --log-file=/tmp/sql.log DATABASE USERNAME > /dev/null 2> /dev/null'"
        program("sh -c 'PGPASSFILE=/etc/syslog-ng/pgpass psql --no-readline --quiet --no-password --host=sql.example.com DATABASE USERNAME > /dev/null 2> /dev/null'"
                template("SELECT record_addr('$ISODATE', '${MAC2ADDR.MAC}', '${MAC2ADDR.ADDR}');\n"));
};


阅读(1458) | 评论(0) | 转发(0) |
0

上一篇:log4cpp总结

下一篇:python之syslog学习

给主人留下些什么吧!~~