proxygen
xlog.h File Reference
#include <folly/Likely.h>
#include <folly/Portability.h>
#include <folly/Range.h>
#include <folly/logging/LogStream.h>
#include <folly/logging/Logger.h>
#include <folly/logging/LoggerDB.h>
#include <folly/logging/RateLimiter.h>
#include <cstdlib>

Go to the source code of this file.

Classes

class  folly::XlogFileScopeInfo
 
class  folly::XlogLevelInfo< IsInHeaderFile >
 
class  folly::XlogCategoryInfo< IsInHeaderFile >
 

Namespaces

 folly
 —— Concurrent Priority Queue Implementation ——
 
 folly::detail
 
 xlog_detail
 

Macros

#define XLOG(level, ...)
 
#define XLOG_IF(level, cond, ...)
 
#define XLOGF(level, fmt, arg1, ...)
 
#define XLOGF_IF(level, cond, fmt, arg1, ...)
 
#define XLOG_EVERY_MS(level, ms, ...)
 
#define XLOG_EVERY_N(level, n, ...)
 
#define XLOG_N_PER_MS(level, count, ms, ...)
 
#define XLOG_FILENAME   __FILE__
 
#define XLOG_IMPL(level, type, ...)
 
#define XLOG_IF_IMPL(level, cond, type, ...)   XLOG_ACTUAL_IMPL(level, cond, false, type, ##__VA_ARGS__)
 
#define XLOG_ACTUAL_IMPL(level, cond, always_fatal, type, ...)
 
#define XLOG_IS_ON(level)   XLOG_IS_ON_IMPL(::folly::LogLevel::level)
 
#define XLOG_IS_ON_IMPL(level)
 
#define XLOG_GET_CATEGORY_NAME()
 
#define XLOG_GET_CATEGORY()   folly::LoggerDB::get().getCategory(XLOG_GET_CATEGORY_NAME())
 
#define XLOG_SET_CATEGORY_CHECK
 
#define XLOG_SET_CATEGORY_NAME(category)
 
#define XCHECK(cond, ...)   XLOG_IF(FATAL, UNLIKELY(!(cond)), "Check failed: " #cond " ", ##__VA_ARGS__)
 
#define XDCHECK(cond, ...)   (!::folly::kIsDebug) ? static_cast<void>(0) : XCHECK(cond, ##__VA_ARGS__)
 
#define XLOG_IS_IN_HEADER_FILE   true
 

Functions

StringPiece folly::getXlogCategoryNameForFile (StringPiece filename)
 
constexpr bool folly::xlogIsDirSeparator (char c)
 
constexpr const char * folly::detail::xlogStripFilenameRecursive (const char *filename, const char *prefixes, size_t prefixIdx, size_t filenameIdx, bool match)
 
constexpr const char * folly::detail::xlogStripFilenameMatchFound (const char *filename, const char *prefixes, size_t prefixIdx, size_t filenameIdx)
 
constexpr const char * folly::xlogStripFilename (const char *filename, const char *prefixes)
 

Macro Definition Documentation

#define XCHECK (   cond,
  ... 
)    XLOG_IF(FATAL, UNLIKELY(!(cond)), "Check failed: " #cond " ", ##__VA_ARGS__)

Assert that a condition is true.

This crashes the program with an XLOG(FATAL) message if the condition is false. Unlike assert() CHECK statements are always enabled, regardless of the setting of NDEBUG.

Definition at line 332 of file xlog.h.

Referenced by main().

#define XDCHECK (   cond,
  ... 
)    (!::folly::kIsDebug) ? static_cast<void>(0) : XCHECK(cond, ##__VA_ARGS__)

Assert that a condition is true in non-debug builds.

When NDEBUG is set this behaves like XDCHECK() When NDEBUG is not defined XDCHECK statements are not evaluated and will never log.

You can use XLOG_IF(DFATAL, condition) instead if you want the condition to be evaluated in release builds but log a message without crashing the program.

Definition at line 346 of file xlog.h.

Referenced by main().

#define XLOG (   level,
  ... 
)
Value:
::folly::LogLevel::level, \
##__VA_ARGS__)
#define XLOG_IMPL(level, type,...)
Definition: xlog.h:165

