-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathgrpc_agent.h
More file actions
389 lines (275 loc) · 10.4 KB
/
Copy pathgrpc_agent.h
File metadata and controls
389 lines (275 loc) · 10.4 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
#ifndef AGENTS_GRPC_SRC_GRPC_AGENT_H_
#define AGENTS_GRPC_SRC_GRPC_AGENT_H_
#include <nsolid.h>
#include <nsolid/async_ts_queue.h>
#include <nsolid/thread_safe.h>
#include <memory>
#include "grpcpp/grpcpp.h"
#include "./proto/nsolid_service.grpc.pb.h"
#include "opentelemetry/version.h"
#include "opentelemetry/sdk/trace/recordable.h"
#include "../../src/profile_collector.h"
#include "asset_stream.h"
#include "command_stream.h"
#include "grpc_client.h"
#include "grpc_errors.h"
// Class pre-declaration
OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter {
namespace otlp {
class OtlpGrpcExporter;
class OtlpGrpcLogRecordExporter;
class OtlpGrpcMetricExporter;
}
}
namespace sdk {
namespace trace {
class Recordable;
}
}
OPENTELEMETRY_END_NAMESPACE
namespace node {
namespace nsolid {
class SpanCollector;
namespace grpc {
// predeclarations
struct AssetStor;
class AssetStream;
class CommandStream;
class GrpcAgent;
using UniqRecordable =
std::unique_ptr<OPENTELEMETRY_NAMESPACE::sdk::trace::Recordable>;
using UniqRecordables = std::vector<UniqRecordable>;
using SharedGrpcAgent = std::shared_ptr<GrpcAgent>;
using WeakGrpcAgent = std::weak_ptr<GrpcAgent>;
struct JSThreadMetrics {
explicit JSThreadMetrics(SharedEnvInst envinst);
SharedThreadMetrics metrics_;
};
class GrpcAgent: public std::enable_shared_from_this<GrpcAgent>,
public AssetStreamObserver,
public CommandStreamObserver {
public:
struct LogInfoStor {
uint64_t thread_id;
LogWriteInfo info;
};
struct BlockedLoopStor {
bool blocked;
std::string body;
uint64_t thread_id;
};
static SharedGrpcAgent Inst();
virtual void on_asset_stream_done(const ::grpc::Status&, AssetStor&& stor);
virtual void on_command_received(grpcagent::CommandRequest&&);
virtual void on_command_stream_done(const ::grpc::Status&);
void reset_command_stream();
void set_asset_cb(SharedEnvInst envinst,
const v8::Local<v8::Function>& cb);
int start();
int start_cpu_profile(const grpcagent::CommandRequest& req);
int start_cpu_profile_from_js(const grpcagent::CommandRequest& req);
int start_heap_profile(const grpcagent::CommandRequest& req);
int start_heap_profile_from_js(const grpcagent::CommandRequest& req);
int start_heap_sampling(const grpcagent::CommandRequest& req);
int start_heap_sampling_from_js(const grpcagent::CommandRequest& req);
int start_heap_snapshot(const grpcagent::CommandRequest& req);
int start_heap_snapshot_from_js(const grpcagent::CommandRequest& req);
int stop(bool profile_stopped = false);
const std::string& agent_id() const { return agent_id_; }
const std::string& saas() const {
static std::string empty;
return saas_ ? saas_->token : empty;
}
private:
struct CommandRequestStor {
grpcagent::CommandRequest request;
};
struct ProfileStor {
std::string req_id;
AssetStream* stream;
ProfileOptions options;
bool done = false;
};
using StartProfiling = ErrorType (GrpcAgent::*)(
const grpcagent::ProfileArgs&,
ProfileOptions& opts); // NOLINT(runtime/references)
using ProfileStorMap = std::map<uint64_t, ProfileStor>;
struct ProfileState {
ProfileStorMap pending_profiles_map;
std::atomic<unsigned int> nr_profiles = 0;
std::string last_main_profile;
};
struct StartProfStor {
ErrorType err;
std::string req_id;
ProfileType type;
ProfileOptions options;
};
struct SaaSInfo {
std::string token;
std::string endpoint;
bool testing;
};
GrpcAgent();
~GrpcAgent();
static void run_(nsuv::ns_thread*, WeakGrpcAgent);
static void asset_done_msg_cb_(nsuv::ns_async*, WeakGrpcAgent);
static void at_exit_cb_(bool on_signal, bool profile_stopped, WeakGrpcAgent);
static void command_msg_cb_(nsuv::ns_async*, WeakGrpcAgent);
static void command_stream_done_msg_cb_(nsuv::ns_async*, WeakGrpcAgent);
static void config_agent_cb_(std::string, WeakGrpcAgent);
static void config_msg_cb_(nsuv::ns_async*, WeakGrpcAgent);
static void cont_profiler_cb(const ProfileCollector::ProfileQStor&,
WeakGrpcAgent);
static void env_creation_cb_(SharedEnvInst, WeakGrpcAgent);
static void env_deletion_cb_(SharedEnvInst, WeakGrpcAgent);
static void env_msg_cb_(nsuv::ns_async*, WeakGrpcAgent);
static void log_cb_(SharedEnvInst, LogWriteInfo, WeakGrpcAgent);
static void log_msg_cb_(nsuv::ns_async*, WeakGrpcAgent);
static void loop_blocked_(SharedEnvInst, std::string, WeakGrpcAgent);
static void loop_unblocked_(SharedEnvInst, std::string, WeakGrpcAgent);
static void metrics_msg_cb_(nsuv::ns_async*, WeakGrpcAgent);
static void metrics_timer_cb_(nsuv::ns_timer*, WeakGrpcAgent);
static void profile_msg_cb_(nsuv::ns_async*, WeakGrpcAgent);
static void shutdown_cb_(nsuv::ns_async*, WeakGrpcAgent);
static void span_msg_cb_(nsuv::ns_async*, WeakGrpcAgent);
static void start_profiling_msg_cb(nsuv::ns_async*, WeakGrpcAgent);
static void thr_metrics_cb_(SharedThreadMetrics, WeakGrpcAgent);
static void trace_hook_(Tracer*, const Tracer::SpanStor&, WeakGrpcAgent);
void check_exit_on_profile();
void command_stream_closed(const ::grpc::Status& s);
int config(const nlohmann::json& config);
void do_start();
void do_stop();
ErrorType do_start_prof_init(
const grpcagent::CommandRequest& req,
const ProfileType& type,
ProfileOptions& options); // NOLINT(runtime/references)
// ErrorType do_start_prof(const grpcagent::CommandRequest& req,
// const ProfileType& type);
ErrorType do_start_prof_end(
ErrorType err,
const std::string& req_id,
const ProfileType& type,
ProfileOptions&& opts); // NOLINT(runtime/references)
ErrorType do_start_cpu_prof(
const grpcagent::ProfileArgs&,
ProfileOptions& opts); // NOLINT(runtime/references)
ErrorType do_start_heap_prof(
const grpcagent::ProfileArgs& args,
ProfileOptions& opts); // NOLINT(runtime/references)
ErrorType do_start_heap_sampl(
const grpcagent::ProfileArgs& args,
ProfileOptions& opts); // NOLINT(runtime/references)
ErrorType do_start_heap_snapshot(
const grpcagent::ProfileArgs& args,
ProfileOptions& opts); // NOLINT(runtime/references)
void got_asset_done_msg();
void got_blocked_loop(BlockedLoopStor&& stor);
void got_logs();
void got_proc_metrics();
void got_profile(const ProfileCollector::ProfileQStor& stor);
void got_continuous_profile(const ProfileCollector::ProfileQStor& stor);
void got_spans(const UniqRecordables& spans);
void handle_command_request(CommandRequestStor&& req);
void parse_saas_token(const std::string& token);
bool pending_profiles() const;
void reconfigure(const grpcagent::CommandRequest& config);
void send_asset_error(const ProfileType& type,
const std::string& req_id,
ProfileOptions&& options,
AssetStream* stream,
const ErrorType& error);
void send_blocked_loop_event(BlockedLoopStor&& stor);
void send_exit();
void send_info_event(const char* req_id = nullptr);
void send_metrics_event(const char* req_id);
void send_packages_event(const char* req_id = nullptr);
void send_reconfigure_event(const char* req_id);
void send_source_code_event(const grpcagent::CommandRequest& req);
void send_startup_times_event(const char* req_id);
void send_unblocked_loop_event(BlockedLoopStor&& stor);
void setup_blocked_loop_hooks();
int setup_metrics_timer(uint64_t period);
void update_tracer(uint32_t flags);
private:
uv_loop_t loop_;
nsuv::ns_thread thread_;
nsuv::ns_async shutdown_;
// For thread start/stop synchronization
bool hooks_init_;
std::atomic<bool> ready_;
uv_cond_t start_cond_;
uv_mutex_t start_lock_;
uv_cond_t stop_cond_;
uv_mutex_t stop_lock_;
std::atomic<bool> exiting_;
nsuv::ns_async env_msg_;
TSQueue<std::tuple<SharedEnvInst, bool>> env_msg_q_;
// Blocked Loop
std::shared_ptr<AsyncTSQueue<BlockedLoopStor>> blocked_loop_queue_;
// For the Tracing API
uint32_t trace_flags_;
std::shared_ptr<SpanCollector> span_collector_;
std::unique_ptr<opentelemetry::v1::exporter::otlp::OtlpGrpcExporter>
trace_exporter_;
std::vector<std::unique_ptr<opentelemetry::sdk::trace::Recordable>>
recordables_;
// For the Metrics API
uint64_t metrics_interval_;
ProcessMetrics proc_metrics_;
ProcessMetrics::MetricsStor proc_prev_stor_;
std::map<uint64_t, JSThreadMetrics> env_metrics_map_;
nsuv::ns_async metrics_msg_;
TSQueue<ThreadMetrics::MetricsStor> thr_metrics_msg_q_;
nsuv::ns_timer metrics_timer_;
std::unique_ptr<opentelemetry::v1::exporter::otlp::OtlpGrpcMetricExporter>
metrics_exporter_;
std::map<uint64_t, ThreadMetrics::MetricsStor> thr_metrics_cache_;
// For the Configuration API
nsuv::ns_async config_msg_;
TSQueue<nlohmann::json> config_msg_q_;
nlohmann::json config_;
std::string agent_id_;
std::unique_ptr<SaaSInfo> saas_;
nsuv::ns_timer auth_timer_;
int auth_retries_;
bool unauthorized_;
// For the Logging API
nsuv::ns_async log_msg_;
TSQueue<LogInfoStor> log_msg_q_;
std::unique_ptr<opentelemetry::v1::exporter::otlp::OtlpGrpcLogRecordExporter>
log_exporter_;
// Profiling
std::atomic<bool> assets_enabled_;
std::atomic<bool> cont_cpu_profile_enabled_;
nsuv::ns_mutex profile_state_lock_;
ProfileState profile_state_[ProfileType::kNumberOfProfileTypes];
std::atomic<bool> profile_on_exit_;
std::shared_ptr<ProfileCollector> profile_collector_;
nsuv::ns_async start_profiling_msg_;
TSQueue<StartProfStor> start_profiling_msg_q_;
// Continuous Profiling
ProfileStorMap cont_profile_stor_map_;
std::shared_ptr<AsyncTSQueue<ProfileCollector::ProfileQStor>>
cont_profile_queue_;
// For the grpc client
std::unique_ptr<grpcagent::NSolidService::StubInterface> nsolid_service_stub_;
std::unique_ptr<CommandStream> command_stream_;
std::string cacert_;
std::string custom_certs_;
// For the gRPC server
nsuv::ns_async command_msg_;
TSQueue<CommandRequestStor> command_q_;
nsuv::ns_async command_stream_done_msg_;
TSQueue<::grpc::Status> command_stream_done_q_;
nsuv::ns_async asset_done_msg_;
TSQueue<AssetStor> asset_done_q_;
// For the Assets JS API
std::map<SharedEnvInst, v8::Global<v8::Function>> asset_cb_map_;
};
} // namespace grpc
} // namespace nsolid
} // namespace node
#endif // AGENTS_GRPC_SRC_GRPC_AGENT_H_