// Android has a 1024 limit on log inputs. We use 60 chars as an // approx for the header/tag portion. // See android/system/core/liblog/logd_write.c staticconst int kMaxLogLineSize = 1024 - 60; #endif// WEBRTC_MAC && !defined(WEBRTC_IOS) || WEBRTC_ANDROID
// By default, release builds don't log, debug builds at info level #if !defined(NDEBUG)
constexpr LoggingSeverity kDefaultLoggingSeverity = LS_INFO; #else
constexpr LoggingSeverity kDefaultLoggingSeverity = LS_NONE; #endif
// Note: `g_min_sev` and `g_dbg_sev` can be changed while running.
LoggingSeverity g_min_sev = kDefaultLoggingSeverity;
LoggingSeverity g_dbg_sev = kDefaultLoggingSeverity;
// Return the filename portion of the string (that following the last slash). const char* FilenameFromPath(const char* file) { const char* end1 = ::strrchr(file, '/'); const char* end2 = ::strrchr(file, '\\');
if (!end1 && !end2) return file; else return (end1 > end2) ? end1 + 1 : end2 + 1;
}
// Global lock for log subsystem, only needed to serialize access to streams_.
Mutex& GetLoggingLock() { static Mutex& mutex = *new Mutex(); return mutex;
}
// Internal helper to manage config state. // NOTE: The return value is non-const only while transitioning away from and // deprecating legacy global methods that allow modifying the logging config // after initialization. Once those methods are removed, this should return a // const reference again to ensure lockless read-only access.
LoggingConfig& GetOrInitConfig(LoggingConfig* init_config, bool& config_applied) { static absl::NoDestructor<LoggingConfig> config([&]() {
config_applied = true;
if (init_config != nullptr) { return std::move(*init_config);
} return LoggingConfig(); // Default configuration
}()); return *config;
}
// The list of logging streams currently configured. // Note: we explicitly do not clean this up, because of the uncertain ordering // of destructors at program exit. Let the person who sets the stream trigger // cleanup by setting to null, or let it leak (safe at program exit).
constinit LogSink* LogMessage::streams_ RTC_GUARDED_BY(GetLoggingLock()) =
nullptr;
LogMessage::LogMessage(const char* file,
int line,
LoggingSeverity sev,
LogErrorContext err_ctx,
int err) {
log_line_.set_severity(sev); const LoggingConfig& config = GetLoggingConfig();
if (log_timestamp_) {
int64_t log_start_time = LogStartTime(); // Use SystemTimeMillis so that even if tests use fake clocks, the timestamp // in log messages represents the real system time.
int64_t time = TimeDiff(SystemTimeMillis(), log_start_time); // Also ensure WallClockStartTime is initialized, so that it matches // LogStartTime.
WallClockStartTime();
log_line_.set_timestamp(Timestamp::Millis(time));
}
if (config.log_thread()) {
log_line_.set_thread_id(CurrentThreadId());
}
if (log_queue_name_) {
if (TaskQueueBase* tq = TaskQueueBase::Current(); tq != nullptr) {
log_line_.set_queue_name(tq->queue_name());
}
}
#ifdefined(WEBRTC_WIN) && !defined(WINUWP)
if ((LS_NONE != debug_level) && !::IsDebuggerPresent()) { // First, attempt to attach to our parent's console... so if you invoke // from the command line, we'll see the output there. Otherwise, create // our own console window. // Note: These methods fail if a console already exists, which is fine.
if (!AttachConsole(ATTACH_PARENT_PROCESS))
::AllocConsole();
} #endif// defined(WEBRTC_WIN) && !defined(WINUWP)
void LogMessage::OutputToDebug(const LogLineRef& log_line) {
std::string msg_str = log_line.DefaultLogLine(); bool log_to_stderr = log_to_stderr_; #ifdefined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && defined(NDEBUG) // On the Mac, all stderr output goes to the Console log and causes clutter. // So in opt builds, don't log to stderr unless the user specifically sets // a preference to do so.
CFStringRef domain = CFBundleGetIdentifier(CFBundleGetMainBundle());
if (domain != nullptr) {
Boolean exists_and_is_valid;
Boolean should_log = CFPreferencesGetAppBooleanValue(
CFSTR("logToStdErr"), domain, &exists_and_is_valid); // If the key doesn't exist or is invalid or is false, we will not log to // stderr.
log_to_stderr = exists_and_is_valid && should_log;
} #endif// defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && defined(NDEBUG)
#ifdefined(WEBRTC_WIN) // Always log to the debugger. // Perhaps stderr should be controlled by a preference, as on Mac? #if RTC_DLOG_IS_ON
OutputDebugStringA(msg_str.c_str()); #endif
if (log_to_stderr) { // This handles dynamically allocated consoles, too.
if (HANDLE error_handle = ::GetStdHandle(STD_ERROR_HANDLE)) {
log_to_stderr = false;
DWORD written = 0;
::WriteFile(error_handle, msg_str.c_str(), static_cast<DWORD>(msg_str.size()), &written, 0);
}
} #endif// WEBRTC_WIN
#ifdefined(WEBRTC_ANDROID) // Android's logging facility uses severity to log messages but we // need to map libjingle's severity levels to Android ones first. // Also write to stderr which maybe available to executable started // from the shell.
int prio; switch (log_line.severity()) { case LS_VERBOSE:
prio = ANDROID_LOG_VERBOSE; break; case LS_INFO:
prio = ANDROID_LOG_INFO; break; case LS_WARNING:
prio = ANDROID_LOG_WARN; break; case LS_ERROR:
prio = ANDROID_LOG_ERROR; break; default:
prio = ANDROID_LOG_UNKNOWN;
}
int size = msg_str.size();
int current_line = 0;
int idx = 0; const int max_lines = size / kMaxLogLineSize + 1;
if (max_lines == 1) {
__android_log_print(prio, log_line.tag().data(), "%.*s", size,
msg_str.c_str());
} else { while (size > 0) { const int len = std::min(size, kMaxLogLineSize); // Use the size of the string in the format (msg may have \0 in the // middle).
__android_log_print(prio, log_line.tag().data(), "[%d/%d] %.*s",
current_line + 1, max_lines, len,
msg_str.c_str() + idx);
idx += len;
size -= len;
++current_line;
}
} #endif// WEBRTC_ANDROID
if (log_to_stderr) {
fprintf(stderr, "%s", msg_str.c_str());
fflush(stderr);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.