aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/lwtrace/example3/my_action.h
blob: 80a34ecca83d2d923ce1982875903edd88cae8bd (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
#pragma once 
 
#include <library/cpp/lwtrace/all.h>
#include <util/stream/file.h> 
 
// Example of custom state for custom executors 
// Holds file for output from TMyActionExecutor 
class TMyFile: public NLWTrace::IResource { 
private: 
    TMutex Mutex; 
    THolder<TUnbufferedFileOutput> File;
 
public: 
    // Note that this class must have default ctor (it's declared here just for clearness) 
    TMyFile() { 
    } 
 
    // Note that dtor will be called by TManager::Delete() after detachment and destruction of all executors 
    ~TMyFile() { 
    } 
 
    // Some kind of state initialization 
    // Can be called only from executor constructor, and should not be thread-safe 
    void Open(const TString& path) { 
        if (File) { 
            // We must avoid double open because each executor will call Open() on the same object 
            // if the same file was specified in Opts 
            return; 
        } 
        File.Reset(new TUnbufferedFileOutput(path));
    } 
 
    // Outputs a line to opened file 
    // Can be called from DoExecute() and must be thread-safe 
    void Output(const TString& line) { 
        Y_VERIFY(File); 
        TGuard<TMutex> g(Mutex); // Because DoExecute() call can come from any thread 
        *File << line << Endl; 
    } 
}; 
 
// Action that prints events to specified file 
class TMyActionExecutor: public NLWTrace::TCustomActionExecutor { 
private: 
    TMyFile& File; 
 
public: 
    TMyActionExecutor(NLWTrace::TProbe* probe, const NLWTrace::TCustomAction& action, NLWTrace::TSession* session) 
        : NLWTrace::TCustomActionExecutor(probe, false /* not destructive */) 
        , File(session->Resources().Get<TMyFile>("FileHolder/" + action.GetOpts(0))) // unique state id must include your d 
    { 
        if (action.GetOpts().size() != 1) { 
            yexception() << "wrong number of Opts in MyAction"; 
        } 
        File.Open(action.GetOpts(0)); 
    } 
 
    static const char* GetActionName() { 
        static const char name[] = "MyAction"; 
        return name; 
    } 
 
private: 
    virtual bool DoExecute(NLWTrace::TOrbit&, const NLWTrace::TParams& params) { 
        // Serialize param values to strings 
        TString paramValues[LWTRACE_MAX_PARAMS];
        Probe->Event.Signature.SerializeParams(params, paramValues); 
 
        // Generate output line 
        TStringStream ss; 
        ss << "TMyActionExecutor>>> "; 
        ss << Probe->Event.Name; 
        for (ui32 i = 0; i < Probe->Event.Signature.ParamCount; ++i) { 
            ss << " " << Probe->Event.Signature.ParamNames[i] << "=" << paramValues[i]; 
        } 
 
        // Write line to file 
        File.Output(ss.Str()); 
 
        // Executors can chain if you specify multiple actions in one block (in trace query). 
        // So return true to continue execution of actions for given trace query block (on current triggered event) 
        // or return false if this action is the last for this block 
        return true; 
    } 
};