【讀書筆記】WEB應用:1、日誌配置
log4j.properties 使用
一.引數意義說明
輸出級別的種類
ERROR、WARN、INFO、DEBUG
ERROR 為嚴重錯誤 主要是程式的錯誤
WARN 為一般警告,比如session丟失
INFO 為一般要顯示的資訊,比如登入登出
DEBUG 為程式的除錯資訊
配置日誌資訊輸出目的地
log4j.appender.appenderName = fully.qualified.name.of.appender.class
1.org.apache.log4j.ConsoleAppender(控制檯)
2.org.apache.log4j.FileAppender(檔案)
3.org.apache.log4j.DailyRollingFileAppender(每天產生一個日誌檔案)
4.org.apache.log4j.RollingFileAppender(檔案大小到達指定尺寸的時候產生一個新的檔案)
5.org.apache.log4j.WriterAppender(將日誌資訊以流格式傳送到任意指定的地方)
配置日誌資訊的格式
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
1.org.apache.log4j.HTMLLayout(以HTML表格形式佈局),
2.org.apache.log4j.PatternLayout(可以靈活地指定佈局模式),
3.org.apache.log4j.SimpleLayout(包含日誌資訊的級別和資訊字串),
4.org.apache.log4j.TTCCLayout(包含日誌產生的時間、執行緒、類別等等資訊)
控制檯選項
Threshold=DEBUG:指定日誌訊息的輸出最低層次。
ImmediateFlush=true:預設值是true,意謂著所有的訊息都會被立即輸出。
Target=System.err:預設情況下是:System.out,指定輸出控制檯
FileAppender 選項
Threshold=DEBUF:指定日誌訊息的輸出最低層次。
ImmediateFlush=true:預設值是true,意謂著所有的訊息都會被立即輸出。
File=mylog.txt:指定訊息輸出到mylog.txt檔案。
Append=false:預設值是true,即將訊息增加到指定檔案中,false指將訊息覆蓋指定的檔案內容。
RollingFileAppender 選項
Threshold=DEBUG:指定日誌訊息的輸出最低層次。
ImmediateFlush=true:預設值是true,意謂著所有的訊息都會被立即輸出。
File=mylog.txt:指定訊息輸出到mylog.txt檔案。
Append=false:預設值是true,即將訊息增加到指定檔案中,false指將訊息覆蓋指定的檔案內容。
MaxFileSize=100KB: 字尾可以是KB, MB 或者是 GB. 在日誌檔案到達該大小時,將會自動滾動,即將原來的內容移到mylog.log.1檔案。
MaxBackupIndex=2:指定可以產生的滾動檔案的最大數。
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n
日誌資訊格式中幾個符號所代表的含義:
-X號: X資訊輸出時左對齊;
%p: 輸出日誌資訊優先順序,即DEBUG,INFO,WARN,ERROR,FATAL,
%d: 輸出日誌時間點的日期或時間,預設格式為ISO8601,也可以在其後指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},輸出類似:2002年10月18日 22:10:28,921
%r: 輸出自應用啟動到輸出該log資訊耗費的毫秒數
%c: 輸出日誌資訊所屬的類目,通常就是所在類的全名
%t: 輸出產生該日誌事件的執行緒名
%l: 輸出日誌事件的發生位置,相當於%C.%M(%F:%L)的組合,包括類目名、發生的執行緒,以及在程式碼中的行數。舉例:Testlog4.main (TestLog4.java:10)
%x: 輸出和當前執行緒相關聯的NDC(巢狀診斷環境),尤其用到像java servlets這樣的多客戶多執行緒的應用中。
%%: 輸出一個"%"字元
%F: 輸出日誌訊息產生時所在的檔名稱
%L: 輸出程式碼中的行號
%m: 輸出程式碼中指定的訊息,產生的日誌具體資訊
%n: 輸出一個回車換行符,Windows平臺為"\r\n",Unix平臺為"\n"輸出日誌資訊換行
可以在%與模式字元之間加上修飾符來控制其最小寬度、最大寬度、和文字的對齊方式。如:
1)%20c:指定輸出category的名稱,最小的寬度是20,如果category的名稱小於20的話,預設的情況下右對齊。
2)%-20c:指定輸出category的名稱,最小的寬度是20,如果category的名稱小於20的話,"-"號指定左對齊。
3)%.30c:指定輸出category的名稱,最大的寬度是30,如果category的名稱大於30的話,就會將左邊多出的字元截掉,但小於30的話也不會有空格。
4)%20.30c:如果category的名稱小於20就補空格,並且右對齊,如果其名稱長於30字元,就從左邊較遠輸出的字元截掉。
二.檔案配置Sample1
log4j.rootLogger=DEBUG,A1,R
#log4j.rootLogger=INFO,A1,R
# ConsoleAppender 輸出
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
# File 輸出 一天一個檔案,輸出路徑可以定製,一般在根路徑下
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=blog_log.txt
log4j.appender.R.MaxFileSize=500KB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n
檔案配置Sample2
下面給出的Log4J配置檔案實現了輸出到控制檯,檔案,回滾檔案,傳送日誌郵件,輸出到資料庫日誌表,自定義標籤等全套功能。
log4j.rootLogger=DEBUG,CONSOLE,A1,im
#DEBUG,CONSOLE,FILE,ROLLING_FILE,MAIL,DATABASE
log4j.addivity.org.apache=true
###################
# Console Appender
###################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
#####################
# File Appender
#####################
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# Use this layout for LogFactor 5 analysis
########################
# Rolling File
########################
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
####################
# Socket Appender
####################
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
########################
# Log Factor 5 Appender
########################
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
########################
# SMTP Appender
#######################
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
[email protected]
log4j.appender.MAIL.SMTPHost=mail.hollycrm.com
log4j.appender.MAIL.Subject=Log4J Message
[email protected]
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
########################
# JDBC Appender
#######################
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
###################
#自定義Appender
###################
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = [email protected]
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
今天沒事隨便看了看專案程式碼,無意間留意到了日誌這一塊,於是就重新寫了一個專案,分別瞭解熟悉了從單獨使用log4j、slf4j和log4j結合、logback和slf4j的結合使用,下面就將遇到的問題記錄下來
jar包(日誌相關):
log4j-1.2.12.jar
slf4j-api-1.6.4.jar
slf4j-log4j12-1.6.1.jar
logback-classic-1.0.0.jar
logback-core-1.0.0.jar
專案結構:
servlet3.1
spring 4
spring mvc
mybatis
功能:
查詢資料庫
例項一:
將log4j-1.2.12.jar引入到classpath下,專案會在啟動的時候載入log4j-1.2.12.jar裡面的類,在src的目錄下順序查詢檔案,那麼就看下這個jar包下的LogManager.class的原始碼
static
{
Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG));
repositorySelector = new DefaultRepositorySelector(h);
String override = OptionConverter.getSystemProperty("log4j.defaultInitOverride", null);
if(override == null || "false".equalsIgnoreCase(override))
{
String configurationOptionStr = OptionConverter.getSystemProperty("log4j.configuration", null);
String configuratorClassName = OptionConverter.getSystemProperty("log4j.configuratorClass", null);
URL url = null;
if(configurationOptionStr == null)
{
url = Loader.getResource("log4j.xml");
if(url == null)
url = Loader.getResource("log4j.properties");
} else
{
try
{
url = new URL(configurationOptionStr);
}
catch(MalformedURLException _ex)
{
url = Loader.getResource(configurationOptionStr);
}
}
if(url != null)
{
LogLog.debug("Using URL [" + url + "] for automatic log4j configuration.");
OptionConverter.selectAndConfigure(url, configuratorClassName, getLoggerRepository());
} else
{
LogLog.debug("Could not find resource: [" + configurationOptionStr + "].");
}
}
}
再看下log4j.properties中的配置
例項二:
在例項一的基礎上將slf4j-api-1.6.4.jar和slf4j-log4j12-1.6.1.jar引入到classpath下,將繫結的實現轉移到log4j-1.2.12.jar中的類來實現(具體原理可以看官方文件)
例項三:
將log4j-1.2.12.jar去掉,引入logback-classic-1.0.0.jar和logback-core-1.0.0.jar,將繫結的實現轉移到logback-classic-1.0.0.jar中的類來實現(具體原理可以看官方文件)
ContextInitializer.class這個原始碼中有
private URL findConfigFileURLFromSystemProperties(ClassLoader classLoader, boolean updateStatus)
{
String logbackConfigFile;
URL result;
logbackConfigFile = OptionHelper.getSystemProperty("logback.configurationFile");
if(logbackConfigFile == null)
break MISSING_BLOCK_LABEL_164;
result = null;
URL url;
result = new URL(logbackConfigFile);
url = result;
if(updateStatus)
statusOnResourceSearch(logbackConfigFile, classLoader, result);
return url;
MalformedURLException e;
e;
File f;
result = Loader.getResource(logbackConfigFile, classLoader);
if(result == null)
break MISSING_BLOCK_LABEL_75;
f = result;
if(updateStatus)
statusOnResourceSearch(logbackConfigFile, classLoader, result);
return f;
f = new File(logbackConfigFile);
if(!f.exists() || !f.isFile())
break MISSING_BLOCK_LABEL_132;
URL url1;
result = f.toURI().toURL();
url1 = result;
if(updateStatus)
statusOnResourceSearch(logbackConfigFile, classLoader, result);
return url1;
MalformedURLException e1;
e1;
if(updateStatus)
statusOnResourceSearch(logbackConfigFile, classLoader, result);
break MISSING_BLOCK_LABEL_164;
Exception exception;
exception;
if(updateStatus)
statusOnResourceSearch(logbackConfigFile, classLoader, result);
throw exception;
return null;
}
public URL findURLOfDefaultConfigurationFile(boolean updateStatus)
{
ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);
URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);
if(url != null)
return url;
url = getResource("logback.groovy", myClassLoader, updateStatus);
if(url != null)
return url;
url = getResource("logback-test.xml", myClassLoader, updateStatus);
if(url != null)
return url;
else
return getResource("logback.xml", myClassLoader, updateStatus);
}
顯而易見的載入順序
主要就是logback.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
說明:
1、日誌級別及檔案
日誌記錄採用分級記錄,級別與日誌檔名相對應,不同級別的日誌資訊記錄到不同的日誌檔案中
例如:error級別記錄到log_error_xxx.log或log_error.log(該檔案為當前記錄的日誌檔案),而log_error_xxx.log為歸檔日誌,
日誌檔案按日期記錄,同一天內,若日誌檔案大小等於或大於2M,則按0、1、2...順序分別命名
例如log-level-2013-12-21.0.log
其它級別的日誌也是如此。
2、檔案路徑
若開發、測試用,在Eclipse中執行專案,則到Eclipse的安裝路徑查詢logs資料夾,以相對路徑../logs。
若部署到Tomcat下,則在Tomcat下的logs檔案中
3、Appender
FILEERROR對應error級別,檔名以log-error-xxx.log形式命名
FILEWARN對應warn級別,檔名以log-warn-xxx.log形式命名
FILEINFO對應info級別,檔名以log-info-xxx.log形式命名
FILEDEBUG對應debug級別,檔名以log-debug-xxx.log形式命名
stdout將日誌資訊輸出到控制上,為方便開發測試使用
-->
<contextName>SpringBootDemo</contextName>
<property name="LOG_PATH" value="D:\\JavaWebLogs" />
<!--設定系統日誌目錄-->
<property name="APPDIR" value="SpringBootDemo" />
<!-- 日誌記錄器,日期滾動記錄 -->
<appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日誌檔案的路徑及檔名 -->
<file>${LOG_PATH}/${APPDIR}/log_error.log</file>
<!-- 日誌記錄器的滾動策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 歸檔的日誌檔案的路徑,例如今天是2013-12-21日誌,當前寫的日誌檔案路徑為file節點指定,可以將此檔案與file指定檔案路徑設定為不同路徑,從而將當前日誌檔案或歸檔日誌檔案置不同的目錄。
而2013-12-21的日誌檔案在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日誌記錄之外,還配置了日誌檔案不能超過2M,若超過2M,日誌檔案會以索引0開始,
命名日誌檔案,例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式記錄日誌 -->
<append>true</append>
<!-- 日誌檔案的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日誌檔案只記錄info級別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日誌記錄器,日期滾動記錄 -->
<appender name="FILEWARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日誌檔案的路徑及檔名 -->
<file>${LOG_PATH}/${APPDIR}/log_warn.log</file>
<!-- 日誌記錄器的滾動策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 歸檔的日誌檔案的路徑,例如今天是2013-12-21日誌,當前寫的日誌檔案路徑為file節點指定,可以將此檔案與file指定檔案路徑設定為不同路徑,從而將當前日誌檔案或歸檔日誌檔案置不同的目錄。
而2013-12-21的日誌檔案在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${APPDIR}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日誌記錄之外,還配置了日誌檔案不能超過2M,若超過2M,日誌檔案會以索引0開始,
命名日誌檔案,例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式記錄日誌 -->
<append>true</append>
<!-- 日誌檔案的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日誌檔案只記錄info級別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日誌記錄器,日期滾動記錄 -->
<appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日誌檔案的路徑及檔名 -->
<file>${LOG_PATH}/${APPDIR}/log_info.log</file>
<!-- 日誌記錄器的滾動策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 歸檔的日誌檔案的路徑,例如今天是2013-12-21日誌,當前寫的日誌檔案路徑為file節點指定,可以將此檔案與file指定檔案路徑設定為不同路徑,從而將當前日誌檔案或歸檔日誌檔案置不同的目錄。
而2013-12-21的日誌檔案在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${APPDIR}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日誌記錄之外,還配置了日誌檔案不能超過2M,若超過2M,日誌檔案會以索引0開始,
命名日誌檔案,例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>2MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式記錄日誌 -->
<append>true</append>
<!-- 日誌檔案的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日誌檔案只記錄info級別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--encoder 預設配置為PatternLayoutEncoder-->
<encoder>
<pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!--此日誌appender是為開發使用,只配置最底級別,控制檯輸出的日誌級別是大於或等於此級別的日誌資訊-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
</appender>
<logger name="org.springframework" level="WARN" />
<logger name="org.hibernate" level="WARN" />
<!-- 生產環境下,將此級別配置為適合的級別,以免日誌檔案太多或影響程式效能 -->
<root level="INFO">
<appender-ref ref="FILEERROR" />
<appender-ref ref="FILEWARN" />
<appender-ref ref="FILEINFO" />
<!-- 生產環境將請stdout,testfile去掉 -->
<appender-ref ref="STDOUT" />
</root>
</configuration>
說明:
方便----只需要引入jar包,並且配置好日誌檔案,就可以實現日誌列印
遇到的問題:
1、類找不到-------------------沒有用maven工程,在lib下面匯入jar包,日誌的jar包需要放在lib的根目錄下
2、日誌還是不列印----------在xml中日誌列印被註釋了,或者配置中使用了不巧當的檔名,也可以自己定義配置檔案路徑,但是沒那個必要
如有幸遇到大神路過,發現什麼問題,還請不辭麻煩的指出來,小弟萬分感謝