用syslog服务器收集java日志

初来公司时,java日志收集使用的nfs方式,将nfs server上的一块大容量磁盘挂载到所有java服务器的$catalina_home/logs目录,解决服务器本地空间不足问题;

这个方案的弊端是,如果nfs server想停机做个维护,几乎不可行;同时,多节点的日志在nfs服务器上是分开的,如果某个应用有8个节点,那查日志要查8个文件。

用syslog收集java日志,能完美解决这个问题。

安装syslog-ng

有兴趣建议看看官方文档:https://syslog-ng.com/documents/html/syslog-ng-ose-latest-guides/en/syslog-ng-ose-guide-admin/html/index.html

以下是Centos7.4上的安装过程
yum install zlib-devel libffi-devel 
yum install pcre pcre-devel glib2-devel json-c json-c-devel openssl-devel

安装以下4个依赖,方式都一样./configure && make && makeinstall
flex-2.6.4
bison-3.0.4
autoconf-archive-2017.09.28
pcre-8.41

安装syslog-ng
cd syslog-ng-3.13.2
./configure --prefix=/syslog-ng --with-jsonc=system
make 
make install

java输出日志主要通过log4j或logback,咱公司这两种都用到了,因此提供两种方式的syslog服务器。

syslog-ng for logback配置

syslog-ng.conf 

#############################################################################
# Default syslog-ng.conf file which collects all local logs into a
# single file called /var/log/messages.
#

@version: 3.7
@include "scl.conf"

options {
    keep-hostname(no);
    chain-hostnames(no);
    use-dns(no);
    flush-lines(0);
    time-reap(1);
    log-msg-size(4096);
    create-dirs(yes);  
    stats-freq(3600);
    owner (root);
    group(root);
    perm(0666);
    dir-perm(0777);
};

source s_local {
        system();
        internal();
};

destination d_local {
        file("/var/log/messages");
};

log {
    source(s_local);
    destination(d_local);
};
#logback只支持udp方式输出udp,因此这里通过udp接受日志
source s_app {
    udp(
        ip(0.0.0.0) 
        port(515)
        log_iw_size(50000)
    );
};

filter f_app {
    facility(local2) and (level(error) or level(info) or level(debug));
};
# syslog通过解析日志格式化输出,通过“|”分割日志;同时“[]”中作为一个整体,不做分割;
# 日志分割后,各个字段名称通过columns()来命名;
# template,指定从syslog协议中取的日志来源
parser p_msg {
    csv-parser(
        columns("APPNAME","FILENAME","MYDATE","LOGGER","INVOKENO","CONTENT")
        flags(escape-double-char,strip-whitespace,greedy)
        delimiters("|")
        quote-pairs('[]')
        template("${MSGHDR}${MESSAGE}")
    );
};
# 日志输出到/syslog/${APPNAME}下,以日期做后缀
# 日志格式通过template指定
destination d_appfile {
    file(
        "/syslog/${APPNAME}/${FILENAME}-${LEVEL}.log.$YEAR$MONTH$DAY" 
        template("${MYDATE}|$HOST|${LOGGER}|${INVOKENO}|${CONTENT}\n")
        log-fifo-size(500000)
    );
};

# 日志从收集到解析、输出的处理流
log {
    source(s_app);
    filter(f_app);
    parser(p_msg);
    destination(d_appfile);

};

# java程序logback.xml的配置
# 每个应用的日志可以按2个维度区分:级别、来源
# 级别(debug\info\warning\error)
# 日志来源(通过appender区分不同的java程序打印的日志,如用户登录访问日志,组件mybaits的日志等,可选)
# suffixPattern指定输出的格式,根据syslog-ng的指定,以“|”分割,myapp用于创建目录,myfile1用于文件的前缀



    
    
        syslogserverip
        515
        local2
        true
        [myapp]|myfile1|%date|%logger{50}|%X{invokeNo}|%X{userIP}|%X{userName}|%msg%n%xException
    
	 
    
        syslogserver
        515
        local2
        true
        [myapp]|myfile2|%date|%logger{50}|%X{invokeNo}|%X{userIP}|%X{userName}|%msg%n%xException
    
	 
    
        syslogserver
        515
        local2
        true
        [myapp]|myfile3|%date|%logger{50}|%X{invokeNo}|%X{userIP}|%X{userName}|%msg%n%xException
    
	 
	 
    
	
    
	 
    
	
    
 
    
        
    
 

syslog-ng for log4j配置

syslog-ng.conf 
#############################################################################
# Default syslog-ng.conf file which collects all local logs into a
# single file called /var/log/messages.
#
@version: 3.7
@include "scl.conf"

options {
    keep-hostname(no);
    chain-hostnames(no);
    use-dns(no);
    flush-lines(0);
    time-reap(1);
    log-msg-size(4096);
    create-dirs(yes);  
    stats-freq(3600);
    owner (root);
    group(root);
    perm(0666);
    dir-perm(0777);
};

source s_local {
        system();
        internal();
};
# log4j同时支持tcp\udp方式输出日志,但压力测试过程发现log4j的udp输出到日志服务器日志会串,即A应用的日志会写到B应用的文件中,用tcp没这样的问题
source s_app {
    tcp(
        ip(0.0.0.0) 
        port(515)
        max-connections(500)
        log_iw_size(50000)
    );
};

filter f_app {
    facility(local2) and (level(error) or level(info) or level(debug));
};
# 因为log4j输出的格式和logback不同,因此syslog-ng解析方式也不同
parser p_msg {
    csv-parser(
        columns("MSG.TIME", "MSG.HOSTNAME", "MSG.APPNAME","MSG.PID","MSG.MESSAGEID","MSG.APPINFO","MSG.CONTENT")
        flags(escape-double-char,strip-whitespace,greedy)
        delimiters(" ")
        quote-pairs('[]')
    );
};


rewrite r_nl {
    subst("#NewLine#","\n",value("MSG.CONTENT") flags(global));
    subst("mdc@18060 ","",value("MSG.APPINFO") flags(global));
    subst("syslogk[1-9]=\"","|",value("MSG.APPINFO") flags(global));
    subst("\" ","",value("MSG.APPINFO") flags(global));
    subst("\"","|",value("MSG.APPINFO") flags(global));
};

destination d_local {
        file("/var/log/messages");
};

destination d_appfile {
    file(
        "/syslog/${MSG.APPNAME}/${MSG.MESSAGEID}-$LEVEL.log.$YEAR$MONTH$DAY" 
        template("$(substr $(replace-delimiter 'T' ' ' ${MSG.TIME}) 0 23)|$HOST${MSG.APPINFO}${MSG.CONTENT} \n")
        log-fifo-size(500000)
    );
};

log {
    source(s_local);
    destination(d_local);
};

log {
    source(s_app);
    filter(f_app);
    parser(p_msg);
    rewrite(r_nl);
    destination(d_appfile);
    flags(flow-control);
};


# log4j2.xml
# 中syslogk1是固定字段,对应类名称;syslogk2- syslogk9都是自定义字段,可用于记录登录的用户名,用户的客户端IP等个性化的信息;
# 不需要用的syskogkn,建议删除,否则日志文件中会多余的||,影响日志查看。
# 自定义内容的添加,在java程序中执行:MDC.put("syslogk2", "1111");



	
		
			
				
				 
				
				
				
			
		
		
			
				
				
				
				
				
			
		
	
	
	    
	        
	    
            
	        
	    
	




你可能感兴趣的:(日志)