思路:由于系统特殊需求,日志必须记录完整的客户轨迹,采用Log4j的方式,在文件中无法有效处理和统计分析,所以考虑使用MongoDB作为日志服务器。log4j有MongoDB的接口,这种方式系统侵入和修改很小,但是一直没试通,最后没办法自己采用传统方式做了一个日志工具类和MongoDB连接写入类,而且把系统必要的日志也重新设计了一下,都做了相应调整。

代码如下:

public class LogUtils {

    private static Logger logger = LoggerFactory.getLogger(LogUtils.class);

    /**
     * @param querySeq
     *            识别号
     * @param method
     *            方法
     * @param line
     *            行号
     * @param content
     *            内容
     * @param level
     *            日志级别
     * @param logger
     * @return
     */
    public static void crtLoggerJson(Class<?> cls, String querySeq, String method, int line, String level,
            String content) {
        Document doc = new Document(WsLog.FIELD_QUERYSEQ, querySeq)
                .append(WsLog.FIELD_CRTDATE, CommUtils.FormatDateToString(new Date(), "yyyy-MM-dd HH:mm:ss SSS"))
                .append(WsLog.FIELD_CLASSNAME, cls.getName()).append(WsLog.FIELD_MEHTOD, method)
                .append(WsLog.FIELD_LINE, String.valueOf(line)).append(WsLog.FIELD_LEVEL, level).append(WsLog.FIELD_CONTENT, content);
        MongoDBUtils mg = new MongoDBUtils();
        mg.insertLog(doc);
        //logger.debug(doc.toJson());
    }

    /**
     * 简单日志
     * @param querySeq 识别号
     * @param content 内容
     */
    public static void crtLoggerJson(String querySeq, String content) {
        Document doc = new Document(WsLog.FIELD_QUERYSEQ, querySeq).append(WsLog.FIELD_CRTDATE,
                CommUtils.FormatDateToString(new Date(), "yyyy-MM-dd HH:mm:ss SSS")).append(WsLog.FIELD_CONTENT,
                content);
        MongoDBUtils mg = new MongoDBUtils();
        mg.insertLog(doc);
        //logger.debug(doc.toJson());
    }

    /**
     * 耗时日志
     * @param querySeq 识别号
     * @param time 耗时,单位为毫秒
     * @param content 内容
     * @param detaile 内容
     */
    public static void crtLoggerJson(String querySeq, long time, String content, String detaile) {
        Document doc = new Document(WsLog.FIELD_QUERYSEQ, querySeq)
                .append(WsLog.FIELD_CRTDATE, CommUtils.FormatDateToString(new Date(), "yyyy-MM-dd HH:mm:ss SSS"))
                .append(WsLog.FIELD_CONTENT, content).append(WsLog.FIELD_ETIME, String.valueOf(time))
                .append(WsLog.FIELD_DETAIL, detaile);
        MongoDBUtils mg = new MongoDBUtils();
        mg.insertLog(doc);
        //logger.debug(doc.toJson());
    }
}
public class LogUtils {

    private static Logger logger = LoggerFactory.getLogger(LogUtils.class);

    /**
     * @param querySeq
     *            识别号
     * @param method
     *            方法
     * @param line
     *            行号
     * @param content
     *            内容
     * @param level
     *            日志级别
     * @param logger
     * @return
     */
    public static void crtLoggerJson(Class<?> cls, String querySeq, String method, int line, String level,
            String content) {
        Document doc = new Document(WsLog.FIELD_QUERYSEQ, querySeq)
                .append(WsLog.FIELD_CRTDATE, CommUtils.FormatDateToString(new Date(), "yyyy-MM-dd HH:mm:ss SSS"))
                .append(WsLog.FIELD_CLASSNAME, cls.getName()).append(WsLog.FIELD_MEHTOD, method)
                .append(WsLog.FIELD_LINE, String.valueOf(line)).append(WsLog.FIELD_LEVEL, level).append(WsLog.FIELD_CONTENT, content);
        MongoDBUtils mg = new MongoDBUtils();
        mg.insertLog(doc);
        //logger.debug(doc.toJson());
    }

    /**
     * 简单日志
     * @param querySeq 识别号
     * @param content 内容
     */
    public static void crtLoggerJson(String querySeq, String content) {
        Document doc = new Document(WsLog.FIELD_QUERYSEQ, querySeq).append(WsLog.FIELD_CRTDATE,
                CommUtils.FormatDateToString(new Date(), "yyyy-MM-dd HH:mm:ss SSS")).append(WsLog.FIELD_CONTENT,
                content);
        MongoDBUtils mg = new MongoDBUtils();
        mg.insertLog(doc);
        //logger.debug(doc.toJson());
    }

