1. 程式人生 > >log 的 debug()、 error()、 info()方法的區別

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() 做記錄一般標誌著方法的開始和結束。

相關推薦

logdebug() error() info方法區別

軟體中總免不了要使用諸如 Log4net, Log4j, Tracer 等東東來寫日誌,不管用什麼,這些東東大多是大同小異的,一般都提供了這樣5個日誌級別:     × Debug     × Info     × Warn     × Error     × Fatal

logdebug() error() info方法

error 登錄 如果 tps com 用戶 沒有 pst baidu 簡單的說,就是配合log的等級過濾輸出比如,你在開發的時候,要驗證一個方法有沒有被調用到,為了方便調試,通常會在這個方法開始的時候加一些system.out。但是項目真正發布的時候這些代碼通常是要移除掉

log4j的8個日誌級別OFFFATALERRORWARNINFODEBUGTRACE ALL

log4j定義了8個級別的log(除去OFF和ALL,可以說分為6個級別),優先順序從高到低依次為:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。 ALL 最低等級的,用於開啟所有日誌記錄。 TRACE designates f

og4j的日誌級別OFFFATALERRORWARNINFODEBUGTRACE ALL

log4j定義了8個級別的log(除去OFF和ALL,可以說分為6個級別),優先順序從高到低依次為:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。 ALL 最低等級的,用於開啟所有日誌記錄。 TRACE designates finer-grain

程式人生, 檢視自己的Log記錄,是ErrorDebug還是Info

          程式人生, IT人也要常檢視自己的Log記錄,是Error、Debug還是Info .                  十一快到了,工作上的圈友們更樂於分享一些五一十一遊玩的經驗,想更好的去分配這難得的長假。我的這個十一,沒得玩嘍,有事情做,自己喜

日誌級別的選擇:DebugInfoWarnErrorFatal

日誌資訊分類 1.等級由低到高:Debug < Info < Warn < Error < Fatal; 2.區別: Debug 級別最低。一般的來說,在系統實際執行過程中,一般都是不輸出的。因此這個級別的資訊,可以隨意的使用,任何覺得有利於在除錯時更詳細的瞭

關於執行緒的runstartjoin方法

一、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複習5pip的使用安裝虛擬環境安裝BeautifulSoup庫

1.建立虛擬環境(win10) 配置清華大學pip映象源 C:\Users\huxia\pip\pip.ini [global] timeout = 60 index-url = https://

I/O複用——selectpoll與epoll區別

       select()、poll()、epoll()三組I/O複用系統呼叫都可以同時監聽多個檔案描述符。它們將等待由timeout引數指定的超時時間,直到一個或者多個檔案描述符上有事件發生時返回,返回值就是就緒檔案描述符的數量,返回0表示沒有事件發生。 1、sele

Map集合中value方法與keySetentrySet()區別

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#之LinqwhereFindAll區別

對於實現了IEnumerable<T>介面的類、型別、集合可以使用Linq、Linq的擴充套件方法where()、FindAll()來查詢符合謂詞約束的資料。這三者之間執行的方式是不一樣的,同樣的資料同樣的查詢條件返回的結果也不相同。先上程式碼再分析。 publ

人臉檢測人臉對齊MTCNN方法

眾所眾知,嚴格定義上的人臉識別分為四個步驟: ①人臉檢測:從圖片中準確定位到人臉 ②人臉矯正(對齊): 檢測到的人臉,可能角度不是很正,需要使其對齊 ③對矯正後的人臉進行特徵提取 ④對兩張人臉影象的特徵向量進行對比,計算相似度 這裡,我們主要是推薦步驟1和步驟2用到的一個方

面試總結3:執行緒Thread的同步以及sleep() wait區別

前言 這幾天忙一點私事,今天回來趕緊把面試總結接著寫下去,這次來看看Thread的join()方法和sleep()和wait()方法的區別。 正文 執行緒同步 上一篇提到了執行緒同步的問題,主要是通過鎖的形式來進行執行緒間的喚醒和等待,執行緒之間的

為什麼一個好的類需要覆寫toStringhashCodeequals方法

第一:覆寫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()livebindone區別

live()用法與bind()類似,bind()方法繫結的事件對於新新增的元素不起作用,live()方法可以 on()可以看做新版本的bind(),用法與bind()類似 one()在每一個匹配元素的特定事件,繫結一個一次性的事件處理函式,事件只會執行一次,其他與bind(

Hibernate 使用QuerySQLQuery 的setCacheable設定快取問題

使用Hibernate SQLQuery或Query做查詢時,預設從快取中獲取資料,SQLQuery有個setCacheable( )方法,sqlQuery.setCacheable(false)為不從快取中讀取資料, sqlQuery.setCacheable(true

html中url路徑請求的六種方式:無斜槓單斜槓/點+單斜槓./點點+單斜槓../多個點點+單斜槓../../全路徑

  圖一:專案結構  圖二:rootPath.html內容 說明:圖一為專案結構,圖二為rootPath.html內容。 我在做專案過程中路徑寫錯,跳轉不到目標頁面,花了好長時間才發現原因,鑑於自己的慘痛經歷,就把這幾種url路徑總結了一下,配上了我的具體專案結構圖和