zoukankan      html  css  js  c++  java
  • 玩转mongodb(九):通过log4jmongo来实现分布式系统的日志统一管理

    背景

      在分布式系统中,我们有多个web app,这些web app可能分别部署在不同的物理服务器上,并且有各自的日志输出。当生产问题来临时,很多时候都需要去各个日志文件中查找可能的异常,相当耗费人力。日志存储多以文本文件形式存在,当有需求需要对日志进行分析挖掘时,这个处理起来也是诸多不便,而且效率低下。

      为了方便对这些日志进行统一管理和分析,我们可以将日志统一输出到指定的数据库系统中,再由日志分析系统去管理。由于这里是mongodb的篇章,所以主观上以mongodb来做日志数据存储;客观上,一是因为它轻便、简单,与log4j整合方便,对系统的侵入性低。二是因为它与大型的关系型数据库相比有很多优势,比如查询快速bson存储结构利于扩展免费等。

    解决方案

    整合mongodb和log4j

    1、安装mongodb数据库,并在本地启动,默认端口是27017,详细请参考:玩转mongodb(一):初识mongodb

    2、新建一个maven(maven版本要求3.0以上)工程,选择maven-archetype-quickstart,工程名:log4j2mongo

    3、在pom.xml文件中,添加log4j、log4mongo-java、mongo-java-driver三个依赖。具体代码如下:

     1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     2   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     3   <modelVersion>4.0.0</modelVersion>
     4 
     5   <groupId>com.manyjar</groupId>
     6   <artifactId>log4j2mongo</artifactId>
     7   <version>0.0.1-SNAPSHOT</version>
     8   <packaging>jar</packaging>
     9 
    10   <name>log4j2mongo</name>
    11   <url>http://maven.apache.org</url>
    12   
    13   <properties>  
    14     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
    15     <junit.version>3.8.1</junit.version>  
    16     <log4j.version>1.2.17</log4j.version>  
    17     <log4mongo.version>0.7.4</log4mongo.version>  
    18     <mongo-java-driver.version>2.8.0</mongo-java-driver.version>  
    19   </properties> 
    20 
    21   <dependencies>
    22     <dependency>  
    23       <groupId>junit</groupId>  
    24       <artifactId>junit</artifactId>  
    25       <version>${junit.version}</version>  
    26       <scope>test</scope>  
    27     </dependency>  
    28   
    29       <dependency>  
    30           <groupId>log4j</groupId>  
    31           <artifactId>log4j</artifactId>  
    32           <version>${log4j.version}</version>  
    33       </dependency>  
    34   
    35       <dependency>  
    36           <groupId>org.log4mongo</groupId>  
    37           <artifactId>log4mongo-java</artifactId>  
    38           <version>${log4mongo.version}</version>  
    39       </dependency>  
    40   
    41       <dependency>  
    42           <groupId>org.mongodb</groupId>  
    43           <artifactId>mongo-java-driver</artifactId>  
    44           <version>${mongo-java-driver.version}</version>  
    45       </dependency>
    46   </dependencies>
    47 </project>
    pom.xml

    4、在resources文件夹中,添加log4j.properties文件。文件中主要添加log4j对mongodb的适配器org.log4mongo.MongoDbAppender。这里的适配器是log4mongo-java这个jar包提供。mongodb数据库的ip:127.0.0.1,port:27017,库名:logs,集合名:log。具体配置如下:

     1 log4j.rootLogger=DEBUG,MongoDB
     2 log4j.appender.MongoDB=org.log4mongo.MongoDbAppender
     3 log4j.appender.MongoDB.databaseName=logs
     4 log4j.appender.MongoDB.collectionName=log
     5 log4j.appender.MongoDB.hostname=127.0.0.1
     6 log4j.appender.MongoDB.port=27017
     7    
     8 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
     9 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    10 log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
    log4j.properties

    5、在java文件夹中,com.manyjar.log4j2mongo这个包中,添加Main.java文件,观察文件中的代码可以发现,和我们平时用log4j来写日志一模一样,把日志流到mongodb这件事情,对业务开发的程序员完全透明。具体代码如下:

     1 package com.manyjar.log4j2mongo;
     2 
     3 import org.apache.log4j.Logger;
     4 
     5 import com.mongodb.BasicDBObject;
     6 import com.mongodb.DBObject;
     7 
     8 public class Main {
     9     
    10     public static void main(String[] args) {
    11         Logger logger = Logger.getLogger(Main.class);
    12             
    13             for (int i = 0; i < 10000000; i++) {
    14                 DBObject bson = new BasicDBObject();
    15                 bson.put("name", "ryan"+i);
    16                 logger.debug(bson);
    17             }
    18     }
    19 }
    Main.java

    6、步骤5中,我们执行了1000万次的日志插入,数据结构如下:

    默认的数据量大小有10G:

    这里,我们可以看到,日志的数据存储量相对不小。如果需要修改日志数据的存储结构,可以用log4mongo的源代码进行二次开发。

    如果数据量过大,我们可以用TTL索引(过期自动删除)或固定集合大小两种方式来解决:

    TTL索引:db.log_events.createIndex({"timestamp": 1},{expireAfterSeconds: 60*60*24*30}) #1个月后过期后删除

    将log集合修改成固定大小集合:db.runCommand({"convertToCapped":"log",size:10000})

    喜欢请微信扫描下面二维码,关注我公众号--“精修Java”,做一些实战项目中的问题和解决方案分享。 

  • 相关阅读:
    谷歌浏览器内核自带长截图
    js文件导入swiper方法及分页器不显示原因
    Error: Cannot find module 'gifsicle'问题解决
    新型横向移动工具原理分析、代码分析、优缺点以及检测方案
    武汉解封一周年
    JAVA线程池ThreadPoolExecutor的分析和使用(新手踩坑和推荐方案)
    JAVA常量池
    Java String的intern()注意事项(分JDK1.6及JDK1.7)
    JAVA的类加载过程
    react hooks方法获取不到最新的state解决方法
  • 原文地址:https://www.cnblogs.com/zhouqinxiong/p/6822260.html
Copyright © 2011-2022 走看看