aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/unified_agent_client/backend.cpp
blob: b3c4b4ebcfc253b7a4eca77888f9395132e4f5d3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#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)));
    }
}