15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/* 25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle 35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004--2005, Google Inc. 45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without 65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met: 75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer. 105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer in the documentation 125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * and/or other materials provided with the distribution. 135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 3. The name of the author may not be used to endorse or promote products 145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * derived from this software without specific prior written permission. 155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LOG(...) an ostream target that can be used to send formatted 295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// output to a variety of logging targets, such as debugger console, stderr, 305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// file, or any StreamInterface. 315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// The severity level passed as the first argument to the LOGging 325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// functions is used as a filter, to limit the verbosity of the logging. 335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Static members of LogMessage documented below are used to control the 345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// verbosity and target of the output. 355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// There are several variations on the LOG macro which facilitate logging 365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// of common error conditions, detailed below. 375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LOG(sev) logs the given stream at severity "sev", which must be a 395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// compile-time constant of the LoggingSeverity type, without the namespace 405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// prefix. 415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LOG_V(sev) Like LOG(), but sev is a run-time variable of the LoggingSeverity 425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// type (basically, it just doesn't prepend the namespace). 435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LOG_F(sev) Like LOG(), but includes the name of the current function. 445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LOG_GLE(M)(sev [, mod]) attempt to add a string description of the 455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// HRESULT returned by GetLastError. The "M" variant allows searching of a 465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// DLL's string table for the error description. 475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LOG_ERRNO(sev) attempts to add a string description of an errno-derived 485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// error. errno and associated facilities exist on both Windows and POSIX, 495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// but on Windows they only apply to the C/C++ runtime. 505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LOG_ERR(sev) is an alias for the platform's normal error system, i.e. _GLE on 515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Windows and _ERRNO on POSIX. 525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// (The above three also all have _EX versions that let you specify the error 535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// code, rather than using the last one.) 545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LOG_E(sev, ctx, err, ...) logs a detailed error interpreted using the 555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// specified context. 565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LOG_CHECK_LEVEL(sev) (and LOG_CHECK_LEVEL_V(sev)) can be used as a test 575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// before performing expensive or sensitive operations whose sole purpose is 585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// to output logging data at the desired level. 595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Lastly, PLOG(sev, err) is an alias for LOG_ERR_EX. 605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef TALK_BASE_LOGGING_H_ 625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define TALK_BASE_LOGGING_H_ 635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef HAVE_CONFIG_H 655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "config.h" // NOLINT 665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <list> 695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <sstream> 705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <string> 715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <utility> 725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/basictypes.h" 735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/criticalsection.h" 745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace talk_base { 765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass StreamInterface; 785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// ConstantLabel can be used to easily generate string names from constant 815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// values. This can be useful for logging descriptive names of error messages. 825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Usage: 835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// const ConstantLabel LIBRARY_ERRORS[] = { 845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// KLABEL(SOME_ERROR), 855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// KLABEL(SOME_OTHER_ERROR), 865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// ... 875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LASTLABEL 885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// } 895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// 905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// int err = LibraryFunc(); 915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LOG(LS_ERROR) << "LibraryFunc returned: " 925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// << ErrorName(err, LIBRARY_ERRORS); 935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstruct ConstantLabel { int value; const char * label; }; 955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define KLABEL(x) { x, #x } 965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define TLABEL(x, y) { x, y } 975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LASTLABEL { 0, 0 } 985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char * FindLabel(int value, const ConstantLabel entries[]); 1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string ErrorName(int err, const ConstantLabel* err_table); 1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org////////////////////////////////////////////////////////////////////// 1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Note that the non-standard LoggingSeverity aliases exist because they are 1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// still in broad use. The meanings of the levels are: 1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LS_SENSITIVE: Information which should only be logged with the consent 1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// of the user, due to privacy concerns. 1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LS_VERBOSE: This level is for data which we do not want to appear in the 1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// normal debug log, but should appear in diagnostic logs. 1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LS_INFO: Chatty level used in debugging for all sorts of things, the default 1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// in debug builds. 1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LS_WARNING: Something that may warrant investigation. 1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LS_ERROR: Something that should not have occurred. 1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgenum LoggingSeverity { LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR, 1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org INFO = LS_INFO, 1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org WARNING = LS_WARNING, 1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LERROR = LS_ERROR }; 1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// LogErrorContext assists in interpreting the meaning of an error value. 1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgenum LogErrorContext { 1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ERRCTX_NONE, 1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ERRCTX_ERRNO, // System-local errno 1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ERRCTX_HRESULT, // Windows HRESULT 1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ERRCTX_OSSTATUS, // MacOS OSStatus 1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Abbreviations for LOG_E macro 1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ERRCTX_EN = ERRCTX_ERRNO, // LOG_E(sev, EN, x) 1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ERRCTX_HR = ERRCTX_HRESULT, // LOG_E(sev, HR, x) 1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ERRCTX_OS = ERRCTX_OSSTATUS, // LOG_E(sev, OS, x) 1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass LogMessage { 1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public: 1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static const int NO_LOGGING; 1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static const uint32 WARN_SLOW_LOGS_DELAY = 50; // ms 1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LogMessage(const char* file, int line, LoggingSeverity sev, 1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LogErrorContext err_ctx = ERRCTX_NONE, int err = 0, 1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* module = NULL); 1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ~LogMessage(); 1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static inline bool Loggable(LoggingSeverity sev) { return (sev >= min_sev_); } 1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::ostream& stream() { return print_stream_; } 1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Returns the time at which this function was called for the first time. 1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // The time will be used as the logging start time. 1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If this is not called externally, the LogMessage ctor also calls it, in 1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // which case the logging start time will be the time of the first LogMessage 1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // instance is created. 1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static uint32 LogStartTime(); 1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Returns the wall clock equivalent of |LogStartTime|, in seconds from the 1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // epoch. 1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static uint32 WallClockStartTime(); 1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // These are attributes which apply to all logging channels 1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // LogContext: Display the file and line number of the message 1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void LogContext(int min_sev); 1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // LogThreads: Display the thread identifier of the current thread 1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void LogThreads(bool on = true); 1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // LogTimestamps: Display the elapsed time of the program 1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void LogTimestamps(bool on = true); 1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // These are the available logging channels 1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Debug: Debug console on Windows, otherwise stderr 1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void LogToDebug(int min_sev); 1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static int GetLogToDebug() { return dbg_sev_; } 1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Stream: Any non-blocking stream interface. LogMessage takes ownership of 1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // the stream. Multiple streams may be specified by using AddLogToStream. 1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // LogToStream is retained for backwards compatibility; when invoked, it 1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // will discard any previously set streams and install the specified stream. 1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // GetLogToStream gets the severity for the specified stream, of if none 1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // is specified, the minimum stream severity. 1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // RemoveLogToStream removes the specified stream, without destroying it. 1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void LogToStream(StreamInterface* stream, int min_sev); 1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static int GetLogToStream(StreamInterface* stream = NULL); 1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void AddLogToStream(StreamInterface* stream, int min_sev); 1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void RemoveLogToStream(StreamInterface* stream); 1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Testing against MinLogSeverity allows code to avoid potentially expensive 1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // logging operations by pre-checking the logging level. 1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static int GetMinLogSeverity() { return min_sev_; } 1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void SetDiagnosticMode(bool f) { is_diagnostic_mode_ = f; } 1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static bool IsDiagnosticMode() { return is_diagnostic_mode_; } 1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Parses the provided parameter stream to configure the options above. 1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Useful for configuring logging from the command line. If file logging 1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // is enabled, it is output to the specified filename. 1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void ConfigureLogging(const char* params, const char* filename); 1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Convert the string to a LS_ value; also accept numeric values. 1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static int ParseLogSeverity(const std::string& value); 1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private: 1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org typedef std::list<std::pair<StreamInterface*, int> > StreamList; 1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Updates min_sev_ appropriately when debug sinks change. 2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void UpdateMinLogSeverity(); 2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // These assist in formatting some parts of the debug output. 2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static const char* Describe(LoggingSeverity sev); 2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static const char* DescribeFile(const char* file); 2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // These write out the actual log messages. 2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void OutputToDebug(const std::string& msg, LoggingSeverity severity_); 2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static void OutputToStream(StreamInterface* stream, const std::string& msg); 2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // The ostream that buffers the formatted message before output 2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::ostringstream print_stream_; 2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // The severity level of this message 2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LoggingSeverity severity_; 2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // String data generated in the constructor, that should be appended to 2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // the message before output. 2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string extra_; 2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If time it takes to write to stream is more than this, log one 2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // additional warning about it. 2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org uint32 warn_slow_logs_delay_; 2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Global lock for the logging subsystem 2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static CriticalSection crit_; 2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // dbg_sev_ is the thresholds for those output targets 2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // min_sev_ is the minimum (most verbose) of those levels, and is used 2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // as a short-circuit in the logging macros to identify messages that won't 2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // be logged. 2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // ctx_sev_ is the minimum level at which file context is displayed 2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static int min_sev_, dbg_sev_, ctx_sev_; 2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // The output streams and their associated severities 2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static StreamList streams_; 2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Flags for formatting options 2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static bool thread_, timestamp_; 2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // are we in diagnostic mode (as defined by the app)? 2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static bool is_diagnostic_mode_; 2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org DISALLOW_EVIL_CONSTRUCTORS(LogMessage); 2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org////////////////////////////////////////////////////////////////////// 2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Logging Helpers 2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org////////////////////////////////////////////////////////////////////// 2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass LogMultilineState { 2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public: 2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t unprintable_count_[2]; 2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LogMultilineState() { 2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org unprintable_count_[0] = unprintable_count_[1] = 0; 2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// When possible, pass optional state variable to track various data across 2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// multiple calls to LogMultiline. Otherwise, pass NULL. 2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid LogMultiline(LoggingSeverity level, const char* label, bool input, 2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const void* data, size_t len, bool hex_mode, 2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LogMultilineState* state); 2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org////////////////////////////////////////////////////////////////////// 2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Macros which automatically disable logging when LOGGING == 0 2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org////////////////////////////////////////////////////////////////////// 2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// If LOGGING is not explicitly defined, default to enabled in debug mode 2695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if !defined(LOGGING) 2705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(_DEBUG) && !defined(NDEBUG) 2715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOGGING 1 2725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else 2735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOGGING 0 2745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 2755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // !defined(LOGGING) 2765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef LOG 2785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if LOGGING 2795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// The following non-obvious technique for implementation of a 2815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// conditional log stream was stolen from google3/base/logging.h. 2825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// This class is used to explicitly ignore values in the conditional 2845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// logging macros. This avoids compiler warnings like "value computed 2855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// is not used" and "statement has no effect". 2865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass LogMessageVoidify { 2885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public: 2895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LogMessageVoidify() { } 2905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // This has to be an operator with a precedence lower than << but 2915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // higher than ?: 2925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void operator&(std::ostream&) { } 2935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 2945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_SEVERITY_PRECONDITION(sev) \ 2965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org !(talk_base::LogMessage::Loggable(sev)) \ 2975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ? (void) 0 \ 2985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org : talk_base::LogMessageVoidify() & 2995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG(sev) \ 3015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_SEVERITY_PRECONDITION(talk_base::sev) \ 3025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org talk_base::LogMessage(__FILE__, __LINE__, talk_base::sev).stream() 3035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// The _V version is for when a variable is passed in. It doesn't do the 3055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// namespace concatination. 3065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_V(sev) \ 3075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_SEVERITY_PRECONDITION(sev) \ 3085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org talk_base::LogMessage(__FILE__, __LINE__, sev).stream() 3095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// The _F version prefixes the message with the current function name. 3115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if (defined(__GNUC__) && defined(_DEBUG)) || defined(WANT_PRETTY_LOG_F) 3125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": " 3135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else 3145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": " 3155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 3165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_CHECK_LEVEL(sev) \ 3185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org talk_base::LogCheckLevel(talk_base::sev) 3195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_CHECK_LEVEL_V(sev) \ 3205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org talk_base::LogCheckLevel(sev) 3215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orginline bool LogCheckLevel(LoggingSeverity sev) { 3225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return (LogMessage::GetMinLogSeverity() <= sev); 3235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_E(sev, ctx, err, ...) \ 3265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_SEVERITY_PRECONDITION(talk_base::sev) \ 3275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org talk_base::LogMessage(__FILE__, __LINE__, talk_base::sev, \ 3285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org talk_base::ERRCTX_ ## ctx, err , ##__VA_ARGS__) \ 3295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org .stream() 3305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else // !LOGGING 3325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Hopefully, the compiler will optimize away some of this code. 3345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Note: syntax of "1 ? (void)0 : LogMessage" was causing errors in g++, 3355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// converted to "while (false)" 3365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG(sev) \ 3375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (false)talk_base:: LogMessage(NULL, 0, talk_base::sev).stream() 3385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_V(sev) \ 3395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (false) talk_base::LogMessage(NULL, 0, sev).stream() 3405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": " 3415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_CHECK_LEVEL(sev) \ 3425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org false 3435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_CHECK_LEVEL_V(sev) \ 3445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org false 3455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_E(sev, ctx, err, ...) \ 3475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (false) talk_base::LogMessage(__FILE__, __LINE__, talk_base::sev, \ 3485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org talk_base::ERRCTX_ ## ctx, err , ##__VA_ARGS__) \ 3495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org .stream() 3505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // !LOGGING 3525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_ERRNO_EX(sev, err) \ 3545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_E(sev, ERRNO, err) 3555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_ERRNO(sev) \ 3565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_ERRNO_EX(sev, errno) 3575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef WIN32 3595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_GLE_EX(sev, err) \ 3605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_E(sev, HRESULT, err) 3615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_GLE(sev) \ 3625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_GLE_EX(sev, GetLastError()) 3635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_GLEM(sev, mod) \ 3645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_E(sev, HRESULT, GetLastError(), mod) 3655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_ERR_EX(sev, err) \ 3665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_GLE_EX(sev, err) 3675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_ERR(sev) \ 3685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_GLE(sev) 3695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LAST_SYSTEM_ERROR \ 3705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (::GetLastError()) 3715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#elif POSIX 3725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_ERR_EX(sev, err) \ 3735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_ERRNO_EX(sev, err) 3745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LOG_ERR(sev) \ 3755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_ERRNO(sev) 3765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define LAST_SYSTEM_ERROR \ 3775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (errno) 3785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // WIN32 3795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define PLOG(sev, err) \ 3815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_ERR_EX(sev, err) 3825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// TODO(?): Add an "assert" wrapper that logs in the same manner. 3845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // LOG 3865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} // namespace talk_base 3885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // TALK_BASE_LOGGING_H_ 390