    /**
     * 耗时日志
     * @param querySeq 识别号
     * @param time 耗时,单位为毫秒
     * @param content 内容
     * @param detaile 内容
     */
    public static void crtLoggerJson(String querySeq, long time, String content, String detaile) {
        Document doc = new Document(WsLog.FIELD_QUERYSEQ, querySeq)
                .append(WsLog.FIELD_CRTDATE, CommUtils.FormatDateToString(new Date(), "yyyy-MM-dd HH:mm:ss SSS"))
                .append(WsLog.FIELD_CONTENT, content).append(WsLog.FIELD_ETIME, String.valueOf(time))
                .append(WsLog.FIELD_DETAIL, detaile);
        MongoDBUtils mg = new MongoDBUtils();
        mg.insertLog(doc);
        //logger.debug(doc.toJson());
    }
}
public class MongoDBUtils {
    private static Logger logger = LoggerFactory.getLogger(MongoDBUtils.class);

    public static MongoClient mongoClient;
    private static MongoDatabase database;
    private static MongoCollection<Document> collection;

    public MongoDBUtils() {
        try {
            if (mongoClient == null) {
                MongoClientOptions mgco = new MongoClientOptions.Builder().socketKeepAlive(true) // 是否保持长链接
                        .connectTimeout(5000) // 链接超时时间
                        .socketTimeout(5000) // read数据超时时间
                        .readPreference(ReadPreference.primary()) // 最近优先策略
                        .connectionsPerHost(60) // 每个地址最大请求数
                        .maxWaitTime(1000 * 60 * 2) // 长链接的最大等待时间
                        .threadsAllowedToBlockForConnectionMultiplier(50) // 一个socket最大的等待请求数
                        .writeConcern(WriteConcern.NORMAL).build();
                String host = ZtzxUtils.getJdbcConfig("mongodb.host");
                String port = ZtzxUtils.getJdbcConfig("mongodb.port");
                if (StringUtils.isBlank(host)) {
                    host = "localhost";
                }
                if (StringUtils.isBlank(port)) {
                    port = "27017";
                }

                // String user = ZtzxUtils.getJdbcConfig("");
                // String pwd = ZtzxUtils.getJdbcConfig("");

                mongoClient = new MongoClient(new ServerAddress(host, Integer.parseInt(port)), mgco);

            }
        } catch (Exception e) {
            logger.error("mongodb connect error=" + e.toString());
        }
    }

    public void insertLog(Document doc) {
        try {
            // 获取temp DB;如果默认没有创建,mongodb会自动创建
            database = mongoClient.getDatabase(WsLog.DBNAME);

            // 如果默认没有创建,mongodb会自动创建
            collection = database.getCollection(WsLog.COLLECTION);
            collection.insertOne(doc);
        } catch (Exception e) {
            logger.error("mongodb insertLog:{} error=" + e.toString(), doc.toJson());
        }
    }

    public MongoCursor<Document> query(String uuid) {
        if (StringUtils.isBlank(uuid)) {
            return null;
        }
        try {
            // 获取temp DB;如果默认没有创建,mongodb会自动创建
            database = mongoClient.getDatabase(WsLog.DBNAME);
            // 如果默认没有创建,mongodb会自动创建
            collection = database.getCollection(WsLog.COLLECTION);

            return collection.find(eq("querySeq", uuid)).sort(ascending(WsLog.FIELD_CRTDATE)).iterator();

        } catch (Exception e) {
            logger.error("mongodb query error=" + e.toString());
            return null;
        }
    }

}
public class MongoDBUtils {
    private static Logger logger = LoggerFactory.getLogger(MongoDBUtils.class);

    public static MongoClient mongoClient;
    private static MongoDatabase database;
    private static MongoCollection<Document> collection;

    public MongoDBUtils() {
        try {
            if (mongoClient == null) {
                MongoClientOptions mgco = new MongoClientOptions.Builder().socketKeepAlive(true) // 是否保持长链接
                        .connectTimeout(5000) // 链接超时时间
                        .socketTimeout(5000) // read数据超时时间
                        .readPreference(ReadPreference.primary()) // 最近优先策略
                        .connectionsPerHost(60) // 每个地址最大请求数
                        .maxWaitTime(1000 * 60 * 2) // 长链接的最大等待时间
                        .threadsAllowedToBlockForConnectionMultiplier(50) // 一个socket最大的等待请求数
                        .writeConcern(WriteConcern.NORMAL).build();
                String host = ZtzxUtils.getJdbcConfig("mongodb.host");
                String port = ZtzxUtils.getJdbcConfig("mongodb.port");
                if (StringUtils.isBlank(host)) {
                    host = "localhost";
                }
                if (StringUtils.isBlank(port)) {
                    port = "27017";
                }

                // String user = ZtzxUtils.getJdbcConfig("");
                // String pwd = ZtzxUtils.getJdbcConfig("");

                mongoClient = new MongoClient(new ServerAddress(host, Integer.parseInt(port)), mgco);

            }
        } catch (Exception e) {
            logger.error("mongodb connect error=" + e.toString());
        }
    }