Log a message to this file's default log category.

By default the log category name is automatically picked based on the current filename. In src/foo/bar.cpp the log category name "src.foo.bar" will be used. In "lib/stuff/foo.h" the log category name will be "lib.stuff.foo"

Note that the filename is based on the FILE macro defined by the compiler. This is typically dependent on the filename argument that you give to the compiler. For example, if you compile src/foo/bar.cpp by invoking the compiler inside src/foo and only give it "bar.cpp" as an argument, the category name will simply be "bar". In general XLOG() works best if you always invoke the compiler from the root directory of your project repository.

Definition at line 57 of file xlog.h.

Referenced by ReadStats::check(), main(), ReadStats::messageReceived(), readThread(), TEST(), TEST_F(), logging_test::testXlogFile1Dbg1(), logging_test::testXlogFile2Dbg1(), and logging_test::testXlogHdrFunction().

#define XLOG_ACTUAL_IMPL (   level,
  cond,
  always_fatal,
  type,
  ... 
)
Value:
(!XLOG_IS_ON_IMPL(level) || !(cond)) \
::folly::LogStreamProcessor( \
[] { \
static ::folly::XlogCategoryInfo<XLOG_IS_IN_HEADER_FILE> \
folly_detail_xlog_category; \
return folly_detail_xlog_category.getInfo( \
&xlog_detail::xlogFileScopeInfo); \
}(), \
(level), \
xlog_detail::getXlogCategoryName(XLOG_FILENAME, 0), \
xlog_detail::isXlogCategoryOverridden(0), \
__LINE__, \
__func__, \
(type), \
##__VA_ARGS__) \
.stream()
#define XLOG_FILENAME
Definition: xlog.h:162
void logDisabledHelper(std::true_type) noexcept
PskType type
std::integral_constant< bool, B > bool_constant
Definition: Traits.h:145
#define XLOG_IS_ON_IMPL(level)
Definition: xlog.h:258
constexpr bool isLogLevelFatal(LogLevel level)
Definition: LogLevel.h:145

Helper macro used to implement XLOG() and XLOGF()

Beware that the level argument is evaluated twice.

This macro is somewhat tricky:

  • In order to support streaming argument support (with the << operator), the macro must expand to a single ternary ? expression. This is the only way we can avoid evaluating the log arguments if the log check fails, and still have the macro behave as expected when used as the body of an if or else statement.
  • We need to store some static-scope local state in order to track the LogCategory to use. This is a bit tricky to do and still meet the requirements of being a single expression, but fortunately static variables inside a lambda work for this purpose.

    Inside header files, each XLOG() statement defines to static variables:

    • the LogLevel for this category
    • a pointer to the LogCategory

    If the INCLUDE_LEVEL macro is available (both gcc and clang support this), then we we can detect when we are inside a .cpp file versus a header file. If we are inside a .cpp file, we can avoid declaring these variables once per XLOG() statement, and instead we only declare one copy of these variables for the entire file.

  • We want to make sure this macro is safe to use even from inside static initialization code that runs before main. We also want to make the log admittance check as cheap as possible, so that disabled debug logs have minimal overhead, and can be left in place even in performance senstive code.

    In order to do this, we rely on zero-initialization of variables with static storage duration. The LogLevel variable will always be 0-initialized before any code runs. Therefore the very first time an XLOG() statement is hit the initial log level check will always pass (since all level values are greater or equal to 0), and we then do a second check to see if the log level and category variables need to be initialized. On all subsequent calls, disabled log statements can be skipped with just a single check of the LogLevel.

Definition at line 215 of file xlog.h.

#define XLOG_EVERY_MS (   level,
  ms,
  ... 
)
Value:
level, \
[] { \
static ::folly::logging::IntervalRateLimiter \
folly_detail_xlog_limiter(1, std::chrono::milliseconds(ms)); \
return folly_detail_xlog_limiter.check(); \
}(), \
##__VA_ARGS__)
#define XLOG_IF(level, cond,...)
Definition: xlog.h:68

Similar to XLOG(...) except only log a message every

Parameters
msmilliseconds.

Note that this is threadsafe.

Definition at line 105 of file xlog.h.

Referenced by TEST_F().

#define XLOG_EVERY_N (   level,
  n,
  ... 
)
Value:
level, \
[] { \
static std::atomic<size_t> folly_detail_xlog_count{0}; \
(folly_detail_xlog_count.fetch_add(1, std::memory_order_relaxed) % \
(n)) == 0); \
}(), \
##__VA_ARGS__)
#define FOLLY_UNLIKELY(x)
Definition: Likely.h:36
#define XLOG_IF(level, cond,...)
Definition: xlog.h:68

Similar to XLOG(...) except only log a message every

Parameters
ninvocations.

The internal counter is process-global and threadsafe.

Definition at line 121 of file xlog.h.

Referenced by TEST_F().

#define XLOG_FILENAME   __FILE__

FOLLY_XLOG_STRIP_PREFIXES can be defined to a string containing a colon-separated list of directory prefixes to strip off from the filename before using it to compute the log category name.

If this is defined, use xlogStripFilename() to strip off directory prefixes; otherwise just use FILE literally. xlogStripFilename() is a constexpr expression so that this stripping can be performed fully at compile time. (There is no guarantee that the compiler will evaluate it at compile time, though.)

Definition at line 162 of file xlog.h.

#define XLOG_GET_CATEGORY ( )    folly::LoggerDB::get().getCategory(XLOG_GET_CATEGORY_NAME())

Get a pointer to the LogCategory that will be used by XLOG() statements in this file.

This is just a small wrapper around a LoggerDB::getCategory() call. This must be implemented as a macro since it uses FILE, and that must expand to the correct filename based on where the macro is used.

Definition at line 286 of file xlog.h.

Referenced by TEST(), and TEST_F().

#define XLOG_GET_CATEGORY_NAME ( )
Value:
(xlog_detail::isXlogCategoryOverridden(0) \
? xlog_detail::getXlogCategoryName(XLOG_FILENAME, 0) \
#define XLOG_FILENAME
Definition: xlog.h:162
StringPiece getXlogCategoryNameForFile(StringPiece filename)
Definition: xlog.cpp:57

Get the name of the log category that will be used by XLOG() statements in this file.

Definition at line 273 of file xlog.h.

Referenced by TEST_F().

#define XLOG_IF (   level,
  cond,
  ... 
)
Value:
::folly::LogLevel::level, \
cond, \
##__VA_ARGS__)
#define XLOG_IF_IMPL(level, cond, type,...)
Definition: xlog.h:169

Log a message if and only if the specified condition predicate evaluates to true. Note that the condition is only evaluated if the log-level check passes.

Definition at line 68 of file xlog.h.

Referenced by main(), and TEST_F().

#define XLOG_IF_IMPL (   level,
  cond,
  type,
  ... 
)    XLOG_ACTUAL_IMPL(level, cond, false, type, ##__VA_ARGS__)

Definition at line 169 of file xlog.h.

#define XLOG_IMPL (   level,
  type,
  ... 
)
Value:
level, true, ::folly::isLogLevelFatal(level), type, ##__VA_ARGS__)
PskType type
constexpr bool isLogLevelFatal(LogLevel level)
Definition: LogLevel.h:145
#define XLOG_ACTUAL_IMPL(level, cond, always_fatal, type,...)
Definition: xlog.h:215

Definition at line 165 of file xlog.h.

#define XLOG_IS_IN_HEADER_FILE   true

XLOG_IS_IN_HEADER_FILE evaluates to false if we can definitively tell if we are not in a header file. Otherwise, it evaluates to true.

