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};
};