aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/providers/common/udf_resolve/yql_udf_resolver_logger.cpp
blob: 5993074c6c51cd1519d6729dbed16462376d63b9 (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
#include "yql_udf_resolver_logger.h"

#include <yql/essentials/core/yql_user_data_storage.h>

#include <util/stream/file.h>
#include <util/string/builder.h>
#include <util/datetime/cputimer.h>

namespace {
using namespace NYql;

class TUdfResolverWithLoggerDecorator : public IUdfResolver {
public:
    TUdfResolverWithLoggerDecorator(const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry,
                        IUdfResolver::TPtr underlying, const TString& path, const TString& sessionId)
        : FunctionRegistry_(functionRegistry)
        , Underlying_(underlying)
        , Out_(TFile(path, WrOnly | ForAppend | OpenAlways))
        , SessionId_(sessionId) {}

    TMaybe<TFilePathWithMd5> GetSystemModulePath(const TStringBuf& moduleName) const override {
        return Underlying_->GetSystemModulePath(moduleName);
    }

    void LogImport(TStringBuilder& sb, const TImport& import) const {
        sb << " ";
        switch (import.Block->Type) {
        case NYql::EUserDataType::PATH:             sb << "PATH"; break;
        case NYql::EUserDataType::URL:              sb << "URL"; break;
        case NYql::EUserDataType::RAW_INLINE_DATA:  sb << "RAW_INLINE_DATA"; break;
        };
        sb << ":" << import.FileAlias << ":";
        bool isTrusted = false;
        if (import.Modules) {
            bool was = false;
            for (auto& e: *import.Modules) {
                sb << (was ? "," : "") << e;
                isTrusted |= FunctionRegistry_->IsLoadedUdfModule(e);
                was = true;
            }
        }
        sb << ":" << isTrusted << ":";
        auto frozen = import.Block->FrozenFile;
        Y_ENSURE(frozen);
        sb << frozen->GetMd5() << ":" << frozen->GetSize();
    }

    bool LoadMetadata(
        const TVector<TImport*>& imports, const TVector<TFunction*>& functions,
        TExprContext& ctx, NUdf::ELogLevel logLevel, THoldingFileStorage& storage) const override
    {
        TSimpleTimer t;
        auto result = Underlying_->LoadMetadata(imports, functions, ctx, logLevel, storage);
        auto runningTime = t.Get().MilliSeconds();
        if (imports.empty()) {
            return result;
        }

        TStringBuilder sb;
        sb << TInstant::Now() << " " << SessionId_ << " LoadMetadata with imports (";
        for (auto& e: imports) {
            if (!e || !e->Block) {
                continue;
            }
            LogImport(sb, *e);
        }
        sb << ") took " << runningTime << " ms\n";
        Out_ << TString(sb);
        return result;
    }

    TResolveResult LoadRichMetadata(const TVector<TImport>& imports, NUdf::ELogLevel logLevel, THoldingFileStorage& storage) const override {
        TSimpleTimer t;
        auto result = Underlying_->LoadRichMetadata(imports, logLevel, storage);
        auto runningTime = t.Get().MilliSeconds();
        if (imports.empty()) {
            return result;
        }

        TStringBuilder sb;
        sb << TInstant::Now() << " " << SessionId_ << " LoadRichMetadata with imports (";
        for (auto& e: imports) {
            if (!e.Block) {
                continue;
            }
            LogImport(sb, e);
        }
        sb << ") took " << runningTime << " ms\n";
        Out_ << TString(sb);
        return result;
    }

    bool ContainsModule(const TStringBuf& moduleName) const override {
        return Underlying_->ContainsModule(moduleName);
    }
private:
    const NKikimr::NMiniKQL::IFunctionRegistry* FunctionRegistry_;
    IUdfResolver::TPtr Underlying_;
    mutable TUnbufferedFileOutput Out_;
    TString SessionId_;
};

}

namespace NYql::NCommon {
IUdfResolver::TPtr CreateUdfResolverDecoratorWithLogger(const NKikimr::NMiniKQL::IFunctionRegistry* functionRegistry, IUdfResolver::TPtr underlying, const TString& path, const TString& sessionId) {
    return new TUdfResolverWithLoggerDecorator(functionRegistry, underlying, path, sessionId);
}
}