void ExtendedLogger::Log(LogLevelType level, CArrRef stackTrace, bool escape /* = true */, bool escapeMore /* = false */) { assert(!escapeMore || escape); ThreadData *threadData = s_threadData.get(); if (++threadData->message > MaxMessagesPerRequest && MaxMessagesPerRequest >= 0) { return; } if (stackTrace.isNull()) return; if (UseLogFile) { FILE *f = Output ? Output : GetStandardOut(level); PrintStackTrace(f, stackTrace, escape, escapeMore); FILE *tf = threadData->log; if (tf) { PrintStackTrace(tf, stackTrace, escape, escapeMore); } } }
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(LogLevelType level, const std::string &msg, const StackTrace *stackTrace, bool escape /* = false */, bool escapeMore /* = false */) { if (Logger::AlwaysEscapeLog && Logger::Escape) { escape = true; } assert(!escapeMore || escape); ThreadData *threadData = s_threadData.get(); if (threadData->message != -1 && ++threadData->message > MaxMessagesPerRequest && MaxMessagesPerRequest >= 0) { return; } std::unique_ptr<StackTrace> deleter; if (LogNativeStackTrace && stackTrace == nullptr) { deleter.reset(new StackTrace()); stackTrace = deleter.get(); } if (UseSyslog) { syslog(GetSyslogLevel(level), "%s", msg.c_str()); } if (UseLogFile) { FILE *stdf = GetStandardOut(level); FILE *f; if (UseCronolog) { f = cronOutput.getOutputFile(); if (!f) f = stdf; } else { f = Output ? Output : stdf; } std::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); } FILE *tf = threadData->log; if (tf) { int threadBytes = fprintf(tf, "%s%s%s", header.c_str(), escaped, ending); fflush(tf); threadData->flusher.recordWriteAndMaybeDropCaches(tf, threadBytes); } 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)) { flusher.recordWriteAndMaybeDropCaches(f, bytes); } } }