aboutsummaryrefslogblamecommitdiffstats
path: root/library/cpp/unified_agent_client/logger.h
blob: 8130c2894c3036fad9cc7598eb1caba2ad0ef9a9 (plain) (tree)





































































































































                                                                                                               





                                                                   




















                                                                                                   
#pragma once

#include <library/cpp/unified_agent_client/f_maybe.h>
#include <library/cpp/unified_agent_client/throttling.h>

#include <library/cpp/logger/log.h>
#include <library/cpp/monlib/dynamic_counters/counters.h>

#include <util/generic/string.h>
#include <util/string/join.h>
#include <util/string/printf.h>
#include <util/system/file.h>

#include <atomic>

#define YLOG(logPriority, message, logger)                                        \
    do {                                                                          \
        const auto __logPriority = logPriority;                                   \
        if (auto* log = logger.Accept(__logPriority, false); log != nullptr) {    \
            logger.Log(*log, __logPriority, message);                             \
        }                                                                         \
    } while (false)

#define YLOG_EMERG(msg)         YLOG(TLOG_EMERG, msg, Logger)
#define YLOG_ALERT(msg)         YLOG(TLOG_ALERT, msg, Logger)
#define YLOG_CRIT(msg)          YLOG(TLOG_CRIT, msg, Logger)
#define YLOG_ERR(msg)           YLOG(TLOG_ERR, msg, Logger)
#define YLOG_WARNING(msg)       YLOG(TLOG_WARNING, msg, Logger)
#define YLOG_NOTICE(msg)        YLOG(TLOG_NOTICE, msg, Logger)
#define YLOG_INFO(msg)          YLOG(TLOG_INFO, msg, Logger)
#define YLOG_DEBUG(msg)         YLOG(TLOG_DEBUG, msg, Logger)
#define YLOG_RESOURCES(msg)     YLOG(TLOG_RESOURCES , msg, Logger)

#define YLOG_FATAL(msg)            \
    YLOG(TLOG_CRIT, msg, Logger);  \
    _Exit(1);

namespace NUnifiedAgent {
    class TScopeLogger;

    class TLogger {
    public:
        TLogger(TLog& log, TFMaybe<size_t> rateLimitBytes);

        void StartTracing(ELogPriority logPriority) noexcept;

        void FinishTracing() noexcept;

        inline TScopeLogger Child(const TString& v, NMonitoring::TDeprecatedCounter* errors = nullptr);

        inline void SetErrorsCounter(NMonitoring::TDeprecatedCounter* counter) noexcept {
            Errors = counter;
        }

        inline void SetDroppedBytesCounter(NMonitoring::TDeprecatedCounter* counter) noexcept {
            DroppedBytes = counter;
        }

        inline bool HasRateLimit() const noexcept {
            return Throttler != nullptr;
        }

        friend class TScopeLogger;

    private:
        void Log(TLog& log, ELogPriority logPriority, const TStringBuf message, const TString& scope) const;

        inline TLog* Accept(ELogPriority logPriority, NMonitoring::TDeprecatedCounter* errors) const noexcept {
            if ((logPriority <= TLOG_ERR) && (errors != nullptr)) {
                ++(*errors);
            }
            auto* result = CurrentLogContext_.load(std::memory_order_acquire);
            return result != nullptr && static_cast<int>(logPriority) <= static_cast<int>(result->Priority)
                   ? &result->Log
                   : nullptr;
        }

    private:
        struct TLogContext {
            TLog Log;
            ELogPriority Priority;
        };

        class TThrottlerWithLock {
        public:
            explicit TThrottlerWithLock(size_t rateLimitBytes);

            bool TryConsume(double tokens);

        private:
            TThrottler Throttler;
            TAdaptiveLock Lock;
        };

    private:
        void SetCurrentLogContext(TLogContext& logContext);

        TLogContext& GetOrCreateTracingLogContext(ELogPriority logPriority);

        void SetTracing(TLogContext& logContext, const char* action);

    private:
        TLogContext DefaultLogContext;
        TVector<THolder<TLogContext>> TracingLogContexts;
        std::atomic<TLogContext*> CurrentLogContext_;
        NMonitoring::TDeprecatedCounter* Errors;
        NMonitoring::TDeprecatedCounter* DroppedBytes;
        const THolder<TThrottlerWithLock> Throttler;
        TAdaptiveLock Lock;
    };

    class TScopeLogger {
    public:
        TScopeLogger();

        inline void Log(TLog& log, ELogPriority logPriority, const TStringBuf message) const {
            if (Logger) {
                Logger->Log(log, logPriority, message, Scope);
            }
        }

        inline TLog* Accept(ELogPriority logPriority, bool silent) const noexcept {
            return Logger ? Logger->Accept(logPriority, silent ? nullptr : Errors) : nullptr;
        }

        inline TScopeLogger Child(const TString& v, NMonitoring::TDeprecatedCounter* errors = nullptr) {
            return Logger
                ? Logger->Child(Join('/', Scope, v), errors == nullptr ? Errors : errors)
                : TScopeLogger();
        }

        inline TLogger* Unwrap() noexcept {
            return Logger;
        }

        ELogPriority FiltrationLevel() const {
            if (Logger) {
                return Logger->CurrentLogContext_.load()->Priority;
            }
            return LOG_DEF_PRIORITY;
        }

        friend class TLogger;

    private:
        TScopeLogger(TLogger* logger,
                     const TString& scope,
                     NMonitoring::TDeprecatedCounter* errors);

    private:
        TLogger* Logger;
        TString Scope;
        NMonitoring::TDeprecatedCounter* Errors;
    };

    inline TScopeLogger TLogger::Child(const TString& v, NMonitoring::TDeprecatedCounter* errors) {
        return TScopeLogger(this, v, errors == nullptr ? Errors : errors);
    }

    inline ELogPriority ToLogPriority(int level) noexcept {
        const auto result = ClampVal(level, 0, static_cast<int>(TLOG_RESOURCES));
        return static_cast<ELogPriority>(result);
    }
}