平常写一些简单验证程序时,需要频繁输出日志信息便于调试。为了后续验证程序中输出日志信息方便,将平时使用的日志信息抽象成了INFO和FUNC。
- INFO输出单行日志信息,可以输出当前的时间(格式:%Y-%m-%d %H:%M:%S)、进程号和线程号。
- FUNC利用RAII可以在生命周期(比如函数)的开始和结束分别打印日志信息,并统计执行耗时(单位微妙)
#include <iostream>
#include <unistd.h>
#include <chrono>
#include <iomanip>
#include <ctime>
#include <sstream>
#include <string>
#define INFO(msg) \
do { \
auto now = std::chrono::system_clock::now(); \
auto t = std::chrono::system_clock::to_time_t(now); \
auto fmt_t = std::put_time(std::localtime(&t), "%Y-%m-%d %H:%M:%S"); \
std::ostringstream oss; \
oss << fmt_t << " [" << getpid() << "|" << gettid() << "] " << msg << "\n"; \
std::cout << oss.str(); \
} while (0)
class _UniInfo {
public:
_UniInfo(const std::string& msg) : msg_(msg) {
start_ = std::chrono::system_clock::now();
INFO(msg_ << " Enter");
}
~_UniInfo() {
INFO(msg_ << " Exit");
auto end = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start_).count();
INFO(msg_ << " elapsed time: " << elapsed << " microseconds");
}
private:
std::string msg_;
std::chrono::system_clock::time_point start_;
};
#define FUNC(msg) \
std::ostringstream _oss; \
_oss << msg; \
_UniInfo _uniInfo(_oss.str());
#define FUNCTION() FUNC(__func__)
int main(int argc, char* argv[]) {
FUNCTION();
return 0;
}
INFO中之所以先ostringstream再cout,是由于msg中有可能会存在函数调用,是函数调用先执行后再cout。