日志同步工具

我们怎么去做日志同步呢?

方案一:在Log4j的体系中有个东西叫做LoggerFilter,这个类的工具是用来做日志过滤,每次我们打印日志的时候都会经过这个filter,来决定是否打印日志。比如:

  public
  int decide(LoggingEvent event) {
    if(this.levelMin != null) {
      if (event.getLevel().isGreaterOrEqual(levelMin) == false) {
        // level of event is less than minimum
        return Filter.DENY;
      }
    }

    if(this.levelMax != null) {
      if (event.getLevel().toInt() > levelMax.toInt()) {
        // level of event is greater than maximum
        // Alas, there is no Level.isGreater method. and using
        // a combo of isGreaterOrEqual && !Equal seems worse than
        // checking the int values of the level objects..
        return Filter.DENY;
      }
    }

    if (acceptOnMatch) {
      // this filter set up to bypass later filters and always return
      // accept if level in range
      return Filter.ACCEPT;
    }
    else {
      // event is ok for this filter; allow later filters to have a look..
      return Filter.NEUTRAL;
    }
  }

可以看到我们在配置文件里面配置的

        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <param name="LevelMax" value="ERROR" />
            <param name="LevelMin" value="info" />
        </filter>

根据上面的原理,我们可以定义一个filter,然后每次打印日志的时候异步把日志发送出去。

/**
 * Alipay.com Inc.
 * Copyright (c) 2004-2016 All Rights Reserved.
 */
package com.zhangwei.learning.utils.log;

import java.util.Date;

import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;

import com.zhangwei.learning.model.Constants;
import com.zhangwei.learning.model.LogResource;
import com.zhangwei.learning.model.LogResourceDTO;

/**
 * 日志filter
 * @author Administrator
 * @version $Id: LogFilter.java, v 0.1 2016年7月4日 下午9:41:26 Administrator Exp $
 */
public class LogSendFilter extends Filter implements Constants {

    /** 暂存日志的DTO,当日志内容大小到达sendSize的时候,会把日志发送给服务器 */
    private ThreadLocal<LogResourceDTO> dtoThreadLocal   = new ThreadLocal<LogResourceDTO>() {
                                                             protected LogResourceDTO initialValue() {
                                                                 LogResourceDTO logResourceDTO = new LogResourceDTO();
                                                                 return logResourceDTO;
                                                             };
                                                         };

    /** 日志长度为多少字符的时候会触发发送日志事件 */
    private int                         sendSize         = 100;

    /** 系统名 */
    private String                      systemName       = null;

    /** 用于接收日志的服务器 */
    private String                      logServerAddress = null;

    private LogSender                   logSender        = new LogSender();

    /**
     * @see org.apache.log4j.spi.Filter#decide(org.apache.log4j.spi.LoggingEvent)
     */
    @Override
    public int decide(LoggingEvent event) {

        initOnEveryTime();

        sendLogs(event);
        return Filter.ACCEPT;
    }

    /**
     * 每次调用Filter得时候都会初始化下
     */
    private void initOnEveryTime() {
        LogResourceDTO dto = dtoThreadLocal.get();
        dto.setSystemName(systemName);
    }

    /**
     * 按照日志条数发送
     * @param event
     * @return
     */
    private void sendLogs(LoggingEvent event) {
        //先检查大小
        String content = event.getMessage() + EMPTY_STRING;
        LogResourceDTO logResourceDTO = dtoThreadLocal.get();

        logResourceDTO.addLogResource(new LogResource(new Date(), event.getLoggerName(), content));
        //当数据没到sendSize那么保存日志
        if (logResourceDTO.getLogs().size() < sendSize) {
            return;
        }
        //日志超sendSize了,那么发送日志,然后把新的日志保存
        //TODO send data
        try {
            logSender.sendLog(logResourceDTO.reflectToString(), logServerAddress);
            logResourceDTO.clear();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
        return;
    }

    /**
     * Setter method for property <tt>sendSize</tt>.
     *
     * @param sendSize value to be assigned to property sendSize
     */
    public void setSendSize(int sendSize) {
        this.sendSize = sendSize;
    }

    /**
     * 设置系统名
     * @param systemName
     */
    public void setSystemName(String systemName) {
        this.systemName = systemName;
    }

    /**
     * Setter method for property <tt>logServerAddress</tt>.
     *
     * @param logServerAddress value to be assigned to property logServerAddress
     */
    public void setLogServerAddress(String logServerAddress) {
        this.logServerAddress = logServerAddress;
    }
}

日志同步filter

这个filter,实现了如下的功能,使用threadLocal的方式,每个线程都会缓存一个日志DTO对象,发送日志的时候按照条数,达到定义的上限以后,就会把日志发送出去,如果没有达到上限,那就先把日志缓存到本地缓存。

/**
 * 发送日志的task
 * @author Administrator
 * @version $Id: LogSendTask.java, v 0.1 2016年7月4日 下午11:55:21 Administrator Exp $
 */
public class LogSender {

    /** 发送日志的线程池 */
    private ExecutorService THREAD_POOL = Executors
        .newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 3);

