hyperprobe-agent 1.2.27.pre.3-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +13 -0
- data/README.md +386 -0
- data/lib/hyperprobe/agent.rb +537 -0
- data/lib/hyperprobe/core/broker.rb +183 -0
- data/lib/hyperprobe/core/evaluator.rb +418 -0
- data/lib/hyperprobe/core/lexical_scope.rb +222 -0
- data/lib/hyperprobe/core/logger.rb +198 -0
- data/lib/hyperprobe/core/monitoring_engine.rb +857 -0
- data/lib/hyperprobe/core/quota.rb +111 -0
- data/lib/hyperprobe/core/safe_ast_validator.rb +170 -0
- data/lib/hyperprobe/core/safety.rb +256 -0
- data/lib/hyperprobe/core/serializer.rb +437 -0
- data/lib/hyperprobe/core/trace_extractor.rb +158 -0
- data/lib/hyperprobe/core/transports/java_grpc.rb +57 -0
- data/lib/hyperprobe/jars/hyperprobe-grpc.jar +0 -0
- data/lib/hyperprobe/lambda.rb +92 -0
- data/lib/hyperprobe/protos/agent_descriptor.rb +7 -0
- data/lib/hyperprobe/protos/agent_pb.rb +33 -0
- data/lib/hyperprobe/protos/agent_services_pb.rb +31 -0
- data/lib/hyperprobe/protos/java_messages.rb +199 -0
- data/lib/hyperprobe/protos.rb +14 -0
- data/lib/hyperprobe/railtie.rb +22 -0
- data/lib/hyperprobe/version.rb +5 -0
- data/lib/hyperprobe-agent.rb +3 -0
- data/lib/hyperprobe.rb +282 -0
- data/transport/README.md +98 -0
- data/transport/THIRD_PARTY_NOTICES.md +57 -0
- data/transport/pom.xml +78 -0
- data/transport/src/main/java/co/hyperprobe/transport/GrpcTransport.java +118 -0
- data/transport/src/main/java/co/hyperprobe/transport/ProtoCodec.java +43 -0
- metadata +117 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HyperProbe
|
|
4
|
+
module Lambda
|
|
5
|
+
class << self
|
|
6
|
+
def wrap(options = {}, &handler)
|
|
7
|
+
is_aws_lambda = !ENV['AWS_LAMBDA_FUNCTION_NAME'].nil?
|
|
8
|
+
is_local_emulator = ENV['IS_OFFLINE'] == 'true' || ENV['AWS_SAM_LOCAL'] == 'true'
|
|
9
|
+
is_ephemeral = (options[:is_lambda] || is_aws_lambda) && !is_local_emulator
|
|
10
|
+
|
|
11
|
+
# If running locally in emulator, standard background agent mode
|
|
12
|
+
unless is_ephemeral
|
|
13
|
+
HyperProbe.start(options)
|
|
14
|
+
return handler
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Ephemeral Lambda wrapper
|
|
18
|
+
lambda do |event:, context:|
|
|
19
|
+
agent = nil
|
|
20
|
+
begin
|
|
21
|
+
HyperProbe.start(options.merge(is_lambda: true)) unless HyperProbe.instance
|
|
22
|
+
agent = HyperProbe.instance
|
|
23
|
+
agent = nil if agent && agent.agent_disabled?
|
|
24
|
+
if agent
|
|
25
|
+
remaining_ms = context.respond_to?(:get_remaining_time_in_millis) ? context.get_remaining_time_in_millis : nil
|
|
26
|
+
sync_timeout_ms = options[:lambda_sync_timeout_ms] || 2000
|
|
27
|
+
if remaining_ms
|
|
28
|
+
dynamic_budget = (remaining_ms * 0.2).to_i
|
|
29
|
+
sync_timeout_ms = dynamic_budget < 100 ? 0 : [sync_timeout_ms, dynamic_budget].min
|
|
30
|
+
end
|
|
31
|
+
agent.force_sync(sync_timeout_ms / 1000.0) if sync_timeout_ms.positive?
|
|
32
|
+
end
|
|
33
|
+
rescue SignalException, SystemExit
|
|
34
|
+
raise
|
|
35
|
+
rescue Exception
|
|
36
|
+
# This boundary never encloses application handler execution.
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
begin
|
|
40
|
+
params = handler.parameters
|
|
41
|
+
has_keywords = params.any? { |type, _| type == :keyreq || type == :key || type == :keyrest }
|
|
42
|
+
|
|
43
|
+
if has_keywords
|
|
44
|
+
handler.call(event: event, context: context)
|
|
45
|
+
elsif params.length == 1 && (params.first[0] == :req || params.first[0] == :opt)
|
|
46
|
+
handler.call(event)
|
|
47
|
+
else
|
|
48
|
+
handler.call(event, context)
|
|
49
|
+
end
|
|
50
|
+
ensure
|
|
51
|
+
begin
|
|
52
|
+
if agent
|
|
53
|
+
remaining_ms = context.respond_to?(:get_remaining_time_in_millis) ? context.get_remaining_time_in_millis : nil
|
|
54
|
+
flush_timeout_ms = options[:flush_timeout_ms] || 1500
|
|
55
|
+
if remaining_ms.nil? || remaining_ms > 500
|
|
56
|
+
flush_timeout_ms = [remaining_ms - 200, flush_timeout_ms].min if remaining_ms
|
|
57
|
+
agent.force_flush(flush_timeout_ms / 1000.0)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
rescue SignalException, SystemExit
|
|
61
|
+
raise
|
|
62
|
+
rescue Exception
|
|
63
|
+
# Never mask a handler exception with instrumentation cleanup.
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
rescue SignalException, SystemExit
|
|
68
|
+
raise
|
|
69
|
+
rescue Exception
|
|
70
|
+
handler
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def stop
|
|
74
|
+
agent = HyperProbe.instance
|
|
75
|
+
if agent && !agent.agent_disabled?
|
|
76
|
+
begin
|
|
77
|
+
agent.force_flush(1.0)
|
|
78
|
+
rescue SignalException, SystemExit
|
|
79
|
+
raise
|
|
80
|
+
rescue Exception
|
|
81
|
+
# Best effort
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
HyperProbe.shutdown
|
|
85
|
+
rescue SignalException, SystemExit
|
|
86
|
+
raise
|
|
87
|
+
rescue Exception
|
|
88
|
+
nil
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Generated by rake proto:descriptor. DO NOT EDIT.
|
|
3
|
+
module Hyperprobe
|
|
4
|
+
module JavaProto
|
|
5
|
+
DESCRIPTOR_DATA = "\n\x0b\x61gent.proto\x12\x13hyperprobe.agent.v1\"\x9c\x01\n\x10GetProbesRequest\x12\x10\n\x08\x61gent_id\x18\x01 \x01(\t\x12\x12\n\nservice_id\x18\x02 \x01(\t\x12\x13\n\x0b\x65nvironment\x18\x03 \x01(\t\x12\x12\n\ncommit_sha\x18\x04 \x01(\t\x12\x10\n\x08language\x18\x05 \x01(\t\x12\x15\n\ragent_version\x18\x06 \x01(\t\x12\x10\n\x08hostname\x18\x07 \x01(\t\"\xbc\x01\n\x11GetProbesResponse\x12*\n\x06probes\x18\x01 \x03(\x0b\x32\x1a.hyperprobe.agent.v1.Probe\x12\"\n\x15next_sync_interval_ms\x18\x02 \x01(\x05H\x00\x88\x01\x01\x12=\n\rglobal_config\x18\x03 \x01(\x0b\x32&.hyperprobe.agent.v1.AgentGlobalConfigB\x18\n\x16_next_sync_interval_ms\"U\n\x16SourceMapStatusRequest\x12\x12\n\nservice_id\x18\x01 \x01(\t\x12\x13\n\x0b\x65nvironment\x18\x02 \x01(\t\x12\x12\n\ncommit_sha\x18\x03 \x01(\t\"C\n\x17SourceMapStatusResponse\x12\x13\n\x0bis_uploader\x18\x01 \x01(\x08\x12\x13\n\x0bis_complete\x18\x02 \x01(\x08\"n\n\x0eSourceMapChunk\x12\x12\n\nservice_id\x18\x01 \x01(\t\x12\x13\n\x0b\x65nvironment\x18\x02 \x01(\t\x12\x12\n\ncommit_sha\x18\x03 \x01(\t\x12\x11\n\tfile_name\x18\x04 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x05 \x01(\x0c\"!\n\x0eUploadResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"[\n\x1cMarkSourceMapCompleteRequest\x12\x12\n\nservice_id\x18\x01 \x01(\t\x12\x13\n\x0b\x65nvironment\x18\x02 \x01(\t\x12\x12\n\ncommit_sha\x18\x03 \x01(\t\"0\n\x1dMarkSourceMapCompleteResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"\x85\x03\n\x11\x41gentGlobalConfig\x12\x13\n\x0bredact_keys\x18\x01 \x03(\t\x12\x15\n\rredact_values\x18\x02 \x03(\t\x12\x1d\n\x10max_object_depth\x18\x03 \x01(\x05H\x00\x88\x01\x01\x12\x1d\n\x10max_array_length\x18\x04 \x01(\x05H\x01\x88\x01\x01\x12\x1e\n\x11stack_frame_depth\x18\x05 \x01(\x05H\x02\x88\x01\x01\x12\"\n\x15max_object_properties\x18\x06 \x01(\x05H\x03\x88\x01\x01\x12\x1e\n\x11max_string_length\x18\x07 \x01(\x05H\x04\x88\x01\x01\x12\x1d\n\x10\x63\x61pture_closures\x18\x08 \x01(\x08H\x05\x88\x01\x01\x42\x13\n\x11_max_object_depthB\x13\n\x11_max_array_lengthB\x14\n\x12_stack_frame_depthB\x18\n\x16_max_object_propertiesB\x14\n\x12_max_string_lengthB\x13\n\x11_capture_closures\"\x91\x07\n\x05Probe\x12\n\n\x02id\x18\x01 \x01(\t\x12,\n\x04type\x18\x02 \x01(\x0e\x32\x1e.hyperprobe.agent.v1.ProbeType\x12\x18\n\x10runtime_location\x18\x03 \x01(\t\x12\x14\n\x0cruntime_line\x18\x04 \x01(\x05\x12\"\n\x1asecondary_runtime_location\x18\x05 \x01(\t\x12\x1e\n\x16secondary_runtime_line\x18\x06 \x01(\x05\x12\x11\n\tcondition\x18\x07 \x01(\t\x12\x10\n\x08template\x18\x08 \x01(\t\x12\x13\n\x0bmetric_name\x18\t \x01(\t\x12\x19\n\x11metric_expression\x18\n \x01(\t\x12\x19\n\x11watch_expressions\x18\x0b \x03(\t\x12\x11\n\thit_limit\x18\x0c \x01(\x05\x12\x13\n\x0b\x65xpiry_time\x18\r \x01(\x03\x12\x16\n\x0eruntime_column\x18\x0e \x01(\x05\x12 \n\x18secondary_runtime_column\x18\x0f \x01(\x05\x12\x1e\n\x16\x63orrelation_expression\x18\x10 \x01(\t\x12\x1d\n\x10max_object_depth\x18\x11 \x01(\x05H\x00\x88\x01\x01\x12\x1d\n\x10max_array_length\x18\x12 \x01(\x05H\x01\x88\x01\x01\x12\x1e\n\x11stack_frame_depth\x18\x13 \x01(\x05H\x02\x88\x01\x01\x12\"\n\x15max_object_properties\x18\x14 \x01(\x05H\x03\x88\x01\x01\x12\x1e\n\x11max_string_length\x18\x15 \x01(\x05H\x04\x88\x01\x01\x12$\n\x17should_capture_trace_id\x18\x16 \x01(\x08H\x05\x88\x01\x01\x12\x16\n\tlog_level\x18\x17 \x01(\tH\x06\x88\x01\x01\x12!\n\x14should_log_to_stdout\x18\x18 \x01(\x08H\x07\x88\x01\x01\x12\x1d\n\x10\x63\x61pture_closures\x18\x19 \x01(\x08H\x08\x88\x01\x01\x42\x13\n\x11_max_object_depthB\x13\n\x11_max_array_lengthB\x14\n\x12_stack_frame_depthB\x18\n\x16_max_object_propertiesB\x14\n\x12_max_string_lengthB\x1a\n\x18_should_capture_trace_idB\x0c\n\n_log_levelB\x17\n\x15_should_log_to_stdoutB\x13\n\x11_capture_closures\"W\n\x0eTelemetryBatch\x12\x10\n\x08\x61gent_id\x18\x01 \x01(\t\x12\x33\n\x06\x65vents\x18\x02 \x03(\x0b\x32#.hyperprobe.agent.v1.TelemetryEvent\"\x8a\x01\n\nStackFrame\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x13\n\x0bline_number\x18\x03 \x01(\x05\x12\x15\n\rcolumn_number\x18\x04 \x01(\x05\x12\x17\n\nclass_name\x18\x05 \x01(\tH\x00\x88\x01\x01\x42\r\n\x0b_class_name\"\x8f\x02\n\x0eTelemetryEvent\x12\x10\n\x08probe_id\x18\x01 \x01(\t\x12\x14\n\x0ctimestamp_ms\x18\x02 \x01(\x03\x12\x35\n\x0cstack_frames\x18\x03 \x03(\x0b\x32\x1f.hyperprobe.agent.v1.StackFrame\x12\x1a\n\x12\x63\x61ptured_vars_json\x18\x04 \x01(\t\x12\x1a\n\x12watch_results_json\x18\x05 \x01(\t\x12\x15\n\revaluated_log\x18\x06 \x01(\t\x12\x14\n\x0cmetric_value\x18\x07 \x01(\x01\x12\x15\n\rcapture_error\x18\x08 \x01(\t\x12\x15\n\x08trace_id\x18\t \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_trace_id\"/\n\x11TelemetryResponse\x12\x1a\n\x12\x66inished_probe_ids\x18\x01 \x03(\t*\x9c\x01\n\tProbeType\x12\x1a\n\x16PROBE_TYPE_UNSPECIFIED\x10\x00\x12\x17\n\x13PROBE_TYPE_SNAPSHOT\x10\x01\x12\x12\n\x0ePROBE_TYPE_LOG\x10\x02\x12\x16\n\x12PROBE_TYPE_COUNTER\x10\x03\x12\x15\n\x11PROBE_TYPE_METRIC\x10\x04\x12\x17\n\x13PROBE_TYPE_DURATION\x10\x05\x32\x99\x04\n\x0b\x41gentBroker\x12Z\n\tGetProbes\x12%.hyperprobe.agent.v1.GetProbesRequest\x1a&.hyperprobe.agent.v1.GetProbesResponse\x12^\n\x0fReportTelemetry\x12#.hyperprobe.agent.v1.TelemetryBatch\x1a&.hyperprobe.agent.v1.TelemetryResponse\x12o\n\x12GetSourceMapStatus\x12+.hyperprobe.agent.v1.SourceMapStatusRequest\x1a,.hyperprobe.agent.v1.SourceMapStatusResponse\x12]\n\x0fUploadSourceMap\x12#.hyperprobe.agent.v1.SourceMapChunk\x1a#.hyperprobe.agent.v1.UploadResponse(\x01\x12~\n\x15MarkSourceMapComplete\x12\x31.hyperprobe.agent.v1.MarkSourceMapCompleteRequest\x1a\x32.hyperprobe.agent.v1.MarkSourceMapCompleteResponseB\tB\x05\x41gentP\x00\x62\x06proto3".b.freeze
|
|
6
|
+
end
|
|
7
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# source: agent.proto
|
|
4
|
+
|
|
5
|
+
require 'google/protobuf'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
descriptor_data = "\n\x0b\x61gent.proto\x12\x13hyperprobe.agent.v1\"\x9c\x01\n\x10GetProbesRequest\x12\x10\n\x08\x61gent_id\x18\x01 \x01(\t\x12\x12\n\nservice_id\x18\x02 \x01(\t\x12\x13\n\x0b\x65nvironment\x18\x03 \x01(\t\x12\x12\n\ncommit_sha\x18\x04 \x01(\t\x12\x10\n\x08language\x18\x05 \x01(\t\x12\x15\n\ragent_version\x18\x06 \x01(\t\x12\x10\n\x08hostname\x18\x07 \x01(\t\"\xbc\x01\n\x11GetProbesResponse\x12*\n\x06probes\x18\x01 \x03(\x0b\x32\x1a.hyperprobe.agent.v1.Probe\x12\"\n\x15next_sync_interval_ms\x18\x02 \x01(\x05H\x00\x88\x01\x01\x12=\n\rglobal_config\x18\x03 \x01(\x0b\x32&.hyperprobe.agent.v1.AgentGlobalConfigB\x18\n\x16_next_sync_interval_ms\"U\n\x16SourceMapStatusRequest\x12\x12\n\nservice_id\x18\x01 \x01(\t\x12\x13\n\x0b\x65nvironment\x18\x02 \x01(\t\x12\x12\n\ncommit_sha\x18\x03 \x01(\t\"C\n\x17SourceMapStatusResponse\x12\x13\n\x0bis_uploader\x18\x01 \x01(\x08\x12\x13\n\x0bis_complete\x18\x02 \x01(\x08\"n\n\x0eSourceMapChunk\x12\x12\n\nservice_id\x18\x01 \x01(\t\x12\x13\n\x0b\x65nvironment\x18\x02 \x01(\t\x12\x12\n\ncommit_sha\x18\x03 \x01(\t\x12\x11\n\tfile_name\x18\x04 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x05 \x01(\x0c\"!\n\x0eUploadResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"[\n\x1cMarkSourceMapCompleteRequest\x12\x12\n\nservice_id\x18\x01 \x01(\t\x12\x13\n\x0b\x65nvironment\x18\x02 \x01(\t\x12\x12\n\ncommit_sha\x18\x03 \x01(\t\"0\n\x1dMarkSourceMapCompleteResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"\x85\x03\n\x11\x41gentGlobalConfig\x12\x13\n\x0bredact_keys\x18\x01 \x03(\t\x12\x15\n\rredact_values\x18\x02 \x03(\t\x12\x1d\n\x10max_object_depth\x18\x03 \x01(\x05H\x00\x88\x01\x01\x12\x1d\n\x10max_array_length\x18\x04 \x01(\x05H\x01\x88\x01\x01\x12\x1e\n\x11stack_frame_depth\x18\x05 \x01(\x05H\x02\x88\x01\x01\x12\"\n\x15max_object_properties\x18\x06 \x01(\x05H\x03\x88\x01\x01\x12\x1e\n\x11max_string_length\x18\x07 \x01(\x05H\x04\x88\x01\x01\x12\x1d\n\x10\x63\x61pture_closures\x18\x08 \x01(\x08H\x05\x88\x01\x01\x42\x13\n\x11_max_object_depthB\x13\n\x11_max_array_lengthB\x14\n\x12_stack_frame_depthB\x18\n\x16_max_object_propertiesB\x14\n\x12_max_string_lengthB\x13\n\x11_capture_closures\"\x91\x07\n\x05Probe\x12\n\n\x02id\x18\x01 \x01(\t\x12,\n\x04type\x18\x02 \x01(\x0e\x32\x1e.hyperprobe.agent.v1.ProbeType\x12\x18\n\x10runtime_location\x18\x03 \x01(\t\x12\x14\n\x0cruntime_line\x18\x04 \x01(\x05\x12\"\n\x1asecondary_runtime_location\x18\x05 \x01(\t\x12\x1e\n\x16secondary_runtime_line\x18\x06 \x01(\x05\x12\x11\n\tcondition\x18\x07 \x01(\t\x12\x10\n\x08template\x18\x08 \x01(\t\x12\x13\n\x0bmetric_name\x18\t \x01(\t\x12\x19\n\x11metric_expression\x18\n \x01(\t\x12\x19\n\x11watch_expressions\x18\x0b \x03(\t\x12\x11\n\thit_limit\x18\x0c \x01(\x05\x12\x13\n\x0b\x65xpiry_time\x18\r \x01(\x03\x12\x16\n\x0eruntime_column\x18\x0e \x01(\x05\x12 \n\x18secondary_runtime_column\x18\x0f \x01(\x05\x12\x1e\n\x16\x63orrelation_expression\x18\x10 \x01(\t\x12\x1d\n\x10max_object_depth\x18\x11 \x01(\x05H\x00\x88\x01\x01\x12\x1d\n\x10max_array_length\x18\x12 \x01(\x05H\x01\x88\x01\x01\x12\x1e\n\x11stack_frame_depth\x18\x13 \x01(\x05H\x02\x88\x01\x01\x12\"\n\x15max_object_properties\x18\x14 \x01(\x05H\x03\x88\x01\x01\x12\x1e\n\x11max_string_length\x18\x15 \x01(\x05H\x04\x88\x01\x01\x12$\n\x17should_capture_trace_id\x18\x16 \x01(\x08H\x05\x88\x01\x01\x12\x16\n\tlog_level\x18\x17 \x01(\tH\x06\x88\x01\x01\x12!\n\x14should_log_to_stdout\x18\x18 \x01(\x08H\x07\x88\x01\x01\x12\x1d\n\x10\x63\x61pture_closures\x18\x19 \x01(\x08H\x08\x88\x01\x01\x42\x13\n\x11_max_object_depthB\x13\n\x11_max_array_lengthB\x14\n\x12_stack_frame_depthB\x18\n\x16_max_object_propertiesB\x14\n\x12_max_string_lengthB\x1a\n\x18_should_capture_trace_idB\x0c\n\n_log_levelB\x17\n\x15_should_log_to_stdoutB\x13\n\x11_capture_closures\"W\n\x0eTelemetryBatch\x12\x10\n\x08\x61gent_id\x18\x01 \x01(\t\x12\x33\n\x06\x65vents\x18\x02 \x03(\x0b\x32#.hyperprobe.agent.v1.TelemetryEvent\"\x8a\x01\n\nStackFrame\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x13\n\x0bline_number\x18\x03 \x01(\x05\x12\x15\n\rcolumn_number\x18\x04 \x01(\x05\x12\x17\n\nclass_name\x18\x05 \x01(\tH\x00\x88\x01\x01\x42\r\n\x0b_class_name\"\x8f\x02\n\x0eTelemetryEvent\x12\x10\n\x08probe_id\x18\x01 \x01(\t\x12\x14\n\x0ctimestamp_ms\x18\x02 \x01(\x03\x12\x35\n\x0cstack_frames\x18\x03 \x03(\x0b\x32\x1f.hyperprobe.agent.v1.StackFrame\x12\x1a\n\x12\x63\x61ptured_vars_json\x18\x04 \x01(\t\x12\x1a\n\x12watch_results_json\x18\x05 \x01(\t\x12\x15\n\revaluated_log\x18\x06 \x01(\t\x12\x14\n\x0cmetric_value\x18\x07 \x01(\x01\x12\x15\n\rcapture_error\x18\x08 \x01(\t\x12\x15\n\x08trace_id\x18\t \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_trace_id\"/\n\x11TelemetryResponse\x12\x1a\n\x12\x66inished_probe_ids\x18\x01 \x03(\t*\x9c\x01\n\tProbeType\x12\x1a\n\x16PROBE_TYPE_UNSPECIFIED\x10\x00\x12\x17\n\x13PROBE_TYPE_SNAPSHOT\x10\x01\x12\x12\n\x0ePROBE_TYPE_LOG\x10\x02\x12\x16\n\x12PROBE_TYPE_COUNTER\x10\x03\x12\x15\n\x11PROBE_TYPE_METRIC\x10\x04\x12\x17\n\x13PROBE_TYPE_DURATION\x10\x05\x32\x99\x04\n\x0b\x41gentBroker\x12Z\n\tGetProbes\x12%.hyperprobe.agent.v1.GetProbesRequest\x1a&.hyperprobe.agent.v1.GetProbesResponse\x12^\n\x0fReportTelemetry\x12#.hyperprobe.agent.v1.TelemetryBatch\x1a&.hyperprobe.agent.v1.TelemetryResponse\x12o\n\x12GetSourceMapStatus\x12+.hyperprobe.agent.v1.SourceMapStatusRequest\x1a,.hyperprobe.agent.v1.SourceMapStatusResponse\x12]\n\x0fUploadSourceMap\x12#.hyperprobe.agent.v1.SourceMapChunk\x1a#.hyperprobe.agent.v1.UploadResponse(\x01\x12~\n\x15MarkSourceMapComplete\x12\x31.hyperprobe.agent.v1.MarkSourceMapCompleteRequest\x1a\x32.hyperprobe.agent.v1.MarkSourceMapCompleteResponseB\tB\x05\x41gentP\x00\x62\x06proto3"
|
|
9
|
+
|
|
10
|
+
pool = ::Google::Protobuf::DescriptorPool.generated_pool
|
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
|
12
|
+
|
|
13
|
+
module Hyperprobe
|
|
14
|
+
module Agent
|
|
15
|
+
module V1
|
|
16
|
+
GetProbesRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.GetProbesRequest").msgclass
|
|
17
|
+
GetProbesResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.GetProbesResponse").msgclass
|
|
18
|
+
SourceMapStatusRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.SourceMapStatusRequest").msgclass
|
|
19
|
+
SourceMapStatusResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.SourceMapStatusResponse").msgclass
|
|
20
|
+
SourceMapChunk = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.SourceMapChunk").msgclass
|
|
21
|
+
UploadResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.UploadResponse").msgclass
|
|
22
|
+
MarkSourceMapCompleteRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.MarkSourceMapCompleteRequest").msgclass
|
|
23
|
+
MarkSourceMapCompleteResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.MarkSourceMapCompleteResponse").msgclass
|
|
24
|
+
AgentGlobalConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.AgentGlobalConfig").msgclass
|
|
25
|
+
Probe = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.Probe").msgclass
|
|
26
|
+
TelemetryBatch = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.TelemetryBatch").msgclass
|
|
27
|
+
StackFrame = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.StackFrame").msgclass
|
|
28
|
+
TelemetryEvent = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.TelemetryEvent").msgclass
|
|
29
|
+
TelemetryResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.TelemetryResponse").msgclass
|
|
30
|
+
ProbeType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hyperprobe.agent.v1.ProbeType").enummodule
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
2
|
+
# Source: agent.proto for package 'hyperprobe.agent.v1'
|
|
3
|
+
|
|
4
|
+
require 'grpc'
|
|
5
|
+
require 'agent_pb'
|
|
6
|
+
|
|
7
|
+
module Hyperprobe
|
|
8
|
+
module Agent
|
|
9
|
+
module V1
|
|
10
|
+
module AgentBroker
|
|
11
|
+
class Service
|
|
12
|
+
|
|
13
|
+
include ::GRPC::GenericService
|
|
14
|
+
|
|
15
|
+
self.marshal_class_method = :encode
|
|
16
|
+
self.unmarshal_class_method = :decode
|
|
17
|
+
self.service_name = 'hyperprobe.agent.v1.AgentBroker'
|
|
18
|
+
|
|
19
|
+
rpc :GetProbes, ::Hyperprobe::Agent::V1::GetProbesRequest, ::Hyperprobe::Agent::V1::GetProbesResponse
|
|
20
|
+
rpc :ReportTelemetry, ::Hyperprobe::Agent::V1::TelemetryBatch, ::Hyperprobe::Agent::V1::TelemetryResponse
|
|
21
|
+
# Handshake for JS source maps
|
|
22
|
+
rpc :GetSourceMapStatus, ::Hyperprobe::Agent::V1::SourceMapStatusRequest, ::Hyperprobe::Agent::V1::SourceMapStatusResponse
|
|
23
|
+
rpc :UploadSourceMap, stream(::Hyperprobe::Agent::V1::SourceMapChunk), ::Hyperprobe::Agent::V1::UploadResponse
|
|
24
|
+
rpc :MarkSourceMapComplete, ::Hyperprobe::Agent::V1::MarkSourceMapCompleteRequest, ::Hyperprobe::Agent::V1::MarkSourceMapCompleteResponse
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Stub = Service.rpc_stub_class
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'java'
|
|
4
|
+
require_relative 'agent_descriptor'
|
|
5
|
+
|
|
6
|
+
begin
|
|
7
|
+
require_relative '../jars/hyperprobe-grpc.jar'
|
|
8
|
+
JavaUtilities.get_proxy_class('co.hyperprobe.transport.ProtoCodec')
|
|
9
|
+
rescue Java::JavaLang::LinkageError => e
|
|
10
|
+
raise LoadError, "Cannot load HyperProbe protobuf codec (Java 11+ required): #{e.message}"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module Hyperprobe
|
|
14
|
+
module Agent
|
|
15
|
+
module V1
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Only the SDK's canonical messages are exposed, not Google's Ruby runtime API.
|
|
20
|
+
module JavaProto
|
|
21
|
+
CODEC = JavaUtilities.get_proxy_class('co.hyperprobe.transport.ProtoCodec').new(DESCRIPTOR_DATA.to_java_bytes)
|
|
22
|
+
CLASSES = {}
|
|
23
|
+
|
|
24
|
+
class Message
|
|
25
|
+
class << self
|
|
26
|
+
attr_accessor :descriptor, :fields
|
|
27
|
+
|
|
28
|
+
def decode(bytes)
|
|
29
|
+
raise TypeError, 'Expected protobuf bytes as a String' unless bytes.is_a?(String)
|
|
30
|
+
raise ArgumentError, 'Protobuf payload exceeds 4 MiB' if bytes.bytesize > 4 * 1024 * 1024
|
|
31
|
+
|
|
32
|
+
from_java(CODEC.decode(descriptor, bytes.to_java_bytes))
|
|
33
|
+
rescue Java::JavaLang::Exception => e
|
|
34
|
+
raise ArgumentError, "Invalid protobuf: #{e.message}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def encode(message)
|
|
38
|
+
raise TypeError, "Expected #{self}" unless message.is_a?(self)
|
|
39
|
+
|
|
40
|
+
message.to_proto
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def from_java(message)
|
|
44
|
+
result = new
|
|
45
|
+
message.getAllFields.each do |field, value|
|
|
46
|
+
decoded = field.isRepeated ? value.map { |item| decode_value(field, item) } : decode_value(field, value)
|
|
47
|
+
result.public_send("#{field.getName}=", decoded)
|
|
48
|
+
end
|
|
49
|
+
result.instance_variable_set(:@unknown_fields, message.getUnknownFields)
|
|
50
|
+
result
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def decode_value(field, value)
|
|
54
|
+
case field.getJavaType.to_s
|
|
55
|
+
when 'MESSAGE' then CLASSES.fetch(field.getMessageType.getFullName).from_java(value)
|
|
56
|
+
when 'ENUM' then value.getIndex < 0 ? value.getNumber : value.getName.to_sym
|
|
57
|
+
when 'BYTE_STRING' then String.from_java_bytes(value.toByteArray)
|
|
58
|
+
else value
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def normalize(field, value)
|
|
63
|
+
case field.getJavaType.to_s
|
|
64
|
+
when 'MESSAGE'
|
|
65
|
+
klass = CLASSES.fetch(field.getMessageType.getFullName)
|
|
66
|
+
value = klass.new(value) if value.is_a?(Hash)
|
|
67
|
+
raise TypeError, "Expected #{klass} for #{field.getName}" unless value.is_a?(klass)
|
|
68
|
+
when 'ENUM'
|
|
69
|
+
enum = field.getEnumType
|
|
70
|
+
if value.is_a?(Symbol)
|
|
71
|
+
entry = enum.findValueByName(value.to_s)
|
|
72
|
+
raise ArgumentError, "Unknown enum #{value}" unless entry
|
|
73
|
+
return value
|
|
74
|
+
end
|
|
75
|
+
integer!(field, value, 32)
|
|
76
|
+
entry = enum.findValueByNumber(value)
|
|
77
|
+
value = entry.getName.to_sym if entry
|
|
78
|
+
when 'INT', 'LONG'
|
|
79
|
+
integer!(field, value, field.getJavaType.to_s == 'INT' ? 32 : 64)
|
|
80
|
+
when 'DOUBLE', 'FLOAT'
|
|
81
|
+
raise TypeError, "Expected number for #{field.getName}" unless value.is_a?(Numeric) && !value.is_a?(Complex)
|
|
82
|
+
value = value.to_f
|
|
83
|
+
when 'BOOLEAN'
|
|
84
|
+
raise TypeError, "Expected boolean for #{field.getName}" unless value.equal?(true) || value.equal?(false)
|
|
85
|
+
when 'STRING', 'BYTE_STRING'
|
|
86
|
+
raise TypeError, "Expected String for #{field.getName}" unless value.is_a?(String)
|
|
87
|
+
value = field.getJavaType.to_s == 'STRING' ? value.encode(Encoding::UTF_8) : value.b
|
|
88
|
+
raise ArgumentError, 'Invalid UTF-8 protobuf string' unless value.valid_encoding?
|
|
89
|
+
value = value.dup.freeze
|
|
90
|
+
else
|
|
91
|
+
raise ArgumentError, "Unsupported canonical field #{field.getName}"
|
|
92
|
+
end
|
|
93
|
+
value
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def integer!(field, value, bits)
|
|
97
|
+
raise TypeError, "Expected Integer for #{field.getName}" unless value.is_a?(Integer)
|
|
98
|
+
raise RangeError, "Out of range for #{field.getName}" unless value >= -(2**(bits - 1)) && value < 2**(bits - 1)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def java_value(field, value)
|
|
102
|
+
case field.getJavaType.to_s
|
|
103
|
+
when 'MESSAGE' then value.to_java_message
|
|
104
|
+
when 'ENUM'
|
|
105
|
+
enum = field.getEnumType
|
|
106
|
+
value.is_a?(Symbol) ? enum.findValueByName(value.to_s) : enum.findValueByNumberCreatingIfUnknown(value)
|
|
107
|
+
when 'BYTE_STRING' then CODEC.bytes(value.to_java_bytes)
|
|
108
|
+
when 'STRING' then value.to_java(:string)
|
|
109
|
+
when 'INT' then value.to_java(:int)
|
|
110
|
+
when 'LONG' then value.to_java(:long)
|
|
111
|
+
when 'FLOAT' then value.to_java(:float)
|
|
112
|
+
when 'DOUBLE' then value.to_java(:double)
|
|
113
|
+
when 'BOOLEAN' then value.to_java(:boolean)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def initialize(values = {})
|
|
119
|
+
raise ArgumentError, 'Expected a field Hash' unless values.is_a?(Hash)
|
|
120
|
+
|
|
121
|
+
@values = {}
|
|
122
|
+
values.each do |name, value|
|
|
123
|
+
key = name.to_s
|
|
124
|
+
raise ArgumentError, "Unknown field #{key}" unless self.class.fields.key?(key)
|
|
125
|
+
public_send("#{key}=", value) unless value.nil?
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def to_java_message
|
|
130
|
+
builder = CODEC.builder(self.class.descriptor)
|
|
131
|
+
builder.mergeUnknownFields(@unknown_fields) if @unknown_fields
|
|
132
|
+
@values.each do |name, value|
|
|
133
|
+
field = self.class.fields.fetch(name)
|
|
134
|
+
if field.isRepeated
|
|
135
|
+
# Arrays remain mutable; scalar setters already normalize and freeze strings.
|
|
136
|
+
value.each { |item| builder.addRepeatedField(field, self.class.java_value(field, self.class.normalize(field, item))) }
|
|
137
|
+
else
|
|
138
|
+
builder.setField(field, self.class.java_value(field, value))
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
builder.build
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def to_proto
|
|
145
|
+
String.from_java_bytes(to_java_message.toByteArray)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def serialized_size
|
|
149
|
+
to_java_message.getSerializedSize
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def ==(other)
|
|
153
|
+
other.instance_of?(self.class) && to_java_message == other.to_java_message
|
|
154
|
+
end
|
|
155
|
+
alias eql? ==
|
|
156
|
+
|
|
157
|
+
def hash
|
|
158
|
+
to_java_message.hashCode
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
CODEC.getFile.getEnumTypes.each do |enum|
|
|
163
|
+
mod = Module.new
|
|
164
|
+
enum.getValues.each { |value| mod.const_set(value.getName, value.getNumber) }
|
|
165
|
+
Agent::V1.const_set(enum.getName, mod)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
CODEC.getFile.getMessageTypes.each do |descriptor|
|
|
169
|
+
klass = Class.new(Message)
|
|
170
|
+
klass.descriptor = descriptor
|
|
171
|
+
klass.fields = descriptor.getFields.each_with_object({}) { |field, fields| fields[field.getName] = field }.freeze
|
|
172
|
+
CLASSES[descriptor.getFullName] = klass
|
|
173
|
+
Agent::V1.const_set(descriptor.getName, klass)
|
|
174
|
+
klass.fields.each do |name, field|
|
|
175
|
+
klass.define_method(name) do
|
|
176
|
+
return @values[name] if @values.key?(name)
|
|
177
|
+
return @values[name] = [] if field.isRepeated
|
|
178
|
+
return nil if field.getJavaType.to_s == 'MESSAGE'
|
|
179
|
+
|
|
180
|
+
self.class.decode_value(field, field.getDefaultValue)
|
|
181
|
+
end
|
|
182
|
+
klass.define_method("#{name}=") do |value|
|
|
183
|
+
if value.nil? && field.hasPresence
|
|
184
|
+
@values.delete(name)
|
|
185
|
+
elsif field.isRepeated
|
|
186
|
+
raise TypeError, "Expected Array for #{name}" unless value.is_a?(Array)
|
|
187
|
+
@values[name] = value.map { |item| self.class.normalize(field, item) }
|
|
188
|
+
else
|
|
189
|
+
@values[name] = self.class.normalize(field, value)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
if field.hasPresence
|
|
193
|
+
klass.define_method("has_#{name}?") { @values.key?(name) }
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
CLASSES.freeze
|
|
198
|
+
end
|
|
199
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
if RUBY_PLATFORM =~ /java/
|
|
4
|
+
require_relative 'protos/java_messages'
|
|
5
|
+
else
|
|
6
|
+
protos_dir = File.expand_path('protos', __dir__)
|
|
7
|
+
$LOAD_PATH.unshift(protos_dir) unless $LOAD_PATH.include?(protos_dir)
|
|
8
|
+
require 'agent_pb'
|
|
9
|
+
begin
|
|
10
|
+
require 'agent_services_pb'
|
|
11
|
+
rescue LoadError
|
|
12
|
+
# Environments without the C-grpc gem can still use the messages.
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HyperProbe
|
|
4
|
+
if defined?(::Rails::Railtie)
|
|
5
|
+
class Railtie < ::Rails::Railtie
|
|
6
|
+
config.after_initialize do
|
|
7
|
+
enabled = ENV['HYPERPROBE_ENABLED'] != 'false' && ENV['HYPERPROBE_DISABLED'] != 'YES'
|
|
8
|
+
has_service_id = !ENV['HYPERPROBE_SERVICE_ID'].nil? && !ENV['HYPERPROBE_SERVICE_ID'].empty?
|
|
9
|
+
|
|
10
|
+
if enabled && has_service_id
|
|
11
|
+
HyperProbe.start
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
if defined?(::Spring) && ::Spring.respond_to?(:after_fork)
|
|
15
|
+
::Spring.after_fork do
|
|
16
|
+
HyperProbe.after_fork
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|