#include "backend.h" #include <library/cpp/unified_agent_client/enum.h> #include <library/cpp/logger/record.h> #include <util/datetime/base.h> #include <util/generic/guid.h> #include <util/generic/serialized_enum.h> namespace NUnifiedAgent { namespace { class TDefaultRecordConverter : public IRecordConverter { public: TDefaultRecordConverter(bool stripTrailingNewLine) : StripTrailingNewLine(stripTrailingNewLine) , PriorityKey("_priority") { } TClientMessage Convert(const TLogRecord& rec) const override { const auto stripTrailingNewLine = StripTrailingNewLine && rec.Len > 0 && rec.Data[rec.Len - 1] == '\n'; THashMap<TString, TString> metaFlags{{PriorityKey, NameOf(rec.Priority)}}; metaFlags.insert(rec.MetaFlags.begin(), rec.MetaFlags.end()); return { TString(rec.Data, stripTrailingNewLine ? rec.Len - 1 : rec.Len), std::move(metaFlags) }; } private: const bool StripTrailingNewLine; const TString PriorityKey; }; class TClientSessionAdapter: public TLogBackend { public: explicit TClientSessionAdapter(const TClientSessionPtr& session, THolder<IRecordConverter> recordConverter) : Session(session) , RecordConverter(std::move(recordConverter)) { } void WriteData(const TLogRecord& rec) override { Session->Send(RecordConverter->Convert(rec)); } void ReopenLog() override { } private: TClientSessionPtr Session; THolder<IRecordConverter> RecordConverter; }; class TSessionHolder { protected: TSessionHolder(const TClientParameters& parameters, const TSessionParameters& sessionParameters) : Client(MakeClient(parameters)) , Session(Client->CreateSession(sessionParameters)) { } protected: TClientPtr Client; TClientSessionPtr Session; }; class TAgentLogBackend: private TSessionHolder, public TClientSessionAdapter { public: TAgentLogBackend(const TClientParameters& parameters, const TSessionParameters& sessionParameters, THolder<IRecordConverter> recordConverter) : TSessionHolder(parameters, sessionParameters) , TClientSessionAdapter(TSessionHolder::Session, std::move(recordConverter)) { } ~TAgentLogBackend() override { TSessionHolder::Session->Close(); } }; } THolder<IRecordConverter> MakeDefaultRecordConverter(bool stripTrailingNewLine) { return MakeHolder<TDefaultRecordConverter>(stripTrailingNewLine); } THolder<TLogBackend> AsLogBackend(const TClientSessionPtr& session, bool stripTrailingNewLine) { return MakeHolder<TClientSessionAdapter>(session, MakeDefaultRecordConverter(stripTrailingNewLine)); } THolder<TLogBackend> MakeLogBackend(const TClientParameters& parameters, const TSessionParameters& sessionParameters, THolder<IRecordConverter> recordConverter) { if (!recordConverter) { recordConverter = MakeDefaultRecordConverter(); } return MakeHolder<TAgentLogBackend>(parameters, sessionParameters, std::move(recordConverter)); } THolder<::TLog> MakeLog(const TClientParameters& parameters, const TSessionParameters& sessionParameters, THolder<IRecordConverter> recordConverter) { return MakeHolder<::TLog>(MakeLogBackend(parameters, sessionParameters, std::move(recordConverter))); } }