nonolog起步筆記-6-StaticLogInfo
- StaticLogInfo
- 文件名和行號
- 文件名和行號的傳入
- log參數
- RuntimeLogger::registerInvocationSite
- logid為什么只能被賦一次值
- reserveAlloc
- 加入消息頭
- finishAlloc
- 返回
StaticLogInfo
寫C語言編譯前端時,給我印象深刻的一部分是,我們需要記錄,當前的位置,以便于在出錯時,報告出錯的位置。
NanoLogInternal::log函數中,注冊的部分,一部分功能,也是這樣的。
這個方面,還是我比較看重的,前面我提到,現在存在的一個bug與之相關,如果在解壓某條出錯時,打印文件名和行號,這問題,也就不是一個問題了。
文件名和行號
文件名和行號的傳入
如下:
#define NANO_LOG(severity, format, ...) do { \...\NanoLogInternal::log(logId, __FILE__, __LINE__, NanoLog::severity, format, \numNibbles, paramTypes, ##__VA_ARGS__); \
} while(0)
log參數
template<long unsigned int N, int M, typename... Ts>
inline void
log(int &logId,const char *filename,const int linenum,
...
## 調試時的效果
選擇一個用戶面請求
代碼是這樣:
// All the standard printf specifiers (except %n) can be usedchar randomString[] = "Hello World";NANO_LOG(NOTICE, "A string, pointer, number, and float: '%s', %p, %d, %f",randomString,&randomString,512,3.14159);
如上圖,能夠看到文件名與行號,與調用方對應。
這時logI=-1,還沒有被賦值。
RuntimeLogger::registerInvocationSite
##logid賦值和入隊
logId = static_cast<int32_t>(invocationSites.size());invocationSites.push_back(info);
// Maps unique identifiers to log invocation sites encountered thus far// by the non-preprocessor version of NanoLogstd::vector<StaticLogInfo> invocationSites;
logid為什么只能被賦一次值
if (logId == UNASSIGNED_LOGID) {const ParamType *array = paramTypes.data();StaticLogInfo info(&compress<Ts...>,filename,linenum,severity,format,sizeof...(Ts),numNibbles,array);RuntimeLogger::registerInvocationSite(info, logId);}
如上,這代表著,在同一處代碼中的logID不會被重新賦值。
reserveAlloc
這里暫略,如下圖,因為分配的大小很小,所以,直接返回了。
沒有鎖。
這是因為每塊內存,都是線程專有的。不需要鎖。
加入消息頭
如下圖,消息頭(似乎尾),描述了logid,根據這個id,也就能對應上這段binary內存的meta定義了(前面registerInvocationSite,注冊的)。
finishAlloc
刷新內存,收尾。確保cache內容刷入內存。
NanoLogInternal::RuntimeLogger::finishAlloc(allocSize);
返回
# 這兩個沒有命中bread point,是因為級別過低
這里不要吃驚,只是簡單地因為:
NanoLog::setLogLevel(NOTICE);
而這里是DEBUG.
namespace LogLevels {/*** The levels of verbosity for messages logged with #NANO_LOG.*/enum LogLevel {// Keep this in sync with logLevelNames defined inside Log.cc.SILENT_LOG_LEVEL = 0,/*** Bad stuff that shouldn't happen. The system broke its contract to* users in some way or some major assumption was violated.*/ERROR,/*** Messages at the WARNING level indicate that, although something went* wrong or something unexpected happened, it was transient and* recoverable.*/WARNING,/*** Somewhere in between WARNING and DEBUG...*/NOTICE,/*** Messages at the DEBUG level don't necessarily indicate that anything* went wrong, but they could be useful in diagnosing problems.*/DEBUG,NUM_LOG_LEVELS // must be the last element in the enum};
};