Commit dc171587 authored by Mohammad Husain's avatar Mohammad Husain Committed by Facebook GitHub Bot

Introduce conditional XLOG_EVERY_ macros

Differential Revision: D31976729

fbshipit-source-id: 617cce3a62bad6efbfaea0e7ea6d0f120ae35dcf
parent 5f371615
...@@ -306,6 +306,25 @@ TEST_F(XlogTest, rateLimiting) { ...@@ -306,6 +306,25 @@ TEST_F(XlogTest, rateLimiting) {
"msg 0", "msg 8", "msg 16", "msg 24", "msg 32", "msg 40", "msg 48")); "msg 0", "msg 8", "msg 16", "msg 24", "msg 32", "msg 40", "msg 48"));
handler->clearMessages(); handler->clearMessages();
// Test XLOG_EVERY_N_IF
for (size_t n = 0; n < 50; ++n) {
bool shouldLog = n % 2 == 0;
XLOG_EVERY_N_IF(DBG1, shouldLog, 7, "msg ", n);
}
EXPECT_THAT(
handler->getMessageValues(),
ElementsAre("msg 0", "msg 14", "msg 28", "msg 42"));
handler->clearMessages();
for (size_t n = 0; n < 50; ++n) {
XLOG_EVERY_N(DBG1, SEVEN + 1, "msg ", n);
}
EXPECT_THAT(
handler->getMessageValues(),
ElementsAre(
"msg 0", "msg 8", "msg 16", "msg 24", "msg 32", "msg 40", "msg 48"));
handler->clearMessages();
// Test XLOG_EVERY_N_EXACT // Test XLOG_EVERY_N_EXACT
for (size_t n = 0; n < 50; ++n) { for (size_t n = 0; n < 50; ++n) {
XLOG_EVERY_N_EXACT(DBG1, 7, "msg ", n); XLOG_EVERY_N_EXACT(DBG1, 7, "msg ", n);
...@@ -379,6 +398,10 @@ TEST_F(XlogTest, rateLimiting) { ...@@ -379,6 +398,10 @@ TEST_F(XlogTest, rateLimiting) {
XLOG_N_PER_MS(DBG1, 1, 100ms, "1x ms arg ", n); XLOG_N_PER_MS(DBG1, 1, 100ms, "1x ms arg ", n);
XLOG_N_PER_MS(DBG1, 3, 1s, "3x s arg ", n); XLOG_N_PER_MS(DBG1, 3, 1s, "3x s arg ", n);
// Conditional logging
bool shouldLog = n && (n % 2 == 0);
XLOG_EVERY_MS_IF(DBG1, shouldLog, 100, "int arg conditional ", n);
// Sleep for 100ms between iterations 5 and 6 // Sleep for 100ms between iterations 5 and 6
if (n == 5) { if (n == 5) {
/* sleep override */ std::this_thread::sleep_for(110ms); /* sleep override */ std::this_thread::sleep_for(110ms);
...@@ -387,11 +410,27 @@ TEST_F(XlogTest, rateLimiting) { ...@@ -387,11 +410,27 @@ TEST_F(XlogTest, rateLimiting) {
EXPECT_THAT( EXPECT_THAT(
handler->getMessageValues(), handler->getMessageValues(),
ElementsAreArray({ ElementsAreArray({
"int arg 0", "ms arg 0", "s arg 0", "s arg capture 0", "int arg 0",
"fmt arg 0", "fmt ms arg 0", "2x int arg 0", "1x ms arg 0", "ms arg 0",
"3x s arg 0", "2x int arg 1", "3x s arg 1", "3x s arg 2", "s arg 0",
"int arg 6", "ms arg 6", "fmt arg 6", "fmt ms arg 6", "s arg capture 0",
"2x int arg 6", "1x ms arg 6", "2x int arg 7", "fmt arg 0",
"fmt ms arg 0",
"2x int arg 0",
"1x ms arg 0",
"3x s arg 0",
"2x int arg 1",
"3x s arg 1",
"3x s arg 2",
"int arg conditional 2",
"int arg 6",
"ms arg 6",
"fmt arg 6",
"fmt ms arg 6",
"2x int arg 6",
"1x ms arg 6",
"int arg conditional 6",
"2x int arg 7",
})); }));
handler->clearMessages(); handler->clearMessages();
......
...@@ -116,6 +116,24 @@ ...@@ -116,6 +116,24 @@
}(), \ }(), \
##__VA_ARGS__) ##__VA_ARGS__)
/**
* Similar to XLOG(...) except only log a message every @param ms
* milliseconds and if the specified condition predicate evaluates to true.
*
* Note that this is threadsafe.
*/
#define XLOG_EVERY_MS_IF(level, cond, ms, ...) \
XLOG_IF( \
level, \
(cond) && \
[__folly_detail_xlog_ms = ms] { \
static ::folly::logging::IntervalRateLimiter \
folly_detail_xlog_limiter( \
1, std::chrono::milliseconds(__folly_detail_xlog_ms)); \
return folly_detail_xlog_limiter.check(); \
}(), \
##__VA_ARGS__)
/** /**
* Similar to XLOGF(...) except only log a message every @param ms * Similar to XLOGF(...) except only log a message every @param ms
* milliseconds. * milliseconds.
...@@ -168,6 +186,27 @@ FOLLY_EXPORT FOLLY_ALWAYS_INLINE bool xlogEveryNImpl(size_t n) { ...@@ -168,6 +186,27 @@ FOLLY_EXPORT FOLLY_ALWAYS_INLINE bool xlogEveryNImpl(size_t n) {
}(), \ }(), \
##__VA_ARGS__) ##__VA_ARGS__)
/**
* Similar to XLOG(...) except only log a message every @param n
* invocations, approximately, and if the specified condition predicate
* evaluates to true.
*
* The internal counter is process-global and threadsafe but, to
* to avoid the performance degradation of atomic-rmw operations,
* increments are non-atomic. Some increments may be missed under
* contention, leading to possible over-logging or under-logging
* effects.
*/
#define XLOG_EVERY_N_IF(level, cond, n, ...) \
XLOG_IF( \
level, \
(cond) && \
[&] { \
struct folly_detail_xlog_tag {}; \
return ::folly::detail::xlogEveryNImpl<folly_detail_xlog_tag>(n); \
}(), \
##__VA_ARGS__)
namespace folly { namespace folly {
namespace detail { namespace detail {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment