std::ostream& log(/*LogLevel severity*/) { std::cerr<<"test\n"; if (s_LogNeedInited) initLogLevel(); // if (isLogEnabled((LogLevel)severity)) // { // return g_file; // } return g_file; }
namespace cxwcfea { __thread char t_errnobuf[512]; __thread char t_time[32]; __thread time_t t_lastSecond; Logger::LogLevel initLogLevel() { if (::getenv("CX_LOG_TRACE")) { return Logger::TRACE; } else if (::getenv("CX_LOG_DEBUG")) { return Logger::DEBUG; } else { return Logger::INFO; } } Logger::LogLevel g_logLevel = initLogLevel(); const char *LogLevelName[Logger::NUM_LOG_LEVELS] = { "TRACE ", "DEBUG ", "INFO ", "WARN ", "ERROR ", "FATAL ", }; class T { public: T(const char *str, unsigned len) : str_(str), len_(len) { ASSERT(strlen(str) == len); } const char *str_; const unsigned len_; }; inline LogStream &operator<<(LogStream &s, T v) { s.append(v.str_, v.len_); return s; } inline LogStream &operator<<(LogStream &s, const Logger::SourceFile &v) { s.append(v.data_, v.size_); return s; } auto Logger::Impl::formatTime() -> void { t_lastSecond = time_.secondsSinceEpoch(); strncpy(t_time, time_.toFormattedString().c_str(), sizeof t_time); stream_ << T(t_time, 24); } auto Logger::Impl::finish() -> void { stream_ << " - " << baseName_ << ":" << line_ << "\n"; } auto defaultOutput(const char *msg, int len) -> void { fwrite(msg, 1, len, stdout); } auto defaultFlush() -> void { fflush(stdout); } Logger::OutputFunc g_output = defaultOutput; Logger::FlushFunc g_flush = defaultFlush; Logger::Impl::Impl(LogLevel level, int savedErrno, const SourceFile &baseName, int line) : time_(Timestamp::now()), stream_(), level_(level), line_(line), baseName_(baseName) { formatTime(); CurrentThread::tid(); stream_ << T(CurrentThread::tidString(), 6); stream_ << T(LogLevelName[level], 6); if (savedErrno != 0) { stream_ << strerror_tl(savedErrno) << " (errno=" << savedErrno << ") "; } } Logger::Logger(SourceFile file, int line, LogLevel level) : impl_(level, 0, file, line) { } Logger::Logger(SourceFile file, int line, LogLevel level, const char *func) : Logger(file, line, level) { impl_.stream_ << func << ' '; } Logger::Logger(SourceFile file, int line, bool toAbort) : impl_(toAbort?FATAL:ERROR, errno, file, line) { } auto strerror_tl(int savedErrno) -> const char * { #ifndef __MACH__ return strerror_r(savedErrno, t_errnobuf, sizeof t_errnobuf); #else strerror_r(savedErrno, t_errnobuf, sizeof t_errnobuf); return t_errnobuf; #endif } auto Logger::setLogLevel(LogLevel level) -> void { g_logLevel = level; } inline Logger::~Logger() { impl_.finish(); const LogStream::Buffer &buf(stream().buffer()); g_output(buf.data(), buf.length()); if (impl_.level_ == FATAL) { g_flush(); abort(); } } auto Logger::setOutput(OutputFunc out) -> void { g_output = out; } auto Logger::setFlush(FlushFunc flush) -> void { g_flush = flush; } } // namespace cxwcfea
namespace PUBLIC { Logger::LogLevel initLogLevel() { return Logger::INFO; } Logger::LogLevel g_logLevel = initLogLevel(); const char* LogLevelName[Logger::NUM_LOG_LEVELS] = { "TRACE ", "DEBUG ", "INFO ", "WARN ", "ERROR ", "FATAL ", }; class T { public: T(const char* str, unsigned len) :str_(str), len_(len) { assert(strlen(str) == len_); } const char* str_; const unsigned len_; }; inline LogStream& operator<<(LogStream& s, T v) { s.append(v.str_, v.len_); return s; } inline LogStream& operator<<(LogStream& s, const Logger::SourceFile& v) { s.append(v.data_, v.size_); return s; } void defaultOutput(const char* msg, int len) { size_t n = fwrite(msg, 1, len, stdout); (void)n; } void defaultFlush() { fflush(stdout); } Logger::OutputFunc g_output = defaultOutput; Logger::FlushFunc g_flush = defaultFlush; Logger::Impl::Impl(LogLevel level, int savedErrno, const SourceFile& file, int line) : time_(Timestamp::now()), stream_(), level_(level), line_(line), basename_(file) { formatTime(); stream_ << T(LogLevelName[level], 6); if (savedErrno != 0) { char buf[100] = {0}; #ifdef Q_OS_WIN32 strerror_s(buf, 100, savedErrno); #elseif defined Q_OS_LINUX strerror_r(savedErrno, buf, sizeof(buf)); #endif stream_ << T(buf, strlen(buf)) << " (errno=" << savedErrno << ") "; } } void Logger::Impl::formatTime() { __time64_t seconds = time_.getTime(); struct tm tm_time; char buf[32] = {0}; #ifdef Q_OS_WIN32 _gmtime64_s(&tm_time, &seconds); int len = _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%4d-%02d-%02d %02d:%02d:%02d ", tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec); #elif defined Q_OS_LINUX gmtime_r(&seconds, &tm_time); int len = snprintf(buf, sizeof(buf), "%4d-%02d-%02d %02d:%02d:%02d ", tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec); #endif stream_ << T(buf, len); } void Logger::Impl::finish() { stream_ << " - " << basename_ << ':' << line_ << '\n'; } Logger::Logger(SourceFile file, int line) : impl_(INFO, 0, file, line) { } Logger::Logger(SourceFile file, int line, LogLevel level, const char* func) : impl_(level, 0, file, line) { impl_.stream_ << func << ' '; } Logger::Logger(SourceFile file, int line, LogLevel level) : impl_(level, 0, file, line) { } Logger::Logger(SourceFile file, int line, bool toAbort) : impl_(toAbort?FATAL:ERROR, errno, file, line) { } Logger::~Logger() { impl_.finish(); const LogStream::Buffer& buf(stream().buffer()); g_output(buf.data(), buf.length()); if (impl_.level_ == FATAL) { g_flush(); abort(); } } void Logger::setLogLevel(Logger::LogLevel level) { g_logLevel = level; } void Logger::setOutput(OutputFunc out) { g_output = out; } void Logger::setFlush(FlushFunc flush) { g_flush = flush; } }
namespace kimgbo { __thread char t_errnobuf[512]; __thread char t_time[32]; __thread time_t t_lastSecond; const char* strerror_tl(int savedErrno) { return strerror_r(savedErrno, t_errnobuf, sizeof t_errnobuf); } Logger::LogLevel initLogLevel() { if (::getenv("MUDUO_LOG_TRACE")) return Logger::TRACE; else if (::getenv("MUDUO_LOG_DEBUG")) return Logger::DEBUG; else return Logger::DEBUG; } Logger::LogLevel g_logLevel = initLogLevel(); const char* LogLevelName[Logger::NUM_LOG_LEVELS] = { "TRACE ", "DEBUG ", "INFO ", "WARN ", "ERROR ", "FATAL ", }; // helper class for known string length at compile time class T { public: T(const char* str, unsigned len) :m_str(str), m_len(len) { assert(strlen(str) == m_len); } const char* m_str; const unsigned m_len; }; inline LogStream& operator<<(LogStream& s, T v) { s.append(v.m_str, v.m_len); return s; } inline LogStream& operator<<(LogStream& s, const Logger::SourceFile& v) { s.append(v.m_data, v.m_size); return s; } void defaultOutput(const char* msg, int len) { size_t n = fwrite(msg, 1, len, stdout); //FIXME check n (void)n; } void defaultFlush() { fflush(stdout); } Logger::OutputFunc g_output = defaultOutput; Logger::FlushFunc g_flush = defaultFlush; }
NS_BEGIN threadlocal char t_errnobuf[512]; threadlocal char t_time[32]; threadlocal time_t t_lastSecond; //全局函数,返回一个enum LogLevel Logger::LogLevel initLogLevel() { return Logger::DEBUG; //一般正式环境定义成Logger::INFO } Logger::LogLevel g_logLevel = initLogLevel(); const char* LogLevelName[Logger::NUM_LOG_LEVELS] = { "[TRACE] ", "[DEBUG] ", "[INFO ] ", "[OK ] ", "[WARN ] ", "[ERROR] ", "[FATAL] ", }; /** helper class for known string length at compile time */ class T {
namespace pai { /* class LoggerImpl { public: typedef Logger::LogLevel LogLevel; LoggerImpl(LogLevel level, int old_errno, const char* file, int line); void finish(); Timestamp time_; LogStream stream_; LogLevel level_; int line_; const char* fullname_; const char* basename_; }; */ __thread char t_errnobuf[512]; __thread char t_time[32]; __thread time_t t_lastSecond; const char* strerror_tl(int savedErrno) { return strerror_r(savedErrno, t_errnobuf, sizeof t_errnobuf); } Logger::LogLevel initLogLevel() { if (::getenv("MUDUO_LOG_TRACE")) return Logger::TRACE; else if (::getenv("MUDUO_LOG_DEBUG")) return Logger::DEBUG; else return Logger::INFO; } Logger::LogLevel g_logLevel = initLogLevel(); const char* LogLevelName[Logger::NUM_LOG_LEVELS] = { "TRACE ", "DEBUG ", "INFO ", "WARN ", "ERROR ", "FATAL ", }; // helper class for known string length at compile time class T { public: T(const char* str, unsigned len) :str_(str), len_(len) { assert(strlen(str) == len_); } const char* str_; const unsigned len_; }; inline LogStream& operator<<(LogStream& s, T v) { s.append(v.str_, v.len_); return s; } inline LogStream& operator<<(LogStream& s, const Logger::SourceFile& v) { s.append(v.data_, v.size_); return s; } void defaultOutput(const char* msg, int len) { size_t n = fwrite(msg, 1, len, stdout); //FIXME check n (void)n; } void defaultFlush() { fflush(stdout); } Logger::OutputFunc g_output = defaultOutput; Logger::FlushFunc g_flush = defaultFlush; TimeZone g_logTimeZone; };