Definition at line 358 of file xlog.h.

#define XLOG_IS_ON (   level)    XLOG_IS_ON_IMPL(::folly::LogLevel::level)

Check if an XLOG() statement with the given log level would be enabled.

The level parameter must be an unqualified LogLevel enum value.

Definition at line 241 of file xlog.h.

Referenced by TEST_F().

#define XLOG_IS_ON_IMPL (   level)
Value:
([] { \
static ::folly::XlogLevelInfo<XLOG_IS_IN_HEADER_FILE> \
folly_detail_xlog_level; \
return folly_detail_xlog_level.check( \
(level), \
xlog_detail::getXlogCategoryName(XLOG_FILENAME, 0), \
xlog_detail::isXlogCategoryOverridden(0), \
&xlog_detail::xlogFileScopeInfo); \
}())
#define XLOG_FILENAME
Definition: xlog.h:162

Helper macro to implement of XLOG_IS_ON()

This macro is used in the XLOG() implementation, and therefore must be as cheap as possible. It stores the category's LogLevel as a local static variable. The very first time this macro is evaluated it will look up the correct LogCategory and initialize the LogLevel. Subsequent calls then are only a single conditional log level check.

The LogCategory object keeps track of this local LogLevel variable and automatically keeps it up-to-date when the category's effective level is changed.

See XlogLevelInfo for the implementation details.

Definition at line 258 of file xlog.h.

#define XLOG_N_PER_MS (   level,
  count,
  ms,
  ... 
)
Value:
level, \
[] { \
static ::folly::logging::IntervalRateLimiter \
folly_detail_xlog_limiter((count), std::chrono::milliseconds(ms)); \
return folly_detail_xlog_limiter.check(); \
}(), \
##__VA_ARGS__)
#define XLOG_IF(level, cond,...)
Definition: xlog.h:68
int * count

Similar to XLOG(...) except only log at most

Parameters
countmessages per
msmillisecond interval.

The internal counters are process-global and threadsafe.

Definition at line 138 of file xlog.h.

Referenced by TEST_F().

#define XLOG_SET_CATEGORY_CHECK

XLOG_SET_CATEGORY_NAME() can be used to explicitly define the log category name used by all XLOG() and XLOGF() calls in this translation unit.

This overrides the default behavior of picking a category name based on the current filename.

This should be used at the top-level scope in a .cpp file, before any XLOG() or XLOGF() macros have been used in the file.

XLOG_SET_CATEGORY_NAME() cannot be used inside header files.

Definition at line 307 of file xlog.h.

#define XLOG_SET_CATEGORY_NAME (   category)
Value:
namespace { \
namespace xlog_detail { \
XLOG_SET_CATEGORY_CHECK \
constexpr inline folly::StringPiece getXlogCategoryName( \
int) { \
return category; \
} \
constexpr inline bool isXlogCategoryOverridden(int) { \
return true; \
} \
} \
}

Definition at line 310 of file xlog.h.

#define XLOGF (   level,
  fmt,
  arg1,
  ... 
)
Value:
::folly::LogLevel::level, \
fmt, \
arg1, \
##__VA_ARGS__)
#define XLOG_IMPL(level, type,...)
Definition: xlog.h:165

Log a message to this file's default log category, using a format string.

Definition at line 77 of file xlog.h.

Referenced by example::ExampleObject::ExampleObject(), main(), TEST(), TEST_F(), logging_test::testXlogHdrLoop(), and example::ExampleObject::~ExampleObject().

#define XLOGF_IF (   level,
  cond,
  fmt,
  arg1,
  ... 
)
Value:
::folly::LogLevel::level, \
cond, \
fmt, \
arg1, \
##__VA_ARGS__)
#define XLOG_IF_IMPL(level, cond, type,...)
Definition: xlog.h:169

Log a message using a format string if and only if the specified condition predicate evaluates to true. Note that the condition is only evaluated if the log-level check passes.

Definition at line 90 of file xlog.h.

Referenced by TEST_F().