123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753 |
- #include "log.h"
- #include "log_settings.h"
- #include <library/cpp/monlib/service/pages/templates.h>
- static_assert(int(NActors::NLog::PRI_EMERG) == int(::TLOG_EMERG), "expect int(NActors::NLog::PRI_EMERG) == int(::TLOG_EMERG)");
- static_assert(int(NActors::NLog::PRI_ALERT) == int(::TLOG_ALERT), "expect int(NActors::NLog::PRI_ALERT) == int(::TLOG_ALERT)");
- static_assert(int(NActors::NLog::PRI_CRIT) == int(::TLOG_CRIT), "expect int(NActors::NLog::PRI_CRIT) == int(::TLOG_CRIT)");
- static_assert(int(NActors::NLog::PRI_ERROR) == int(::TLOG_ERR), "expect int(NActors::NLog::PRI_ERROR) == int(::TLOG_ERR)");
- static_assert(int(NActors::NLog::PRI_WARN) == int(::TLOG_WARNING), "expect int(NActors::NLog::PRI_WARN) == int(::TLOG_WARNING)");
- static_assert(int(NActors::NLog::PRI_NOTICE) == int(::TLOG_NOTICE), "expect int(NActors::NLog::PRI_NOTICE) == int(::TLOG_NOTICE)");
- static_assert(int(NActors::NLog::PRI_INFO) == int(::TLOG_INFO), "expect int(NActors::NLog::PRI_INFO) == int(::TLOG_INFO)");
- static_assert(int(NActors::NLog::PRI_DEBUG) == int(::TLOG_DEBUG), "expect int(NActors::NLog::PRI_DEBUG) == int(::TLOG_DEBUG)");
- static_assert(int(NActors::NLog::PRI_TRACE) == int(::TLOG_RESOURCES), "expect int(NActors::NLog::PRI_TRACE) == int(::TLOG_RESOURCES)");
- namespace {
- struct TRecordWithNewline {
- ELogPriority Priority;
- TTempBuf Buf;
- TRecordWithNewline(const TLogRecord& rec)
- : Priority(rec.Priority)
- , Buf(rec.Len + 1)
- {
- Buf.Append(rec.Data, rec.Len);
- *Buf.Proceed(1) = '\n';
- }
- operator TLogRecord() const {
- return TLogRecord(Priority, Buf.Data(), Buf.Filled());
- }
- };
- }
- namespace NActors {
- class TLoggerCounters : public ILoggerMetrics {
- public:
- TLoggerCounters(TIntrusivePtr<NMonitoring::TDynamicCounters> counters)
- : DynamicCounters(counters)
- {
- ActorMsgs_ = DynamicCounters->GetCounter("ActorMsgs", true);
- DirectMsgs_ = DynamicCounters->GetCounter("DirectMsgs", true);
- LevelRequests_ = DynamicCounters->GetCounter("LevelRequests", true);
- IgnoredMsgs_ = DynamicCounters->GetCounter("IgnoredMsgs", true);
- DroppedMsgs_ = DynamicCounters->GetCounter("DroppedMsgs", true);
- AlertMsgs_ = DynamicCounters->GetCounter("AlertMsgs", true);
- EmergMsgs_ = DynamicCounters->GetCounter("EmergMsgs", true);
- }
- ~TLoggerCounters() = default;
- void IncActorMsgs() override {
- ++*ActorMsgs_;
- }
- void IncDirectMsgs() override {
- ++*DirectMsgs_;
- }
- void IncLevelRequests() override {
- ++*LevelRequests_;
- }
- void IncIgnoredMsgs() override {
- ++*IgnoredMsgs_;
- }
- void IncAlertMsgs() override {
- ++*AlertMsgs_;
- }
- void IncEmergMsgs() override {
- ++*EmergMsgs_;
- }
- void IncDroppedMsgs() override {
- DroppedMsgs_->Inc();
- };
- void GetOutputHtml(IOutputStream& str) override {
- HTML(str) {
- DIV_CLASS("row") {
- DIV_CLASS("col-md-12") {
- TAG(TH4) {
- str << "Counters" << Endl;
- }
- DynamicCounters->OutputHtml(str);
- }
- }
- }
- }
- private:
- NMonitoring::TDynamicCounters::TCounterPtr ActorMsgs_;
- NMonitoring::TDynamicCounters::TCounterPtr DirectMsgs_;
- NMonitoring::TDynamicCounters::TCounterPtr LevelRequests_;
- NMonitoring::TDynamicCounters::TCounterPtr IgnoredMsgs_;
- NMonitoring::TDynamicCounters::TCounterPtr AlertMsgs_;
- NMonitoring::TDynamicCounters::TCounterPtr EmergMsgs_;
- // Dropped while the logger backend was unavailable
- NMonitoring::TDynamicCounters::TCounterPtr DroppedMsgs_;
- TIntrusivePtr<NMonitoring::TDynamicCounters> DynamicCounters;
- };
- class TLoggerMetrics : public ILoggerMetrics {
- public:
- TLoggerMetrics(std::shared_ptr<NMonitoring::TMetricRegistry> metrics)
- : Metrics(metrics)
- {
- ActorMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.actor_msgs"}});
- DirectMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.direct_msgs"}});
- LevelRequests_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.level_requests"}});
- IgnoredMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.ignored_msgs"}});
- DroppedMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.dropped_msgs"}});
- AlertMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.alert_msgs"}});
- EmergMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.emerg_msgs"}});
- }
- ~TLoggerMetrics() = default;
- void IncActorMsgs() override {
- ActorMsgs_->Inc();
- }
- void IncDirectMsgs() override {
- DirectMsgs_->Inc();
- }
- void IncLevelRequests() override {
- LevelRequests_->Inc();
- }
- void IncIgnoredMsgs() override {
- IgnoredMsgs_->Inc();
- }
- void IncAlertMsgs() override {
- AlertMsgs_->Inc();
- }
- void IncEmergMsgs() override {
- EmergMsgs_->Inc();
- }
- void IncDroppedMsgs() override {
- DroppedMsgs_->Inc();
- };
- void GetOutputHtml(IOutputStream& str) override {
- HTML(str) {
- DIV_CLASS("row") {
- DIV_CLASS("col-md-12") {
- TAG(TH4) {
- str << "Metrics" << Endl;
- }
- // TODO: Now, TMetricRegistry does not have the GetOutputHtml function
- }
- }
- }
- }
- private:
- NMonitoring::TRate* ActorMsgs_;
- NMonitoring::TRate* DirectMsgs_;
- NMonitoring::TRate* LevelRequests_;
- NMonitoring::TRate* IgnoredMsgs_;
- NMonitoring::TRate* AlertMsgs_;
- NMonitoring::TRate* EmergMsgs_;
- // Dropped while the logger backend was unavailable
- NMonitoring::TRate* DroppedMsgs_;
- std::shared_ptr<NMonitoring::TMetricRegistry> Metrics;
- };
- TAtomic TLoggerActor::IsOverflow = 0;
- TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- TAutoPtr<TLogBackend> logBackend,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters)
- : TActor(&TLoggerActor::StateFunc)
- , Settings(settings)
- , LogBackend(logBackend.Release())
- , Metrics(std::make_unique<TLoggerCounters>(counters))
- {
- }
- TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- std::shared_ptr<TLogBackend> logBackend,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters)
- : TActor(&TLoggerActor::StateFunc)
- , Settings(settings)
- , LogBackend(logBackend)
- , Metrics(std::make_unique<TLoggerCounters>(counters))
- {
- }
- TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- TAutoPtr<TLogBackend> logBackend,
- std::shared_ptr<NMonitoring::TMetricRegistry> metrics)
- : TActor(&TLoggerActor::StateFunc)
- , Settings(settings)
- , LogBackend(logBackend.Release())
- , Metrics(std::make_unique<TLoggerMetrics>(metrics))
- {
- }
- TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- std::shared_ptr<TLogBackend> logBackend,
- std::shared_ptr<NMonitoring::TMetricRegistry> metrics)
- : TActor(&TLoggerActor::StateFunc)
- , Settings(settings)
- , LogBackend(logBackend)
- , Metrics(std::make_unique<TLoggerMetrics>(metrics))
- {
- }
- TLoggerActor::~TLoggerActor() {
- }
- void TLoggerActor::Log(TInstant time, NLog::EPriority priority, NLog::EComponent component, const char* c, ...) {
- Metrics->IncDirectMsgs();
- if (Settings && Settings->Satisfies(priority, component, 0ull)) {
- va_list params;
- va_start(params, c);
- TString formatted;
- vsprintf(formatted, c, params);
- auto ok = OutputRecord(time, NLog::EPrio(priority), component, formatted);
- Y_UNUSED(ok);
- va_end(params);
- }
- }
- void TLoggerActor::Throttle(const NLog::TSettings& settings) {
- if (AtomicGet(IsOverflow))
- Sleep(settings.ThrottleDelay);
- }
- void TLoggerActor::LogIgnoredCount(TInstant now) {
- TString message = Sprintf("Ignored IgnoredCount# %" PRIu64 " log records due to logger overflow!", IgnoredCount);
- if (!OutputRecord(now, NActors::NLog::EPrio::Error, Settings->LoggerComponent, message)) {
- BecomeDefunct();
- }
- }
- void TLoggerActor::HandleIgnoredEvent(TLogIgnored::TPtr& ev, const NActors::TActorContext& ctx) {
- Y_UNUSED(ev);
- LogIgnoredCount(ctx.Now());
- IgnoredCount = 0;
- PassedCount = 0;
- }
- void TLoggerActor::HandleIgnoredEventDrop() {
- // logger backend is unavailable, just ignore
- }
- void TLoggerActor::WriteMessageStat(const NLog::TEvLog& ev) {
- Metrics->IncActorMsgs();
- const auto prio = ev.Level.ToPrio();
- switch (prio) {
- case ::NActors::NLog::EPrio::Alert:
- Metrics->IncAlertMsgs();
- break;
- case ::NActors::NLog::EPrio::Emerg:
- Metrics->IncEmergMsgs();
- break;
- default:
- break;
- }
- }
- void TLoggerActor::HandleLogEvent(NLog::TEvLog::TPtr& ev, const NActors::TActorContext& ctx) {
- i64 delayMillisec = (ctx.Now() - ev->Get()->Stamp).MilliSeconds();
- WriteMessageStat(*ev->Get());
- if (Settings->AllowDrop) {
- // Disable throttling if it was enabled previously
- if (AtomicGet(IsOverflow))
- AtomicSet(IsOverflow, 0);
- // Check if some records have to be dropped
- if ((PassedCount > 10 && delayMillisec > (i64)Settings->TimeThresholdMs) || IgnoredCount > 0) {
- Metrics->IncIgnoredMsgs();
- if (IgnoredCount == 0) {
- ctx.Send(ctx.SelfID, new TLogIgnored());
- }
- ++IgnoredCount;
- PassedCount = 0;
- return;
- }
- PassedCount++;
- } else {
- // Enable of disable throttling depending on the load
- if (delayMillisec > (i64)Settings->TimeThresholdMs && !AtomicGet(IsOverflow))
- AtomicSet(IsOverflow, 1);
- else if (delayMillisec <= (i64)Settings->TimeThresholdMs && AtomicGet(IsOverflow))
- AtomicSet(IsOverflow, 0);
- }
- const auto prio = ev->Get()->Level.ToPrio();
- if (!OutputRecord(ev->Get()->Stamp, prio, ev->Get()->Component, ev->Get()->Line)) {
- BecomeDefunct();
- }
- }
- void TLoggerActor::BecomeDefunct() {
- Become(&TThis::StateDefunct);
- Schedule(WakeupInterval, new TEvents::TEvWakeup);
- }
- void TLoggerActor::HandleLogComponentLevelRequest(TLogComponentLevelRequest::TPtr& ev, const NActors::TActorContext& ctx) {
- Metrics->IncLevelRequests();
- TString explanation;
- int code = Settings->SetLevel(ev->Get()->Priority, ev->Get()->Component, explanation);
- ctx.Send(ev->Sender, new TLogComponentLevelResponse(code, explanation));
- }
- void TLoggerActor::RenderComponentPriorities(IOutputStream& str) {
- using namespace NLog;
- HTML(str) {
- TAG(TH4) {
- str << "Priority Settings for the Components";
- }
- TABLE_SORTABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- str << "Component";
- }
- TABLEH() {
- str << "Level";
- }
- TABLEH() {
- str << "Sampling Level";
- }
- TABLEH() {
- str << "Sampling Rate";
- }
- }
- }
- TABLEBODY() {
- for (EComponent i = Settings->MinVal; i < Settings->MaxVal; i++) {
- auto name = Settings->ComponentName(i);
- if (!*name)
- continue;
- NLog::TComponentSettings componentSettings = Settings->GetComponentSettings(i);
- TABLER() {
- TABLED() {
- str << "<a href='logger?c=" << i << "'>" << name << "</a>";
- }
- TABLED() {
- str << PriorityToString(EPrio(componentSettings.Raw.X.Level));
- }
- TABLED() {
- str << PriorityToString(EPrio(componentSettings.Raw.X.SamplingLevel));
- }
- TABLED() {
- str << componentSettings.Raw.X.SamplingRate;
- }
- }
- }
- }
- }
- }
- }
- /*
- * Logger INFO:
- * 1. Current priority settings from components
- * 2. Number of log messages (via actors events, directly)
- * 3. Number of messages per components, per priority
- * 4. Log level changes (last N changes)
- */
- void TLoggerActor::HandleMonInfo(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
- const auto& params = ev->Get()->Request.GetParams();
- NLog::EComponent component = NLog::InvalidComponent;
- NLog::EPriority priority = NLog::PRI_DEBUG;
- NLog::EPriority samplingPriority = NLog::PRI_DEBUG;
- ui32 samplingRate = 0;
- bool hasComponent = false;
- bool hasPriority = false;
- bool hasSamplingPriority = false;
- bool hasSamplingRate = false;
- bool hasAllowDrop = false;
- int allowDrop = 0;
- if (params.Has("c")) {
- if (TryFromString(params.Get("c"), component) && (component == NLog::InvalidComponent || Settings->IsValidComponent(component))) {
- hasComponent = true;
- if (params.Has("p")) {
- int rawPriority;
- if (TryFromString(params.Get("p"), rawPriority) && NLog::TSettings::IsValidPriority((NLog::EPriority)rawPriority)) {
- priority = (NLog::EPriority)rawPriority;
- hasPriority = true;
- }
- }
- if (params.Has("sp")) {
- int rawPriority;
- if (TryFromString(params.Get("sp"), rawPriority) && NLog::TSettings::IsValidPriority((NLog::EPriority)rawPriority)) {
- samplingPriority = (NLog::EPriority)rawPriority;
- hasSamplingPriority = true;
- }
- }
- if (params.Has("sr")) {
- if (TryFromString(params.Get("sr"), samplingRate)) {
- hasSamplingRate = true;
- }
- }
- }
- }
- if (params.Has("allowdrop")) {
- if (TryFromString(params.Get("allowdrop"), allowDrop)) {
- hasAllowDrop = true;
- }
- }
- TStringStream str;
- if (hasComponent && !hasPriority && !hasSamplingPriority && !hasSamplingRate) {
- NLog::TComponentSettings componentSettings = Settings->GetComponentSettings(component);
- ui32 samplingRate = componentSettings.Raw.X.SamplingRate;
- HTML(str) {
- DIV_CLASS("row") {
- DIV_CLASS("col-md-12") {
- TAG(TH4) {
- str << "Current log settings for " << Settings->ComponentName(component) << Endl;
- }
- UL() {
- LI() {
- str << "Priority: "
- << NLog::PriorityToString(NLog::EPrio(componentSettings.Raw.X.Level));
- }
- LI() {
- str << "Sampling priority: "
- << NLog::PriorityToString(NLog::EPrio(componentSettings.Raw.X.SamplingLevel));
- }
- LI() {
- str << "Sampling rate: "
- << samplingRate;
- }
- }
- }
- }
- DIV_CLASS("row") {
- DIV_CLASS("col-md-12") {
- TAG(TH4) {
- str << "Change priority" << Endl;
- }
- UL() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
- LI() {
- str << "<a href='logger?c=" << component << "&p=" << p << "'>"
- << NLog::PriorityToString(NLog::EPrio(p)) << "</a>";
- }
- }
- }
- TAG(TH4) {
- str << "Change sampling priority" << Endl;
- }
- UL() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
- LI() {
- str << "<a href='logger?c=" << component << "&sp=" << p << "'>"
- << NLog::PriorityToString(NLog::EPrio(p)) << "</a>";
- }
- }
- }
- TAG(TH4) {
- str << "Change sampling rate" << Endl;
- }
- str << "<form method=\"GET\">" << Endl;
- str << "Rate: <input type=\"number\" name=\"sr\" value=\"" << samplingRate << "\"/>" << Endl;
- str << "<input type=\"hidden\" name=\"c\" value=\"" << component << "\">" << Endl;
- str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"Change\"/>" << Endl;
- str << "</form>" << Endl;
- TAG(TH4) {
- str << "<a href='logger'>Cancel</a>" << Endl;
- }
- }
- }
- }
- } else {
- TString explanation;
- if (hasComponent && hasPriority) {
- Settings->SetLevel(priority, component, explanation);
- }
- if (hasComponent && hasSamplingPriority) {
- Settings->SetSamplingLevel(samplingPriority, component, explanation);
- }
- if (hasComponent && hasSamplingRate) {
- Settings->SetSamplingRate(samplingRate, component, explanation);
- }
- if (hasAllowDrop) {
- Settings->SetAllowDrop(allowDrop);
- }
- HTML(str) {
- if (!explanation.empty()) {
- DIV_CLASS("row") {
- DIV_CLASS("col-md-12 alert alert-info") {
- str << explanation;
- }
- }
- }
- DIV_CLASS("row") {
- DIV_CLASS("col-md-6") {
- RenderComponentPriorities(str);
- }
- DIV_CLASS("col-md-6") {
- TAG(TH4) {
- str << "Change priority for all components";
- }
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- str << "Priority";
- }
- }
- }
- TABLEBODY() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
- TABLER() {
- TABLED() {
- str << "<a href = 'logger?c=-1&p=" << p << "'>"
- << NLog::PriorityToString(NLog::EPrio(p)) << "</a>";
- }
- }
- }
- }
- }
- TAG(TH4) {
- str << "Change sampling priority for all components";
- }
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- str << "Priority";
- }
- }
- }
- TABLEBODY() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
- TABLER() {
- TABLED() {
- str << "<a href = 'logger?c=-1&sp=" << p << "'>"
- << NLog::PriorityToString(NLog::EPrio(p)) << "</a>";
- }
- }
- }
- }
- }
- TAG(TH4) {
- str << "Change sampling rate for all components";
- }
- str << "<form method=\"GET\">" << Endl;
- str << "Rate: <input type=\"number\" name=\"sr\" value=\"0\"/>" << Endl;
- str << "<input type=\"hidden\" name=\"c\" value=\"-1\">" << Endl;
- str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"Change\"/>" << Endl;
- str << "</form>" << Endl;
- TAG(TH4) {
- str << "Drop log entries in case of overflow: "
- << (Settings->AllowDrop ? "Enabled" : "Disabled");
- }
- str << "<form method=\"GET\">" << Endl;
- str << "<input type=\"hidden\" name=\"allowdrop\" value=\"" << (Settings->AllowDrop ? "0" : "1") << "\"/>" << Endl;
- str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"" << (Settings->AllowDrop ? "Disable" : "Enable") << "\"/>" << Endl;
- str << "</form>" << Endl;
- }
- }
- Metrics->GetOutputHtml(str);
- }
- }
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str()));
- }
- constexpr size_t TimeBufSize = 512;
- bool TLoggerActor::OutputRecord(TInstant time, NLog::EPrio priority, NLog::EComponent component,
- const TString& formatted) noexcept try {
- const auto logPrio = ::ELogPriority(ui16(priority));
- char buf[TimeBufSize];
- switch (Settings->Format) {
- case NActors::NLog::TSettings::PLAIN_FULL_FORMAT: {
- TStringBuilder logRecord;
- if (Settings->UseLocalTimestamps) {
- logRecord << FormatLocalTimestamp(time, buf);
- } else {
- logRecord << time;
- }
- logRecord
- << Settings->MessagePrefix
- << " :" << Settings->ComponentName(component)
- << " " << PriorityToString(priority)
- << ": " << formatted;
- LogBackend->WriteData(
- TLogRecord(logPrio, logRecord.data(), logRecord.size()));
- } break;
- case NActors::NLog::TSettings::PLAIN_SHORT_FORMAT: {
- TStringBuilder logRecord;
- logRecord
- << Settings->ComponentName(component)
- << ": " << formatted;
- LogBackend->WriteData(
- TLogRecord(logPrio, logRecord.data(), logRecord.size()));
- } break;
- case NActors::NLog::TSettings::JSON_FORMAT: {
- NJsonWriter::TBuf json;
- json.BeginObject()
- .WriteKey("@timestamp")
- .WriteString(Settings->UseLocalTimestamps ? FormatLocalTimestamp(time, buf) : time.ToString().data())
- .WriteKey("microseconds")
- .WriteULongLong(time.MicroSeconds())
- .WriteKey("host")
- .WriteString(Settings->ShortHostName)
- .WriteKey("cluster")
- .WriteString(Settings->ClusterName)
- .WriteKey("priority")
- .WriteString(PriorityToString(priority))
- .WriteKey("npriority")
- .WriteInt((int)priority)
- .WriteKey("component")
- .WriteString(Settings->ComponentName(component))
- .WriteKey("tag")
- .WriteString("KIKIMR")
- .WriteKey("revision")
- .WriteInt(GetProgramSvnRevision())
- .WriteKey("message")
- .WriteString(formatted)
- .EndObject();
- auto logRecord = json.Str();
- LogBackend->WriteData(
- TLogRecord(logPrio, logRecord.data(), logRecord.size()));
- } break;
- }
- return true;
- } catch (...) {
- return false;
- }
- void TLoggerActor::HandleLogEventDrop(const NLog::TEvLog::TPtr& ev) {
- WriteMessageStat(*ev->Get());
- Metrics->IncDroppedMsgs();
- }
- void TLoggerActor::HandleWakeup() {
- Become(&TThis::StateFunc);
- }
- const char* TLoggerActor::FormatLocalTimestamp(TInstant time, char* buf) {
- struct tm localTime;
- time.LocalTime(&localTime);
- int r = strftime(buf, TimeBufSize, "%Y-%m-%d-%H-%M-%S", &localTime);
- Y_VERIFY(r != 0);
- return buf;
- }
- TAutoPtr<TLogBackend> CreateSysLogBackend(const TString& ident,
- bool logPError, bool logCons) {
- int flags = 0;
- if (logPError)
- flags |= TSysLogBackend::LogPerror;
- if (logCons)
- flags |= TSysLogBackend::LogCons;
- return new TSysLogBackend(ident.data(), TSysLogBackend::TSYSLOG_LOCAL1, flags);
- }
- class TStderrBackend: public TLogBackend {
- public:
- TStderrBackend() {
- }
- void WriteData(const TLogRecord& rec) override {
- #ifdef _MSC_VER
- if (IsDebuggerPresent()) {
- TString x;
- x.reserve(rec.Len + 2);
- x.append(rec.Data, rec.Len);
- x.append('\n');
- OutputDebugString(x.c_str());
- }
- #endif
- bool isOk = false;
- do {
- try {
- TRecordWithNewline r(rec);
- Cerr.Write(r.Buf.Data(), r.Buf.Filled());
- isOk = true;
- } catch (TSystemError err) {
- // Interrupted system call
- Y_UNUSED(err);
- }
- } while (!isOk);
- }
- void ReopenLog() override {
- }
- private:
- const TString Indent;
- };
- class TLineFileLogBackend: public TFileLogBackend {
- public:
- TLineFileLogBackend(const TString& path)
- : TFileLogBackend(path)
- {
- }
- // Append newline after every record
- void WriteData(const TLogRecord& rec) override {
- TFileLogBackend::WriteData(TRecordWithNewline(rec));
- }
- };
- class TCompositeLogBackend: public TLogBackend {
- public:
- TCompositeLogBackend(TVector<TAutoPtr<TLogBackend>>&& underlyingBackends)
- : UnderlyingBackends(std::move(underlyingBackends))
- {
- }
- void WriteData(const TLogRecord& rec) override {
- for (auto& b: UnderlyingBackends) {
- b->WriteData(rec);
- }
- }
- void ReopenLog() override {
- }
- private:
- TVector<TAutoPtr<TLogBackend>> UnderlyingBackends;
- };
- TAutoPtr<TLogBackend> CreateStderrBackend() {
- return new TStderrBackend();
- }
- TAutoPtr<TLogBackend> CreateFileBackend(const TString& fileName) {
- return new TLineFileLogBackend(fileName);
- }
- TAutoPtr<TLogBackend> CreateNullBackend() {
- return new TNullLogBackend();
- }
- TAutoPtr<TLogBackend> CreateCompositeLogBackend(TVector<TAutoPtr<TLogBackend>>&& underlyingBackends) {
- return new TCompositeLogBackend(std::move(underlyingBackends));
- }
- }
|