log 的 debug()、 error()、 info()方法的區別
軟體中總免不了要使用諸如 Log4net, Log4j, Tracer 等東東來寫日誌,不管用什麼,這些東東大多是大同小異的,一般都提供了這樣5個日誌級別:
× Debug
× Info
× Warn
× Error
× Fatal
一個等級比一個高,但是在具體開發中,關於應該如何選擇適應的等級,卻沒有找到好的文章進行說明。記錄一下自己的一些看法,以便日後使用吧。
=== Debug ===
這個級別最低的東東,一般的來說,在系統實際執行過程中,一般都是不輸出的。
因此這個級別的資訊,可以隨意的使用,任何覺得有利於在除錯時更詳細的瞭解系統執行狀態的東東,比如變數的值等等,都輸出來看看也無妨。
當然,在每一個 Debug 呼叫之前,一定要加上 If 判斷。
=== Info ===
這個應該用來反饋系統的當前狀態給終端使用者的,所以,在這裡輸出的資訊,應該對終端使用者具有實際意義,也就是終端使用者要能夠看得明白是什麼意思才行。
從某種角度上說,Info 輸出的資訊可以看作是軟體產品的一部分(就像那些互動介面上的文字一樣),所以需要謹慎對待,不可隨便。
=== Warn、Error、Fatal ===
警告、錯誤、嚴重錯誤,這三者應該都在系統執行時檢測到了一個不正常的狀態,他們之間的區別,要區分還真不是那麼簡單的事情。我大致是這樣區分的:
所謂警告,應該是這個時候進行一些修復性的工作,應該還可以把系統恢復到正常狀態中來,系統應該可以繼續執行下去。
所謂錯誤,就是說可以進行一些修復性的工作,但無法確定系統會正常的工作下去,系統在以後的某個階段,很可能會因為當前的這個問題,導致一個無法修復的錯誤(例如宕機),但也可能一直工作到停止也不出現嚴重問題。
所謂Fatal,那就是相當嚴重的了,可以肯定這種錯誤已經無法修復,並且如果系統繼續執行下去的話,可以肯定必然會越來越亂。這時候採取的最好的措施不是試圖將系統狀態恢復到正常,而是儘可能地保留系統有效資料並停止執行。
也就是說,選擇 Warn、Error、Fatal 中的具體哪一個,是根據當前的這個問題對以後可能產生的影響而定的,如果對以後基本沒什麼影響,則警告之,如果肯定是以後要出嚴重問題的了,則Fatal之,拿不準會怎麼樣,則 Error 之。
示例程式碼:
/**
* <p>Title: 使用者登入處理</p>
* <p>Description: </p>
* @param loginId
* @return
redirect page
*/
@RequestMapping("/user/login.vw")
public String login(HttpServletRequest request, HttpServletResponse response,
ModelMap model, @ModelAttribute("login") @Validated CusLogin login,
BindingResult bindingResult) throws Exception {
log.debug("使用者登入開始......");
//1.檢查登入資訊物件:null判斷
if (null == login) {
log.error("使用者登入失敗-登入資訊不存在");
bindingResult.addError(
new FieldError(
ErrorMsg.USERNOTEXIST[0],
ErrorMsg.USERNOTEXIST[0],
ErrorMsg.USERNOTEXIST[1]));
request.getSession().setAttribute(LOGINSTATE, "1");
login = new CusLogin();
//1:代表登入時使用者輸入的資訊有誤
login.setLoginState("1");
login.setPasswd("");
model.addAttribute("login", login);
return INDEX;
}
//2欄位格式檢查
if (bindingResult.hasErrors()) {
List<ObjectError> ers = bindingResult.getAllErrors();
for (ObjectError e : ers) {
log.error(e.getDefaultMessage());
}
//has error
log.error("使用者登入失敗-請求引數錯誤;username=" + login.getLoginNm());
//redirect index.jsp
request.getSession().setAttribute(LOGINSTATE, "1");
login.setLoginState("1");
login.setPasswd("");
model.addAttribute("login", login);
return INDEX;
}
//3. 第一登入失敗,再次登入需輸入驗證碼,判斷驗證碼是否正確
if("1".equals(request.getSession().getAttribute(LOGINSTATE))){
if (login.getVerCode() == null || !login.getVerCode().equalsIgnoreCase(VerCodeMaker.verImgGet(session))) {
VerCodeMaker.verImgDel(request);
log.error("使用者登入失敗-驗證碼檢查失敗;username=" + login.getLoginNm());
bindingResult.addError(
new FieldError(
ErrorMsg.VERCODEEROOR[0],
ErrorMsg.VERCODEEROOR[0],
ErrorMsg.VERCODEEROOR[1]));
request.getSession().setAttribute(LOGINSTATE, "1");
login.setLoginState("1");
login.setPasswd("");
model.addAttribute("login", login);
return INDEX;
}
}
try {
//no error
//4.獲取登入使用者資訊:條件為使用者名稱和使用者型別
LoginUsersDto dto = loginService.login(login);
if (null == dto || StringUtility.isEmpty(dto.getLoginName())) {
bindingResult.addError(
new FieldError(
ErrorMsg.USERNOTEXIST[0],
ErrorMsg.USERNOTEXIST[0],
ErrorMsg.USERNOTEXIST[1]));
log.error("使用者登入-查詢使用者資訊失敗,不存在或DB資料錯誤;username=" + login.getLoginNm());
request.getSession().setAttribute(LOGINSTATE, "1");
login.setLoginState("1");
login.setPasswd("");
model.addAttribute("login", login);
return INDEX;
}
//4. 密碼檢查
boolean isPwdExist = loginService.passwordChk( dto.getLoginName(), login.getPasswd(), dto.getPassword());
if (!isPwdExist) {
bindingResult.addError(
new FieldError(
ErrorMsg.PWDERROR[0],
ErrorMsg.PWDERROR[0],
ErrorMsg.PWDERROR[1]));
request.getSession().setAttribute(LOGINSTATE, "1");
login.setLoginState("1");
login.setPasswd("");
model.addAttribute("login", login);
log.error("使用者登入-密碼檢查失敗;username=" + login.getLoginNm());
return INDEX;
}
//3.獲取使用者認證及支付資訊
PayAuthInfoDto payInfoDto = payService.getPayAuthInfoByCusCode(dto.getCusCode());
//4. 建立SESSION資料
User user = new User();
if (null != payInfoDto) {
user = UserSession.userSet(dto , payInfoDto);
} else {
user = UserSession.userSet(dto);
}
UserSession.setUser(request, user);
log.debug("使用者登入結束");
} catch (BizException e) {
log.info("使用者登入失敗;username=" + login.getLoginNm(),e);
bindingResult.addError(
new FieldError(
ErrorMsg.UNKNOWEXPCTION[0],
ErrorMsg.UNKNOWEXPCTION[0],
ErrorMsg.UNKNOWEXPCTION[1]));
login.setPasswd("");
model.addAttribute("login", login);
return INDEX;
} catch (Exception e) {
log.info("使用者登入失敗,username=" + login.getLoginNm(),e);
bindingResult.addError(
new FieldError(
ErrorMsg.UNKNOWEXPCTION[0],
ErrorMsg.UNKNOWEXPCTION[0],
ErrorMsg.UNKNOWEXPCTION[1]));
login.setPasswd("");
model.addAttribute("login", login);
return INDEX;
} finally{
request.getSession().removeAttribute(LOGINSTATE);
}
return REUSERINDEX;
}
心得:
log.error() 一般是需要if()的;
log.info()一般是在try catch 裡面
log.debug() 做記錄一般標誌著方法的開始和結束。
相關推薦
log 的 debug()、 error()、 info()方法的區別
軟體中總免不了要使用諸如 Log4net, Log4j, Tracer 等東東來寫日誌,不管用什麼,這些東東大多是大同小異的,一般都提供了這樣5個日誌級別: × Debug × Info × Warn × Error × Fatal
log 的 debug()、 error()、 info()方法
error 登錄 如果 tps com 用戶 沒有 pst baidu 簡單的說,就是配合log的等級過濾輸出比如,你在開發的時候,要驗證一個方法有沒有被調用到,為了方便調試,通常會在這個方法開始的時候加一些system.out。但是項目真正發布的時候這些代碼通常是要移除掉
log4j的8個日誌級別(OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL)
log4j定義了8個級別的log(除去OFF和ALL,可以說分為6個級別),優先順序從高到低依次為:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。 ALL 最低等級的,用於開啟所有日誌記錄。 TRACE designates f
og4j的日誌級別(OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL)
log4j定義了8個級別的log(除去OFF和ALL,可以說分為6個級別),優先順序從高到低依次為:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。 ALL 最低等級的,用於開啟所有日誌記錄。 TRACE designates finer-grain
程式人生, 檢視自己的Log記錄,是Error、Debug還是Info
程式人生, IT人也要常檢視自己的Log記錄,是Error、Debug還是Info . 十一快到了,工作上的圈友們更樂於分享一些五一十一遊玩的經驗,想更好的去分配這難得的長假。我的這個十一,沒得玩嘍,有事情做,自己喜
日誌級別的選擇:Debug、Info、Warn、Error、Fatal
日誌資訊分類 1.等級由低到高:Debug < Info < Warn < Error < Fatal; 2.區別: Debug 級別最低。一般的來說,在系統實際執行過程中,一般都是不輸出的。因此這個級別的資訊,可以隨意的使用,任何覺得有利於在除錯時更詳細的瞭
關於執行緒的run()、start()、join()方法
一、run()和start() run:run()方法只是類的一個普通方法而已,如果直接呼叫Run方法,程式中依然只有主執行緒這一個執行緒,其程式執行路徑還是隻有一條,還是要順序執行,還是要等待run方法體執行完畢後才可繼續執行下面的程式碼,這樣就沒有達到寫執行緒的目的。 start:用st
String.formCharCode()與、$0.getBoundingClientRect()、與編碼escape()的使用
string.formCharCode() 根據指定的Unicode編碼中的序號值來返回一個字串。 語法:String.formCharCode(num1…numN); 在unicode編碼表中 97 和 65 代表A 根據n的索引值返回A B C D E F 等 $0.getBoun
機器學習 第一章 Python複習(5)pip的使用、安裝虛擬環境()、安裝BeautifulSoup庫
1.建立虛擬環境(win10) 配置清華大學pip映象源 C:\Users\huxia\pip\pip.ini [global] timeout = 60 index-url = https://
I/O複用——select()、poll()與epoll()的區別
select()、poll()、epoll()三組I/O複用系統呼叫都可以同時監聽多個檔案描述符。它們將等待由timeout引數指定的超時時間,直到一個或者多個檔案描述符上有事件發生時返回,返回值就是就緒檔案描述符的數量,返回0表示沒有事件發生。 1、sele
Map集合中value()方法與keySet()、entrySet()區別
Map<String,String> map = new HashMap<String,String>();map.put(“01”, “zhangsan”);map.put(“02”, “lisi”);map.put(“03”, “wangwu”);Collection<St
建立一個數組, 實現函式init()初始化陣列, 實現empty()清空陣列、,實現reverse()函式完成陣列元素的逆置。自己設計函式的引數,返回值。
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> void init(int arr[], int len) { for (int i = 0; i < len; ++i)
C#之Linq、where()、FindAll()的區別
對於實現了IEnumerable<T>介面的類、型別、集合可以使用Linq、Linq的擴充套件方法where()、FindAll()來查詢符合謂詞約束的資料。這三者之間執行的方式是不一樣的,同樣的資料同樣的查詢條件返回的結果也不相同。先上程式碼再分析。 publ
人臉檢測、人臉對齊(MTCNN方法)
眾所眾知,嚴格定義上的人臉識別分為四個步驟: ①人臉檢測:從圖片中準確定位到人臉 ②人臉矯正(對齊): 檢測到的人臉,可能角度不是很正,需要使其對齊 ③對矯正後的人臉進行特徵提取 ④對兩張人臉影象的特徵向量進行對比,計算相似度 這裡,我們主要是推薦步驟1和步驟2用到的一個方
面試總結(3):執行緒(Thread)的同步以及sleep() 、wait()的區別
前言 這幾天忙一點私事,今天回來趕緊把面試總結接著寫下去,這次來看看Thread的join()方法和sleep()和wait()方法的區別。 正文 執行緒同步 上一篇提到了執行緒同步的問題,主要是通過鎖的形式來進行執行緒間的喚醒和等待,執行緒之間的
為什麼一個好的類需要覆寫toString()、hashCode()、equals()方法
第一:覆寫Object類中的toString方法public class Client { public static void main(String[] args) { System.out.println(new Person("張三"
關於新建android專案,MainActivity裡面的onCreate()方法、R檔案報錯的解決方法
做為一位剛剛上手Android開發的小白來說,要適應一門開發語言和一款開發工具十分費勁。本人也在摸索的路上走了很多的彎路,也有了一點點的經驗和問題的解決方案,和大家分享一下。 這是關於第一次用Android studio新建工程所遇到的問題,新建工程中MainActivit
on()、live()、bind()、one()的區別
live()用法與bind()類似,bind()方法繫結的事件對於新新增的元素不起作用,live()方法可以 on()可以看做新版本的bind(),用法與bind()類似 one()在每一個匹配元素的特定事件,繫結一個一次性的事件處理函式,事件只會執行一次,其他與bind(
Hibernate 使用Query、SQLQuery 的setCacheable()設定快取問題
使用Hibernate SQLQuery或Query做查詢時,預設從快取中獲取資料,SQLQuery有個setCacheable( )方法,sqlQuery.setCacheable(false)為不從快取中讀取資料, sqlQuery.setCacheable(true
html中url路徑請求的六種方式:無斜槓、單斜槓(/)、點+單斜槓(./)、點點+單斜槓(../)、多個點點+單斜槓(../../)、全路徑
圖一:專案結構 圖二:rootPath.html內容 說明:圖一為專案結構,圖二為rootPath.html內容。 我在做專案過程中路徑寫錯,跳轉不到目標頁面,花了好長時間才發現原因,鑑於自己的慘痛經歷,就把這幾種url路徑總結了一下,配上了我的具體專案結構圖和