void Logger::log(LogLevelType level, const std::string &msg, const StackTrace *stackTrace, bool escape /* = false */, bool escapeMore /* = false */) { if (Logger::Escape) { escape = true; } assert(!escapeMore || escape); ThreadData *threadData = s_threadData.get(); if (++threadData->message > MaxMessagesPerRequest && MaxMessagesPerRequest >= 0) { return; } boost::shared_ptr<StackTrace> deleter; if (LogNativeStackTrace && stackTrace == nullptr) { deleter = boost::shared_ptr<StackTrace>(new StackTrace()); stackTrace = deleter.get(); } if (UseSyslog) { syslog(GetSyslogLevel(level), "%s", msg.c_str()); } FILE *stdf = GetStandardOut(level); if (UseLogFile) { FILE *f; if (UseCronolog) { f = cronOutput.getOutputFile(); if (!f) f = stdf; } else { f = Output ? Output : stdf; } string header, sheader; if (LogHeader) { header = GetHeader(); if (LogNativeStackTrace) { sheader = header + "[" + stackTrace->hexEncode(5) + "] "; } else { sheader = header; } } const char *escaped = escape ? EscapeString(msg) : msg.c_str(); const char *ending = escapeMore ? "\\n" : "\n"; int bytes; if (f == stdf && s_stderr_color) { bytes = fprintf(f, "%s%s%s%s%s", s_stderr_color, sheader.c_str(), msg.c_str(), ending, ANSI_COLOR_END); } else { bytes = fprintf(f, "%s%s%s", sheader.c_str(), escaped, ending); } bytesWritten.fetch_add(bytes, std::memory_order_relaxed); FILE *tf = threadData->log; if (tf) { threadData->bytesWritten += fprintf(tf, "%s%s%s", header.c_str(), escaped, ending); fflush(tf); threadData->prevBytesWritten = checkDropCache(threadData->bytesWritten, threadData->prevBytesWritten, tf); } if (threadData->hook) { threadData->hook(header.c_str(), msg.c_str(), ending, threadData->hookData); } if (escape) { free((void*)escaped); } fflush(f); if (UseCronolog || (Output && !Logger::IsPipeOutput)) { prevBytesWritten = checkDropCache(bytesWritten.load(std::memory_order_relaxed), prevBytesWritten, f); } } }
void Logger::log(bool err, const std::string &msg, const StackTrace *stackTrace, bool escape /* = true */, bool escapeMore /* = false */) { ASSERT(!escapeMore || escape); ThreadData *threadData = s_threadData.get(); if (++threadData->message > MaxMessagesPerRequest && MaxMessagesPerRequest >= 0) { return; } boost::shared_ptr<StackTrace> deleter; if (stackTrace == NULL) { deleter = boost::shared_ptr<StackTrace>(new StackTrace()); stackTrace = deleter.get(); } if (UseLogAggregator) { LogAggregator::TheLogAggregator.log(*stackTrace, msg); } FILE *stdf = err ? stderr : stdout; if (UseLogFile) { FILE *f; if (UseCronolog) { f = cronOutput.getOutputFile(); if (!f) f = stdf; } else { f = Output ? Output : stdf; } string header, sheader; if (LogHeader) { header = GetHeader(); if (LogNativeStackTrace) { sheader = header + "[" + stackTrace->hexEncode(5) + "] "; } else { sheader = header; } } const char *escaped = escape ? EscapeString(msg) : msg.c_str(); const char *ending = escapeMore ? "\\n" : "\n"; int bytes; if (f == stdf && Util::s_stderr_color) { bytes = fprintf(f, "%s%s%s%s%s", Util::s_stderr_color, sheader.c_str(), msg.c_str(), ending, ANSI_COLOR_END); } else { bytes = fprintf(f, "%s%s%s", sheader.c_str(), escaped, ending); } atomic_add(bytesWritten, bytes); FILE *tf = threadData->log; if (tf) { threadData->bytesWritten += fprintf(tf, "%s%s%s", header.c_str(), escaped, ending); fflush(tf); checkDropCache(threadData->bytesWritten, threadData->prevBytesWritten, tf); } if (threadData->hook) { threadData->hook(header.c_str(), msg.c_str(), ending, threadData->hookData); } if (escape) { free((void*)escaped); } fflush(f); if (UseCronolog || (Output && RuntimeOption::LogFile[0] != '|')) { checkDropCache(bytesWritten, prevBytesWritten, f); } } }