Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/workerd/util/sentry-test.c++
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "sentry.h"

#include <kj/test.h>
#include <kj/thread.h>

namespace {

Expand All @@ -26,4 +27,11 @@ KJ_TEST("Sentry tags are applied only when logging") {
expectSentryTag("NOSENTRY"_kj);
}

KJ_TEST("periodic logging is thread-safe") {
auto log = []() { LOG_PERIODICALLY(INFO, "concurrent periodic log"); };

kj::Thread first(log);
kj::Thread second(log);
}

} // namespace
25 changes: 20 additions & 5 deletions src/workerd/util/sentry.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <kj/string.h>
#include <kj/time.h>

#include <atomic>
#include <cstdint>

namespace workerd {
Expand Down Expand Up @@ -69,6 +70,23 @@ inline bool isInterestingException(const kj::Exception& e) {
e.getType() != kj::Exception::Type::OVERLOADED;
}

struct LogPeriodically {
bool shouldLog() {
const auto now = kj::systemCoarseMonotonicClock().now();
const auto nowNanos = (now - kj::origin<kj::TimePoint>()) / kj::NANOSECONDS;
const auto lastLogged = lastLoggedNanos.load(std::memory_order_relaxed);
if (KJ_LIKELY(nowNanos - lastLogged < 1 * kj::HOURS / kj::NANOSECONDS)) {
return false;
}

lastLoggedNanos.store(nowNanos, std::memory_order_relaxed);
return true;
Comment thread
jasnell marked this conversation as resolved.
}

private:
std::atomic<int64_t> lastLoggedNanos{-(1 * kj::HOURS / kj::NANOSECONDS)};
};

#define LOG_NOSENTRY(severity, ...) KJ_LOG(severity, "NOSENTRY " __VA_ARGS__);

#define LOG_IF_INTERESTING(exception, severity, ...) \
Expand Down Expand Up @@ -98,11 +116,8 @@ inline bool isInterestingException(const kj::Exception& e) {
// be prohibitive.
#define LOG_PERIODICALLY(severity, ...) \
do { \
static kj::TimePoint KJ_UNIQUE_NAME(lastLogged) = kj::origin<kj::TimePoint>() - 1 * kj::HOURS; \
const auto KJ_UNIQUE_NAME(now) = kj::systemCoarseMonotonicClock().now(); \
const auto KJ_UNIQUE_NAME(elapsed) = KJ_UNIQUE_NAME(now) - KJ_UNIQUE_NAME(lastLogged); \
if (KJ_UNLIKELY(KJ_UNIQUE_NAME(elapsed) >= 1 * kj::HOURS)) { \
KJ_UNIQUE_NAME(lastLogged) = KJ_UNIQUE_NAME(now); \
static ::workerd::LogPeriodically KJ_UNIQUE_NAME(logPeriodically); \
if (KJ_UNLIKELY(KJ_UNIQUE_NAME(logPeriodically).shouldLog())) { \
KJ_LOG(severity, __VA_ARGS__); \
} \
} while (0)
Expand Down
Loading