###############################log4j.properties############################### ##### Global Log Level(OFF,FATAL,ERROR,WARN,INFO,DEBUG,ALL) ############# log4j.rootLogger=DEBUG,STDOUT,DB ###### STDOUT Logger ############### log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender #輸出目的Appender的日誌級別,Appender的級別設置要優先於logger的 #級別設置,即先使用Appender的,而無論logger的日誌級別是怎樣設置的 log4j.appender.STDOUT.Threshold=DEBUG log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout log4j.appender.STDOUT.layout.ConversionPattern=[%p] [%l] %10.10c - %m%n ###### File Logger ############### #開發時,使用DEBUG,發佈時最好修改爲INFO,若是未設置級別,則使用 #父日誌記錄器的,設置了就使用logger的,無論父日誌怎樣設置 log4j.logger.com.mypakge=DEBUG,FILELOGER #開發時設爲true,表示須要屏幕輸出,發佈時這裏最好設置爲false,表示不繼承父日誌記錄器的Appender log4j.additivity.com.mypakge=true log4j.appender.FILELOGER=org.apache.log4j.RollingFileAppender #設置日誌輸出編碼方式爲UTF-8,若是不指定,會以當前運行操做系統的編碼方式記錄,這樣在有的Linux上會出面亂碼 log4j.appender.FILELOGER.encoding=UTF-8 #${LOGS_PATH}爲JVM環境變量,咱們能夠在運行裏給JVM加上該參數 -DLOGS_PATH=e:/tmp/log log4j.appender.FILELOGER.File=${LOGS_PATH}/system.log log4j.appender.FILELOGER.MaxFileSize=1024KB log4j.appender.FILELOGER.MaxBackupIndex=10 #文件採用追加方式 log4j.appender.FILELOGER.Append=true log4j.appender.FILELOGER.layout=org.apache.log4j.PatternLayout log4j.appender.FILELOGER.layout.ConversionPattern=[%d{yyy-MM-dd HH:mm:ss.SSS}] [%p] [%t] [%c] [%l] - [%m]%n ###### THREAD Logger ############### #線程日誌通常記入到另外一個文件,線程日誌與主線程日誌基本上沒有什麼邏輯關係 log4j.logger.threadlogger=DEBUG,THREADLOGER log4j.additivity.threadlogger=true log4j.appender.THREADLOGER=org.apache.log4j.RollingFileAppender log4j.appender.THREADLOGER.encoding=UTF-8 log4j.appender.THREADLOGER.File=${LOGS_PATH}/threadLog.log log4j.appender.THREADLOGER.MaxFileSize=2000KB log4j.appender.THREADLOGER.MaxBackupIndex=10 log4j.appender.THREADLOGER.layout=org.apache.log4j.PatternLayout log4j.appender.THREADLOGER.layout.ConversionPattern=[%d{yyy-MM-dd HH:mm:ss.SSS}] [%p] [%t] [%c] [%l] - [%m]%n ###### SOCKET Logger ############### log4j.addivity.org.apache=true log4j.appender.SOCKET=org.apache.log4j.net.SocketAppender #注,SocketAppender沒有encoding屬性,而接收日誌的服務器端類org.apache.log4j.net.Socke #tServer也不能設置編碼方式,這裏在考慮他們在通訊時是否是傳遞的對象,而不是傳遞的字符串呢? #log4j.appender.SOCKET.encoding=UTF-8 log4j.appender.SOCKET.RemoteHost=localhost log4j.appender.SOCKET.Port=8089 log4j.appender.SOCKET.LocationInfo=true log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout #這裏的格式配置不是很中要,好像不是要所這裏的格式要輸出那些消息,這裏仍是這個疑問就是在通訊時是不是 #傳遞的是序列化後的對象?由於服務器接收到消息後能以任何格式輸出,可見傳遞的信息是完整的。~@!@#!哈 #剛跟了一下org.apache.log4j.net.SocketAppender源碼,在獲取輸出流的時候使用的是對象流,以下: #oos = new ObjectOutputStream(socket.getOutputStream());,這樣就進一步證了個人想法,在 #通訊時時傳遞的是對象,因此就不存在字符編碼的問題與客戶端日誌格式輸出問題。 log4j.appender.SOCKET.layout.ConversionPattern=%m ###### MAIL Logger ############### log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender log4j.appender.MAIL.Threshold=ERROR log4j.appender.MAIL.BufferSize=10 log4j.appender.MAIL.From=junJZ_2008@126.com log4j.appender.MAIL.SMTPHost=smtp.126.com #若是含有中文,則需使用native2asii log4j.properties log4jxx.properties 進行轉換,不然亂碼 log4j.appender.MAIL.Subject=Log4J\u63D0\u9192\u60A8\uFF1A\u7CFB\u7EDF\u53D1\u751F\u4E86\u4E25\u91CD\u9519\u8BEF log4j.appender.MAIL.To=junJZ_2008@163.com log4j.appender.MAIL.SMTPUsername=junJZ_2008@126.com log4j.appender.MAIL.SMTPPassword=XXX log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n ###### DB Logger ############### log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender log4j.appender.DB.driver=com.mysql.jdbc.Driver log4j.appender.DB.URL=jdbc:mysql://127.0.0.1/test log4j.appender.DB.bufferSize=1 log4j.appender.DB.user=root log4j.appender.DB.password=111111 log4j.appender.DB.sql=insert into oplog (UserName,opttype,createTime,LogLevel,methodinfo,MSG) values ('%X{UserName}','%X{opttype}','%d{yyyy-MM-dd HH:mm:ss.SSS}','%p','%l','%m') log4j.appender.DB.layout=org.apache.log4j.PatternLayout |
日誌服務器的服務器端由如下類啓動:
log4j jar包中的org.apache.log4j.net.SocketServer
三個參數 【監聽端口】【日誌服務器配置文件】【客戶端配置文件目錄】
第三個參數【配置文件目錄】其實指的是針對每一個客戶端的配置文件,名命規則爲 "客戶端IP.lcf" javascript
當日志保存請求發過來時,服務器會根據客戶端的IP去在指定的目錄(上面第三個參數)下搜索各自的配置文件,若是沒有找到的話,再找是否配置了公用的客戶端日誌配置文件 generic.lcf,若是也沒有配置的話,它將日誌與服務器運行日誌記錄在同一文件中(這裏爲server.log),若是找到了,會把收到的日誌按照配置文件要求記錄,我在這 裏使用的客戶端配置文件與log4j.properties是同樣的,因此這裏會產生與客戶機保存的日誌是同樣的。 java
在運行前還得要修改一下 org.apache.log4j.net.SocketServer 這個類,這個類在取客戶端時有問題,網上其餘人也這麼認爲(我使用的是1.215版本),找到 String key = s.substring(0, i); 這一行,修改爲 String key = s.substring(i + 1); 便可,而後把修改好的class放入log4j-1.2.15.jar包中(後面附上修改好的包)。 mysql
socketserver.properties sql
#文件名socketserver.properties #若是須要顯示日誌界面,能夠將本行啓用 log4j.rootCategory=, A1 log4j.rootLogger=DEBUG,A3,STDOUT log4j.category.org.apache.log4j.net=INFO log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout log4j.appender.STDOUT.layout.ConversionPattern=[%p] [%l] %10.10c - %m%n log4j.appender.A1=org.apache.log4j.lf5.LF5Appender log4j.appender.A1.MaxNumberOfRecords=700 log4j.appender.A3=org.apache.log4j.RollingFileAppender log4j.appender.A3.file=${LOGS_PATH}/server.log log4j.appender.A3.MaxFileSize=1024KB log4j.appender.A3.MaxBackupIndex=10 log4j.appender.A3.layout=org.apache.log4j.PatternLayout log4j.appender.A3.layout.ConversionPattern=\n\n[%-5p] %d{yyyy-MM-dd HH\:mm\:ss,SSS} method\:%l%n%m%n |
客戶端配置文件 127.0.0.1.lcf 數據庫
###############################log4j.properties############################### |
啓動: 服務器
java -classpath log4j-1.2.15.jar -DLOGS_PATH=e:/tmp/sverlog o
rg.apache.log4j.net.SocketServer 8089 socketserver.properties . app
如今使用一個測試類記錄日誌時,它會往日誌服務器發送日誌事件,服務器會根據服務器端配置的客戶端配置文件記錄日誌。 socket
因爲剛開始使用1.2.9版本的包時 org.apache.log4j.net.SMTPAppender 發送郵件時不支持用戶鑑權操做,而有的郵件服務器在發送時須要先登陸後再發送,因此換用了1.2.15的包,SMTPAppender類支持SMTPUsername與SMTPPassword兩個鑑權參數,這樣就能夠發送日誌郵件了,具體配置參見文章開頭。 測試
建立表:
create table oplog(
UserName varchar(20),
opttype varchar(20),
createTime varchar(30),
LogLevel varchar(20),
methodinfo varchar(100),
MSG varchar(1024),
primary key (createTime)
)
表中的 UserName 與 opttype 表示用戶名與操做類型,插入數據時使用 MDC 類進行預先設置,且配置文件中使用 %x{XXX} 來引用, MDC其實就是Java裏的ThreadLocal類的派生類。
測試代碼: