1. 程式人生 > >log4j將日誌儲存到資料庫

log4j將日誌儲存到資料庫

開發十年,就只剩下這套架構體系了! >>>   

helloworld Log4j(一):Log4j將日誌資訊寫入資料庫 前言 為了監聽一些資料的採集等功能,需要隨時監聽裝置的狀態,所以需要執行的時候將日誌打入到資料庫中。

正文 第一步: 首先是jar包,由於我使用的是springboot,所以,在springboot-starter中已經包含了log4j的jar,不需要再導包,如果不是的話,需要匯入log4j的包和mysql-connect的包。

第二步:

接下來是建立log4j的配置檔案:log4j.properties配置檔案,內容如下(這裡只有輸入到資料庫中的配置,如果同時需要輸入到控制檯或者檔案,請自行配置)

複製程式碼

# Define the root logger with appender file
log4j.rootLogger = DEBUG, DB
# Define the DB appender
log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
# Set JDBC URL
log4j.appender.DB.URL=jdbc:mysql://localhost:3306/test
# Set Database Driver
log4j.appender.DB.driver=com.mysql.jdbc.Driver
# Set database user name and password
log4j.appender.DB.user=root
log4j.appender.DB.password=root
# Set the SQL statement to be executed.
log4j.appender.DB.sql=INSERT INTO LOG (CREATE_TIME,TYPE,SYSTEM,HOST,TOTAL_MEMORY,FREE_MEMORY,TOTAL_DISK,FREE_DISK,CPU_CANUSE,DB_CONNECT,LOCATION,LOG_LEVEL,MESSAGE) VALUES (NOW(),'%X{TYPE}','%X{SYSTEM}','%X{HOST}','%X{TOTAL_MEMORY}','%X{FREE_MEMORY}','%X{TOTAL_DISK}','%X{FREE_DISK}','%X{CPU_CANUSE}','%X{DB_CONNECT}','%l','%p','%m')
# Define the layout for file appender
log4j.appender.DB.layout=org.apache.log4j.PatternLayout

複製程式碼

對於上面程式碼的解釋:

第一:寫入資料庫中日誌的時候,可以指定sql語句。比如上面的 insert語句。另外需要指定url,username和password,這樣才能正常插入。

第二:插入的表結構可以自己設定,需要和自己的語句對應,否則會插入錯誤。

第三:我的表結構如下:

複製程式碼

DROP TABLE IF EXISTS `log`;
CREATE TABLE `log` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `CREATE_TIME` datetime DEFAULT NULL COMMENT '建立時間',
  `TYPE` varchar(255) NOT NULL COMMENT '型別:1表示系統資訊,2表示日誌內容資訊',
  `SYSTEM` varchar(255) DEFAULT NULL COMMENT '系統型別-位數,當type=1時候啟用',
  `HOST` varchar(255) DEFAULT NULL COMMENT 'ip,當type=1時候啟用',
  `TOTAL_MEMORY` varchar(255) DEFAULT NULL COMMENT '總記憶體量,當type=1時候啟用',
  `FREE_MEMORY` varchar(255) DEFAULT NULL COMMENT '空閒記憶體,當type=1時候啟用',
  `TOTAL_DISK` varchar(255) DEFAULT NULL COMMENT '工作盤總容量,當type=1時候啟用',
  `FREE_DISK` varchar(255) DEFAULT NULL COMMENT '工作盤剩餘容量,當type=1時候啟用',
  `CPU_CANUSE` varchar(255) DEFAULT NULL COMMENT 'CPU可用百分比,當type=1時候啟用',
  `DB_CONNECT` varchar(255) DEFAULT NULL COMMENT '連線目標資料庫結果,當type=1時候啟用',
  `LOCATION` varchar(255) DEFAULT NULL,
  `LOG_LEVEL` varchar(255) DEFAULT NULL,
  `MESSAGE` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

複製程式碼

第四:插入sql的書寫,在書寫的時候,必須使用'%X{TYPE}' 來表示你需要插入的時候傳入值。特別注意:這裡是大些的X,小寫的不會識別。

第五:最後一些符號的詳情如下

最後是程式碼了:

複製程式碼

import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
import org.hyperic.sigar.*;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.Properties;

/**
 * @Auther: Administrator
 * @Date: 2018/8/20 09:37
 * @Description:
 */
public class Config {

    private static Logger logger = Logger.getLogger(Config.class);

    public static void main(String[] args) throws IOException, SigarException, Exception {
        Properties props = System.getProperties();
        InetAddress addr = InetAddress.getLocalHost();
        MDC.put("TYPE","1");
        MDC.put("HOST",addr.getHostAddress());
        MDC.put("SYSTEM",props.getProperty("os.name") + "-" + props.getProperty("os.arch"));

        Sigar sigar = new Sigar();
        Mem mem = sigar.getMem();
        MDC.put("TOTAL_MEMORY",new BigDecimal(mem.getTotal() / 1024 /1024 / 1024d).setScale(2,BigDecimal.ROUND_HALF_UP) + "GB");
        MDC.put("FREE_MEMORY",new BigDecimal(mem.getFree() / 1024 /1024 / 1024d).setScale(2,BigDecimal.ROUND_HALF_UP) + "GB");

        CpuInfo[] infos= sigar.getCpuInfoList();
        CpuPerc[] cpuList = sigar.getCpuPercList();
        Double totalFree = 0.0d;

        for (int i = 0; i < infos.length; i++) {// 不管是單塊CPU還是多CPU都適用
            CpuPerc cpu = cpuList[i];
            totalFree += cpu.getIdle();
        }

        MDC.put("CPU_CANUSE",String.valueOf(totalFree/cpuList.length));
        FileSystem[] fslist = sigar.getFileSystemList();

        String totalDisk = null;
        String freeDisk = null;
        for (int i = 0; i < fslist.length; i++) {
            FileSystem fs = fslist[i];
            if (fs.getDevName().contains("E")) {
                FileSystemUsage usage = sigar.getFileSystemUsage(fs.getDirName());
                if (fs.getType() == 2) {
                    // 檔案系統總大小
                    MDC.put("TOTAL_DISK",new BigDecimal(usage.getTotal() / 1024d / 1024).setScale(2,BigDecimal.ROUND_HALF_UP) + "GB");
                    MDC.put("FREE_DISK",new BigDecimal(usage.getFree() / 1024d / 1024).setScale(2,BigDecimal.ROUND_HALF_UP) + "GB");
                }
            }
        }
        MDC.put("DB_CONNECT",true);
        try{

            int[] arr = {1,2,3};
            for (int i = 0; i < arr.length + 1 ; i++) {
                System.out.println(arr[i]);
            }
        }catch (Exception e){
            logger.error("出現了異常", e);
            logger.error("出現異常:" + getExceptionMsg(e));
        }

    }


    private static String getExceptionMsg(Exception e){
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);
        e.printStackTrace(pw);
        pw.flush();
        sw.flush();
        return sw.toString();
    }
}

複製程式碼

寫在最後:需要特別特別注意的是:因為我們要插入資料,很多資料都是自己事先指定的資料,所以,我們得使用MDC來把這些資料放入,然後直接打日誌就可以存入資料庫中了。

還有:注意導包的時候一定要使用log4j的logger物件,否則可能無法完成日誌的插入。

關於slf4j來完成,目前我使用一直無法寫入資料庫,晚點更新結果。

附錄:完整版本的log4j.properties配置檔案

複製程式碼

log4j.rootLogger = DEBUG,D,I,E,A,DB

log4jFileName = dailywork

log4j.appender.A = org.apache.log4j.ConsoleAppender
log4j.appender.A.Target = System.out
log4j.appender.A.Threshold=debug
log4j.appender.A.layout = org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern = %d{yyyy-MM-dd HH\:mm\:ss,SSS}%6p [%F\:%L] - %m%n

log4j.appender.I=org.apache.log4j.RollingFileAppender
log4j.appender.I.File=${log4jFileName}_info.log
log4j.appender.I.Threshold=INFO
log4j.appender.I.MaxFileSize = 20MB
log4j.appender.I.MaxBackupIndex = 5
log4j.appender.I.Append=true
log4j.appender.I.layout=org.apache.log4j.PatternLayout
log4j.appender.I.layout.ConversionPattern= %d{yyyy-MM-dd HH\:mm\:ss,SSS}%6p [%F\:%L] - %m%n

log4j.appender.D=org.apache.log4j.RollingFileAppender
log4j.appender.D.File=${log4jFileName}_debug.log
log4j.appender.D.Threshold=DEBUG
log4j.appender.D.MaxFileSize = 20MB
log4j.appender.D.MaxBackupIndex = 5
log4j.appender.D.Append=true
log4j.appender.D.layout=org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern= %d{yyyy-MM-dd HH\:mm\:ss,SSS}%6p [%F\:%L] - %m%n

log4j.appender.W=org.apache.log4j.RollingFileAppender
log4j.appender.W.File=${log4jFileName}_warn.log
log4j.appender.W.Threshold=WARN
log4j.appender.W.MaxFileSize = 20MB
log4j.appender.W.MaxBackupIndex = 5
log4j.appender.W.Append=true
log4j.appender.W.layout=org.apache.log4j.PatternLayout
log4j.appender.W.layout.ConversionPattern= %d{yyyy-MM-dd HH\:mm\:ss,SSS}%6p [%F\:%L] - %m%n

log4j.appender.E=org.apache.log4j.RollingFileAppender
log4j.appender.E.File=${log4jFileName}_error.log
log4j.appender.E.Threshold=ERROR
log4j.appender.E.MaxFileSize = 20MB
log4j.appender.E.MaxBackupIndex = 5
log4j.appender.E.Append=true
log4j.appender.E.layout=org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern= %d{yyyy-MM-dd HH\:mm\:ss,SSS}%6p [%F\:%L] - %m%n

log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DB.driver=com.mysql.jdbc.Driver
log4j.appender.DB.user=root
log4j.appender.DB.password=root
log4j.appender.DB.sql=INSERT INTO LOG (CREATE_TIME,TYPE,SYSTEM,HOST,TOTAL_MEMORY,FREE_MEMORY,TOTAL_DISK,FREE_DISK,CPU_CANUSE,DB_CONNECT,LOCATION,LOG_LEVEL,MESSAGE) VALUES (NOW(),'%X{TYPE}','%X{SYSTEM}','%X{HOST}','%X{TOTAL_MEMORY}','%X{FREE_MEMORY}','%X{TOTAL_DISK}','%X{FREE_DISK}','%X{CPU_CANUSE}','%X{DB_CONNECT}','%l','%p','%m')
log4j.appender.DB