blob: 20fdae8dd29a674ed52ba8fc17f7fbc6a68399a8 (
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;
}
};
|