開心一笑
【牛頓一輩子沒結婚,他創立牛頓三定律,萬有引力定律,張三丰一輩子沒結婚,活到了200多歲,在一百二十多歲創造了太極拳,威震江湖!孫悟空一輩子沒結婚,活了不知道多少歲,大鬧過天宮,闖過龍宮,鬧過地府,最後成了鬥戰勝佛…不用我多說了吧 ,都TMD別惹我,我也是單身狗!】
8.1 Log4J介紹
8.1.1 Log4J概述
Log4j是Apache下的一個開源項目,通過使用Log4j,我們可以將日誌信息打印到控制檯、文件等。我們也可以控制每一條日誌的輸出格式,通過定義每一條日誌信息的級別,我們能夠更加細緻地控制日誌的生成過程。
在應用程序中添加日誌記錄有三個目的:
1) 監視代碼中變量的變化情況,週期性的記錄到文件中供其它應用進行統計分析工作。
2) 跟蹤代碼運行時軌跡,作爲日後審計的依據。
3) 擔當集成開發環境中的調試器的作用,向文件或控制檯打印代碼的調試信息。
Log4j中有三個主要的組件,它們分別是:Loggers(記錄器),Appenders (輸出源)和Layouts(佈局),這三個組件可以簡單的理解爲日誌類別,日誌要輸出的地方和日誌以何種形式輸出。Log4J原理如圖8-1所示。
圖8-1 Log4J日誌框架簡單原理圖
Loggers(記錄器):Loggers組件被分爲七個級別:all、debug、info、warn、error、fatal、off。這七個級別是有優先級的:all<debug< info< warn< error< fatal<off,分別用來指定這條日誌信息的重要程度。 Log4j有一個規則:只輸出級別不低於設定級別的日誌信息。假設Loggers級別設定爲info,則info、warn、error和fatal級別的日誌信息都會輸出,而級別比info低的debug則不會輸出。Log4j允許開發人員定義多個Logger,每個Logger擁有自己的名字,Logger之間通過名字來表明隸屬關係。
Appenders(輸出源):Log4j日誌系統允許把日誌輸出到不同的地方,如控制檯(Console)、文件(Files)等,可以根據天數或者文件大小產生新的文件,可以以流的形式發送到其它地方等等。
Layouts(佈局):Layout的作用是控制Log信息的輸出方式,也就是格式化輸出的信息。
Log4j支持兩種配置文件格式,一種是XML格式的文件,一種是Java特性文件 log4j2.properties (鍵 = 值),properties文件簡單易讀,而XML文件可以配置更多的功能(比如過濾),沒有好壞,能夠融會貫通就是最好的。具體的XML配置如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
8.2 集成Log4j2
8.2.1 引入依賴
在Spring Boot中集成Log4j2,首先需要在pom.xml文件中引入所需的依賴,具體代碼如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
Spring Boot默認使用Logback日誌框架來記錄日誌,並用INFO級別輸出到控制檯,所以我們在引入Log4j2之前,需要先排除該包的依賴,再引入Log4j2的依賴。具體做法就是找到pom.xml文件中的spring-boot-starter-web依賴,使用exclusion標籤排除Logback,具體排除Logback依賴的代碼如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- 排查Spring Boot默認日誌 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
8.2.2 添加Log4J配置
在8.1節當中,我們已經講過,Log4j2支持兩種配置文件格式,一種是XML格式的文件,一種是properties文件的格式。這裏我們使用XML格式配置Log4j2,properties格式可以作爲大家自學任務。使用XML格式配置很簡單,我們只需要在application.properties文件中添加如下的配置信息:
###log4j配置
logging.config=classpath:log4j2.xml
配置完成之後,Spring Boot就會幫我們在classpath路徑下查找log4j2.xml文件,所以最後一步,我們只需要配置好log4j2.xml文件即可。
8.2.3 創建log4j2.xml文件
application.properties配置完成之後,我們在目錄/src/main/resources目錄下新建空的日誌配置文件log4j2.xml。具體代碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<appenders>
</appenders>
<loggers>
<root level="all">
</root>
</loggers>
</Configuration>
8.3 使用Log4J記錄日誌
8.3.1 打印到控制檯
現在我們需要把日誌打印到控制檯,所以需要往log4j2.xml配置文件添加相關的配置,具體代碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<!-- 指定日誌的輸出格式 -->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</Console>
</appenders>
<loggers>
<root level="all">
<!-- 控制檯輸出 -->
<appender-ref ref="Console"/>
</root>
</loggers>
</Configuration>
<Console/ >:指定控制檯輸出。
< PatternLayout />:控制日誌的輸出格式。
Spring Boot集成Log4j日誌完成之後,在6.2.2和7.3.1節中,我們已經開發好AyUserListener監聽器,但是使用System.out.println來打印信息,這是一種非常不合理的方式,現在我們把Logger 類引入到AyUserListener.java監聽器中,同時把System.out.println相關代碼註釋掉,改成用日誌方式記錄信息。這樣,在項目啓動過程中,調用上下文初始化和銷燬方法的時候,就會記錄日誌到開發工具控制檯或者日誌文件中。AyUserListener具體代碼如下:
/**
* 描述:監聽器
* @author Ay
* @date 2017/11/4
*/
@WebListener
public class AyUserListener implements ServletContextListener {
//省略代碼
//需要添加的代碼
Logger logger = LogManager.getLogger(this.getClass());
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//查詢數據庫所有的用戶
List<AyUser> ayUserList = ayUserService.findAll();
//清除緩存中的用戶數據
redisTemplate.delete(ALL_USER);
//存放到redis緩存中
redisTemplate.opsForList().leftPushAll(ALL_USER, ayUserList);
//真實項目中需要註釋掉
List<AyUser> queryUserList = redisTemplate.opsForList().range(ALL_USER, 0, -1);
//System.out.println("緩存中目前的用戶數有:" + queryUserList.size() + " 人");
//System.out.println("ServletContext上下文初始化");
logger.info("ServletContext上下文初始化");
logger.info("緩存中目前的用戶數有:" + queryUserList.size() + " 人");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
//System.out.println("ServletContext上下文銷燬");
logger.info("ServletContext上下文銷燬");
}
}
8.3.2 記錄到文件
在8.3.1節中,日誌只是被打印到控制檯中,當項目真正被上線之後,是沒有控制檯這個概念的,上線環境中,項目的日誌都是被記錄到文件中的。所以我們繼續在log4j2.xml配置文件中添加相關配置,使日誌可以被打印到文件中,具體代碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<!-- 設置日誌輸出的格式 -->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</Console>
<RollingFile name="RollingFileInfo" fileName="D:/info.log"
filePattern="D:/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
<Filters>
<ThresholdFilter level="INFO"/>
</Filters>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
</appenders>
<loggers>
<root level="all">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileInfo"/>
</root>
</loggers>
</Configuration>
< RollingFile>標籤:fileName用於定義日誌的數據路徑,如D:/info.log。filePattern定義日誌的匹配方式。
< Filters>標籤:日誌過濾策略,標籤用於指定日誌信息的最低輸出級別,默認爲DEBUG,
現在我們修改3.2.3節當中AyUserServiceImpl類的刪除方法delete,我們希望刪除用戶這個操作可以被記錄到日誌文件中,AyUserServiceImpl類代碼具體的修改點如下:
/**
* 描述:用戶服務層實現類
* @author 阿毅
* @date 2017/10/14
*/
//@Transactional
@Service
public class AyUserServiceImpl implements AyUserService {
//省略代碼
//需要添加的代碼
Logger logger = LogManager.getLogger(this.getClass());
@Override
public void delete(String id) {
ayUserRepository.delete(id);
//需要添加的代碼
logger.info("userId:" + id + "用戶被刪除");
}
//省略代碼
}
8.3.3 測試
代碼開發完成之後,接下來就是測試工作了。我們重新啓動項目,啓動之前,記得打開Redis服務器,因爲之前的章節,我們已經在Spring Boot中整合了Redis。項目重啓的過程中,我們可以在Intellij IDEA控制檯中看到如圖8-2所示的信息。同時,我們可以到D盤查看日誌文件info.log,在日誌文件中按住Ctrl + F,查詢到和圖8-2所示一樣的信息。
圖8-3 redis斷點調試界面
接着,我們再測試下,刪除用戶的時候,日誌是否可以打印到控制檯或者記錄到日誌文件中。我們在測試類MySpringBootApplicationTests下添加測試用例,具體代碼如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MySpringBootApplicationTests {
//省略代碼
Logger logger = LogManager.getLogger(this.getClass());
@Test
public void testLog4j(){
ayUserService.delete("4");
logger.info("delete success!!!");
}
}
在數據庫ay_test表中存在4條數據,如圖8-3所示。運行單元測試方法testLog4j,如果同樣可以在Intellij IDEA控制檯或者D盤的info.log文件中打印如圖8-4所示信息,證明Spring Boot整合Log4j以及在Spring Boot中運用Log4j成功。
圖8-3 redis斷點調試界面 圖8-4 redis斷點調試界面
啓動項目的時候,記得啓動Redis服務器,否則會報錯。
讀書感悟
來自《女士品茶》
- 有些讀者會說:這絕對是喫飽了撐的!他們會問:“不管這位女士能否分辨兩種飲品,這件事有什麼意義呢?”“這個問題一點兒也不重要,對科學也沒有益處,”他們嘲笑道,“這些聰明人應該把他們的頭腦用在能夠造福人類的事情上。” 不幸的是,不管普通大衆如何看待科學及其影響,根據我的經驗,大多數科學家之所以投入到研究當中,是因爲他們對結果感興趣,並能從工作中獲得知識性的樂趣。優秀的科學家很少會考慮他們的工作是否具有重要意義。回到劍橋那個陽光明媚的夏日午後。女士有可能猜中飲品的混合方式,也有可能猜錯。這件事的樂趣在於找出一種方法判斷她的說法是否正確。在尖髯男子的指導下,他們開始討論如何驗證這種判斷。
經典故事
祖父用紙給我做過一條長龍。長龍腹腔的空隙僅僅只能容納幾隻蝗蟲,投放進去,它們都在裏面死了,無一倖免!祖父說:“蝗蟲性子太躁,除了掙扎,它們沒想過用嘴巴去咬破長龍,也不知道一直向前可以從另一端爬出來。因而,儘管它有鐵鉗般的嘴殼和鋸齒一般的大腿,也無濟於事。”當祖父把幾隻同樣大小的青蟲從龍頭放進去,然後關上龍頭,奇蹟出現了:僅僅幾分鐘,小青蟲們就一一地從龍尾爬了出來。
【命運一直藏匿在我們的思想裏。許多人走不出人生各個不同階段或大或小的陰影,並非因爲他們天生的個人條件比別人要差多遠,而是因爲他們沒有思想要將陰影紙龍咬破,也沒有耐心慢慢地找準一個方向,一步步地向前,直到眼前出現新的洞天。】
大神文章
無
其他
如果有帶給你一絲絲小快樂,就讓快樂繼續傳遞下去,歡迎鼓勵,點贊、頂、歡迎留下寶貴的意見、多謝支持!