    public void insertLog(Document doc) {
        try {
            // 获取temp DB;如果默认没有创建,mongodb会自动创建
            database = mongoClient.getDatabase(WsLog.DBNAME);

            // 如果默认没有创建,mongodb会自动创建
            collection = database.getCollection(WsLog.COLLECTION);
            collection.insertOne(doc);
        } catch (Exception e) {
            logger.error("mongodb insertLog:{} error=" + e.toString(), doc.toJson());
        }
    }

    public MongoCursor<Document> query(String uuid) {
        if (StringUtils.isBlank(uuid)) {
            return null;
        }
        try {
            // 获取temp DB;如果默认没有创建,mongodb会自动创建
            database = mongoClient.getDatabase(WsLog.DBNAME);
            // 如果默认没有创建,mongodb会自动创建
            collection = database.getCollection(WsLog.COLLECTION);

            return collection.find(eq("querySeq", uuid)).sort(ascending(WsLog.FIELD_CRTDATE)).iterator();

        } catch (Exception e) {
            logger.error("mongodb query error=" + e.toString());
            return null;
        }
    }

}
LogUtils.crtLoggerJson(SysdJServicesImpl.class, uuid, "single", 120, "debug", "invoke WebService start:"
                    + userName + ";" + serviceCode + ";" + param + ";" + ip);

//记录耗时
LogUtils.crtLoggerJson(uuid,(System.currentTimeMillis()-start), "SysdJServicesImpl.single end","");
LogUtils.crtLoggerJson(SysdJServicesImpl.class, uuid, "single", 120, "debug", "invoke WebService start:"
                    + userName + ";" + serviceCode + ";" + param + ";" + ip);

//记录耗时
LogUtils.crtLoggerJson(uuid,(System.currentTimeMillis()-start), "SysdJServicesImpl.single end","");
日志实体类:
public class WsLog {
    
    public static final String DBNAME="sysd";
    public static final String COLLECTION="wslog";
    
    public static final String FIELD_QUERYSEQ="querySeq";
    public static final String FIELD_CRTDATE="crtDate";
    public static final String FIELD_CONTENT="content";
    public static final String FIELD_CLASSNAME="className";
    public static final String FIELD_MEHTOD="method";
    public static final String FIELD_LINE="line";
    public static final String FIELD_LEVEL="level";
    public static final String FIELD_ETIME="etime";
    public static final String FIELD_DETAIL="detail";
    
    private Oid _id;
    private String querySeq;
    private String crtDate;
    private String content;
    private String className;
    private String method;
    private String line;
    private String level;
    private String etime;
    private String detail;
    
    public WsLog() {
        super();
    }
    
    public class Oid{
        String $oid;

        public String get$oid() {
            return $oid;
        }

        public void set$oid(String $oid) {
            this.$oid = $oid;
        }
    }
    其他getter setter方式
    }
日志实体类:
public class WsLog {
    
    public static final String DBNAME="sysd";
    public static final String COLLECTION="wslog";
    
    public static final String FIELD_QUERYSEQ="querySeq";
    public static final String FIELD_CRTDATE="crtDate";
    public static final String FIELD_CONTENT="content";
    public static final String FIELD_CLASSNAME="className";
    public static final String FIELD_MEHTOD="method";
    public static final String FIELD_LINE="line";
    public static final String FIELD_LEVEL="level";
    public static final String FIELD_ETIME="etime";
    public static final String FIELD_DETAIL="detail";
    
    private Oid _id;
    private String querySeq;
    private String crtDate;
    private String content;
    private String className;
    private String method;
    private String line;
    private String level;
    private String etime;
    private String detail;
    
    public WsLog() {
        super();
    }
    
    public class Oid{
        String $oid;

        public String get$oid() {
            return $oid;
        }

        public void set$oid(String $oid) {
            this.$oid = $oid;
        }
    }
    其他getter setter方式
    }


private String querySeq;
    
    private List<WsLog> datas;
    
    public String list(){
        
        if(StringUtils.isBlank(querySeq)){
            datas = new ArrayList<WsLog>();
            return SUCCESS;
        }
        
        try {
            MongoDBUtils mg = new MongoDBUtils();
            MongoCursor<Document> cols = mg.query(querySeq);
            datas = new ArrayList<WsLog>();
            Gson gson = new Gson();
            while (cols.hasNext()) {
                datas.add(gson.fromJson(cols.next().toJson(), WsLog.class));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return SUCCESS;
    }
private String querySeq;
    
    private List<WsLog> datas;
    
    public String list(){
        
        if(StringUtils.isBlank(querySeq)){
            datas = new ArrayList<WsLog>();
            return SUCCESS;
        }
        
        try {
            MongoDBUtils mg = new MongoDBUtils();
            MongoCursor<Document> cols = mg.query(querySeq);
            datas = new ArrayList<WsLog>();
            Gson gson = new Gson();
            while (cols.hasNext()) {
                datas.add(gson.fromJson(cols.next().toJson(), WsLog.class));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return SUCCESS;
    }