    public void sendLog(final String content, final String serverUrl) {
        THREAD_POOL.submit(new Callable<String>() {

            public String call() throws Exception {
                long start = System.currentTimeMillis();
                HttpClientUtil.postData(serverUrl, new HashMap<String, String>() {
                    /**  */
                    private static final long serialVersionUID = 5828324817130371646L;

                    {
                        put(LogResourceDTO.LOG_HTTP_KEY, content);
                    }
                });
                long end = System.currentTimeMillis();
                return (end - start) + "ms";
            }
        });
    }
}

上面采用单独的线程池,将日志发送给指定的服务器,采用的是http协议。

<log4j:configuration xmlns:log4j=‘http://jakarta.apache.org/log4j/‘>
    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss:SSS} %c %m%n" />
        </layout> <!--限制输出级别 -->
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <param name="LevelMax" value="ERROR" />
            <param name="LevelMin" value="info" />
        </filter>
        <filter class="com.zhangwei.learning.utils.log.LogSendFilter">
            <param name="sendSize" value="0" />
            <param name="systemName" value="test" />
            <param name="logServerAddress" value="http://45.62.100.209:8080/DataReceiver/" />
        </filter>
    </appender>
    <root>
        <priority value="debug" />
        <appender-ref ref="CONSOLE" />
    </root>
</log4j:configuration>

filter配置,主要是配置了日志接受服务器,以及本地缓存大小。

缺点分析:1.日志同步在业务主链路上,如果有什么问题会对系统有很大的影响。

时间: 2024-10-22 02:27:40

日志同步工具的相关文章

linux云自动化运维基础知识10(日志同步和时间同步)

####1.系统日志默认分类#### /var/log/messages    ##系统服务及日志,包括服务的信息,报错等等/var/log/secure        ##系统认证信息日志/var/log/maillog    ##系统邮件服务信息/var/log/cron        ##系统定时任务信息/var/log/boot.log    ##系统启动信息 ####2.日志管理服务rsyslog#### 1.rsyslog负责采集日志和分类存放日志2.rsyslog日志分类vim /

Linux的rsync远程数据同步工具

Rsync(remote synchronize) 是一个远程数据同步工具,可以使用"Rsync算法"同步本地和远程主机之间的文件. rsync的好处是只同步两个文件不同的部分,相同的部分不在传递.类似于增量备份, 这使的在服务器传递备份文件或者同步文件,比起scp工具要省好多时间. OS:ubuntu server 10.04 server:192.168.64.128 client:192.168.64.145 server 1.ubuntu  server 10.04默认已安装r

project03日志分析工具AWStats

++++++++++++++++++++ 日志分析工具AWStats ++++++++++++++++++++ http://www.oschina.net/project http://www.oschina.net/project/tag/147/log-analyzer --统计日志分析工具 http://www.awstats.org/ --官方网站 http://www.nltechno.com/awstats/awstats.pl?config=destailleur.fr  --官

Linux下同步工具inotify+rsync使用详解

Linux下同步工具inotify+rsync使用详解 Posted on 2014-12-12 |  In Linux|  9|  Visitors 438 1. rsync 1.1 什么是rsync rsync是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件.它使用所谓的"Rsync演算法"来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快.所以通常可以作为备份工具来使用. 运行Rsync serve

愚公oracle数据库同步工具

最近,利用一些时间对oracle数据库实时同步工具做了一些调研分析,主要关注了linkedin的databus和阿里的yugong两个中间件,其中databus需要在每个待同步的表上增加额外的列和触发器来实现,方案比较重,本文将着重分析一下阿里的yugong实现方案及给出分析调研报告. 1.yugong实时同步原理 使用了oracle的物化视图日志功能,类似于一个内部的触发器,原表的数据库需要对用户授权具有物化视图日志的创建和删除权限,关于物化视图日志的详细描述,可以参考下面的文章: http:

rsync远程数据同步工具应用

一直觉得rsync这个命令复杂不好用,一直在排斥这个工具,抱怨rsync功能简单又复杂难用,这些都不是rsync的问题,只是我不愿意去man这个工具的的帮助文档,其实rsync这个工具也没有想象中那么复杂难用:rsync命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件.rsync使用所谓的"rsync算法"来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快. rsync是一个功能非常强大的工具,其命令

Linux系统备份还原工具4(rsync/数据同步工具)

rsync即是能备份系统也是数据同步的工具. 在Jenkins上可以使用rsync结合SSH的免密登录做数据同步和分发.这样一来可以达到部署全命令化,不需要依赖任何插件去实现. 命令参考:http://man.linuxde.net/rsync 说明: rsync命令 是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件.rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快. rsy

linux同步工具rsync?

linux同步工具rsync 一.rsync命令 rsync命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件.rsync使用所谓的"rsync算法"来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快. rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面就对它的选项一一进行分析说明. 语法: rsync [OPTION]... SRC DEST rsync [OPTION]...

Linux文件同步工具-rsync

Linux文件同步工具-rsync 安装包 yum install -y rsync rsync常用选项 -a:归档模式,表示递归方式传输文件,并保持所有属性:通-rlptgoD:-r:同步目录时要加上,类似cp时加R:-v:同步时显示一些信息,让我们知道同步国创:-l:保留软链接:-L:同步软链接时会把源文件给同步:-p:保持文件权限属性:-o:保持文件的属主:-g:保持文件的属组:-D:保持设备文件信息:-t:保持文件的时间属性:--delte:删除DEST中SRC没有的文件:--exclu