這是來某外包公司的第五個星期,時間過得真快啊,又到了週一,也意味着來這裏打了4周的醬油啦。css
公司沒人對我負責,基本上處於放羊的狀態,指派的任務無人講解,看起來遙遙無期,口袋空空(沒錢),更慘的是精神世界也空空(主要一天敲不到50行代碼,看着其餘同窗在其餘公司BAT啦,網易啦,日新月異,感受好虛),這麼久啥都沒學到?html
也不是吧,回憶一下上週老大給講的log4j,因而決定趁着沒忘乾淨趕快整理一下,主要藉助了其餘博客的精華,回憶着老大的諄諄教誨,整理一下。java
說正事以前先吐槽一下艹蛋的win10系統,強制自動更新,在8.10分拋給我一個10分鐘後自動重啓的通知,以後就趁我早晨腦殼蒙圈在10分鐘後強制重啓進行了更新,linux
自動重啓了N次,更新了一個半鐘頭,比重裝還慢...並且更新以後也沒發現哪裏有不同的地方。過後琢磨若是不想更新能夠這麼作:把系統時間往前調整(逃軟件試用期也用過這一招),或者在控制面板中設置禁止自動更新。web
在配置log4j的過程當中回顧了一下之前的知識,提出了3個問題。spring
一.web基礎回顧數據庫
1.1什麼是web工程apache
一個web工程,就是符合一套web標準(工程組織形式我的理解就是源代碼,中間代碼,各類文件怎麼放),由於只有符合一個統一的標準,服務器才能更好的識別,運行。編程
左圖:下面沒有介紹的基本沒用到,因此也懶得理解了...服務器
是eclipse中一個名爲web_log4j的web工程,src顧名思義就是源碼,下面存放着若干.java文件,咱們面向對象編程就是在這裏寫類,寫方法
jreSystemLibrary是java運行依賴的類庫,自動生成
webApplibrary下面是工程引用的外部jar包,一個引用過程是這樣的:將jar包文件拷貝到工程中,右擊buildpath,buildpath至關於將jar包裏面的類引入,
好比以前【beanUtile.封裝】這樣的代碼是沒有提示的,buildpath以後,該代碼出現了提示,按照提示import以後就可使用beanUtil這個工具類,
先後對比說明buildpath完成了jar包中的類導入到工程中的做用。引用外部類還能夠採用直接引用的方式[add external jars],不利於代碼移植性,就不介紹啦。
(舉個例子,你電腦上log4j.jar在c盤,換了一臺電腦跑,程序還去c盤找這個文件,找不到就會報錯)
這裏要說清楚所謂引用類,就不得不說一下什麼是jar包,jar包其實就是打包壓縮好的一堆.class文件,引用就是把外部的.class文件組合到工程裏面的過程。若是想要查看jar包的源碼,
還須要導入源碼。有趣的是本身也能夠將一堆.class文件在cmd命令下打成jar包,自創jar包。
在一個web工程中,依靠的是工程名:web_log4j提供對外訪問,對內web_log4j抽象成根目錄/(內部總使用相對路徑訪問),對於路徑問題有篇博客解釋的超級精闢:java獲取路徑問題,
(一個經常使用作法是從當前類拿到完整路徑,或者是經過容器獲得)
得到路徑能夠經過IO流作輸入輸出,還有讀取配置文件也須要路徑,因此路徑很重要。
這裏插播一個有趣的問題,下面的代碼是錯誤的,錯在哪裏?
public static String s1=this.getClass().getClassLoader().getResource("/").getPath();
或者說:java的static方法裏面爲何不能用this關鍵字?
這和jvm有關,jvm首先加載的是靜態部分,而this的含義是指當前對象,靜態部分加載進入的時候對象尚未建立。
這裏再插播一個對比jdk,jre,jvm,
咱們利用JDK(調用JAVA API)開發了屬於咱們本身的JAVA程序後,經過JDK中的編譯程序(javac)將咱們的文本java文件編譯成JAVA字節碼,
在JRE上運行這些JAVA字節碼,JVM解析這些字節碼,映射到CPU指令集或OS的系統調用
回到web工程的主題:
右圖:build文件夾下存放着編譯好的.class文件,src放源碼,webcontent下面的web-info存放着jar包和配置文件
工程運行所依賴的配置文件(.properties文件:好比用於配置數據庫鏈接的用戶名,密碼;.xml文件,配置類,常數等關係的文件);.class文件(外部jar包,src編譯造成的.class文件)
至此所有介紹完畢,其中大部分位於web-inf目錄下,因而可知這是一個很重要的目錄。而web.xml關係到一個web工程全局的初始化設置,接下來就說一說我所見過的配置,看明白了web.xml文件,這個工程用到哪些技術,是怎樣一個結構基本上有了一個全局性的瞭解。
1.2一個web.xml文件的解讀
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>LogLearning</display-name> <servlet> <servlet-name>Log4JTestServlet</servlet-name> <servlet-class>com.mucfc.Log4JTestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Log4JTestServlet</servlet-name> <url-pattern>/test</url-pattern> </servlet-mapping> <!-- Spring 容器加載 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- 設置根目錄 --> <context-param> <param-name>webAppRootKey</param-name> <param-value>webapp.root</param-value> </context-param> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/classes/log4j.properties</param-value> </context-param> <!-- 3000表示 開一條watchdog線程每60秒掃描一下配置文件的變化;這樣便於日誌存放位置的改變 --> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>3000</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> </web-app>
最前面是約束,這個web.xml中主要配置了servlet和listener
servlet包含兩個標籤<servlet>和<servlet-mapping>
其中servlet-name能夠隨便起,可是倆標籤裏的name必定要一致,之因此這樣作,是由於前一個servlet綁定了servlet類(拿到request,response處理而且返回的代碼,說簡單點,控制代碼就寫在<servlet-class>指定的類裏面,並且指定了初始化參數),後一個url-mapping(假設配成/test)則是提供了訪問路徑:如localhost:8080/web_log4j/test,就是在訪問這個servlet呢,訪問路徑和後臺代碼要綁定,靠的是共有的名字,所謂的servlet之因此能實現交互的緣由就是這樣。既有訪問路徑,又有後臺處理代碼,request和response是一堆郵差,扮演了信息載體的角色。
listener標籤則配置了監聽器,其中org類位於jar包中,這裏所謂的監聽器究竟是什麼東西呢?
1.隨着web應用的啓動開始啓動,也就是說一開始就發揮了做用
2.不負責響應用戶的請求,也就是說只有一行<listener>類</listener>,無需配置url
第一個監聽器:ContextLoaderListener和
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
搭配使用,使得context載入配置文件applicationContext.xml(裏面放置着配置好的bean),所謂classpath指代的是web-info/classes目錄,直接把spring的配置關係載入了
webapp.root能夠用於獲取系統根目錄,具體代碼System.getRoot("...")
第二個監聽器:log4jConfigListener
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
搭配使用載入了log4j文件的位置。
對監聽器做用理解以下:
只有一行,配置指向jar包裏面的某個類,和某些特定參數配合使用,爲其指定初始化模式(好比顯示了配置文件位置)
這裏也能夠作一個逆向思考:計算機不是人,怎麼讀取配置文件呢?web.xml首先是web默認的全局配置文件,裏面配置了監聽器從應用啓動開始啓動
經過一些參數來找到配置文件。
二 log4j的使用
2.1log4j介紹
就是跟日誌掛鉤的東西,大部分web應用部署在linux上,要想時時刻刻記錄運行狀態,就得依靠一種叫日誌的東西,運行狀態,出錯,異常通通記錄在案,出問題了回頭也能查到,日誌的實體就是.log後綴的文件。
Log4j由三個重要的組件構成:日誌信息的優先級,日誌信息的輸出目的地,日誌信息的輸出格式。日誌信息的優先級從高到低有ERROR、WARN、 INFO、DEBUG,分別用來指定這條日誌信息的重要程度;日誌信息的輸出目的地指定了日誌將打印到控制檯仍是文件中;而輸出格式則控制了日誌信息的顯 示內容。
2.2log4j.properties文件解讀
### 設置###
log4j.rootLogger = debug,stdout,D,E
### 輸出信息到控制擡 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 輸出DEBUG 級別以上的日誌到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 輸出ERROR 級別以上的日誌到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
log4j.rootLogger = debug,stdout,D,E
定義」頂「爲debug,意爲debug如下的信息均可以輸出,appenderName1爲stdout(用於控制檯輸出),D(debug),E(error)
PatternLayout表示按照指定格式輸出,纔有後面的規則
[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n:
除了特殊含義字符,其餘字符按照原樣輸出
p:[debug]級別,d:日期樣式,l:輸出日誌事件發生的位置,n:回車換行,m:指定的消息(這纔是重點)
除了控制檯,還指定了error.log和debug.log做爲輸出文件
2.3log4j的代碼應用
static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName ()[通常是當前類,由於記載了當前類的debug信息] )
PropertyConfigurator.configure ( String configFilename) :讀取使用Java的特性文件編寫的配置文件。
[這一步也能夠在spring中配置指定的路徑]
Logger.debug ( Object message ) ; :跟上面對應的m同樣,輸出debug信息
三遺留問題
3.1上面僅僅是作了一個實驗,至關於helloword,在實際應用中,log4j是如何記載產生的異常的?
或者說,上面的message是本身寫的,若是一段代碼跑崩了,日誌是怎樣記錄信息的?
3.2天天產生數以萬計的日誌記錄,如何查看?裏面有沒有什麼技巧?