xhummingbird 0.1.0 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/Gemfile.lock +2 -2
- data/examples/custom_tags.rb +23 -0
- data/examples/send_exception.rb +2 -0
- data/examples/send_trace.rb +2 -0
- data/examples/short_name.rb +2 -0
- data/examples/use_in_processes.rb +4 -0
- data/examples/use_in_threads.rb +2 -0
- data/lib/xhummingbird.rb +67 -16
- data/lib/xhummingbird/client.rb +28 -21
- data/lib/xhummingbird/protos/event_pb.rb +1 -0
- data/lib/xhummingbird/rack.rb +1 -0
- data/lib/xhummingbird/rack/capture_exception.rb +62 -0
- data/lib/xhummingbird/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15a88a5d49e5f283250cb3ea1a3c65cdbd6f856c4d4f8e51833f4395a930fce0
|
4
|
+
data.tar.gz: 6d433c7920f91d794aea403c0f0f6cfd3196b0c166574f250c6e4f6783cb4679
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 746d060320800872e1e0393039d16f12adc5ab79a390f4ee1424cc29a66feae1ac3b2a0fcfb94abecacaaae3c03ce7e70ddaec713ef7600e6514e44fdc556f41
|
7
|
+
data.tar.gz: d19646279e7fc71681753f2980a1cdfe84c6ee3f5bb0b2b1c2381657d814d1fc81da9f62c142ba1d904a16f735edf4c126494481f88fc83f7921fe7bd5e6692f
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.0.0
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
xhummingbird (0.1.
|
4
|
+
xhummingbird (0.1.5)
|
5
5
|
ffi-rzmq
|
6
6
|
google-protobuf
|
7
7
|
|
@@ -14,7 +14,7 @@ GEM
|
|
14
14
|
ffi-rzmq-core (>= 1.0.7)
|
15
15
|
ffi-rzmq-core (1.0.7)
|
16
16
|
ffi
|
17
|
-
google-protobuf (3.15.
|
17
|
+
google-protobuf (3.15.8-x86_64-linux)
|
18
18
|
minitest (5.14.4)
|
19
19
|
parallel (1.20.1)
|
20
20
|
parser (3.0.0.0)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'xhummingbird'
|
2
|
+
|
3
|
+
raise "Set #{Xhummingbird::Client::XH_SERVER} environment variable" unless Xhummingbird.enabled?
|
4
|
+
|
5
|
+
Xhummingbird.start
|
6
|
+
|
7
|
+
Xhummingbird.send_trace(
|
8
|
+
title: "CustomTagTrace",
|
9
|
+
message: "CustomTags",
|
10
|
+
tags: {
|
11
|
+
tag_a: 42,
|
12
|
+
tag_b: "foo",
|
13
|
+
tag_c: :bar
|
14
|
+
}
|
15
|
+
)
|
16
|
+
|
17
|
+
begin
|
18
|
+
raise 'Something wrong'
|
19
|
+
rescue => e
|
20
|
+
Xhummingbird.send_exception(e, tags: {path: __FILE__})
|
21
|
+
end
|
22
|
+
|
23
|
+
sleep 1 # Await sending
|
data/examples/send_exception.rb
CHANGED
data/examples/send_trace.rb
CHANGED
data/examples/short_name.rb
CHANGED
@@ -2,10 +2,14 @@ require 'xhummingbird'
|
|
2
2
|
|
3
3
|
raise "Set #{Xhummingbird::Client::XH_SERVER} environment variable" unless Xhummingbird.enabled?
|
4
4
|
|
5
|
+
Xhummingbird.start
|
6
|
+
|
5
7
|
Xhummingbird.send_trace(title: "ParentProcess", message: "Send trace from parent process")
|
6
8
|
|
7
9
|
process_ids = 10.times.map do |i|
|
8
10
|
fork do
|
11
|
+
Xhummingbird.start
|
12
|
+
|
9
13
|
Xhummingbird.send_trace(title: "ChildProcess", message: "Send trace from child process #{i}")
|
10
14
|
|
11
15
|
sleep 1 # Await sending
|
data/examples/use_in_threads.rb
CHANGED
@@ -2,6 +2,8 @@ require 'xhummingbird'
|
|
2
2
|
|
3
3
|
raise "Set #{Xhummingbird::Client::XH_SERVER} environment variable" unless Xhummingbird.enabled?
|
4
4
|
|
5
|
+
Xhummingbird.start
|
6
|
+
|
5
7
|
threads = 10.times.map do |i|
|
6
8
|
Thread.start do
|
7
9
|
Xhummingbird.send_trace(title: "Thread", message: "Send trace from thread #{i}")
|
data/lib/xhummingbird.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require 'singleton'
|
4
4
|
require 'ffi-rzmq'
|
5
5
|
require 'socket'
|
6
|
+
require 'logger'
|
7
|
+
require 'set'
|
6
8
|
|
7
9
|
require_relative "xhummingbird/version"
|
8
10
|
require_relative "xhummingbird/client"
|
@@ -11,7 +13,25 @@ require_relative "xhummingbird/protos/event_pb"
|
|
11
13
|
module Xhummingbird
|
12
14
|
class Error < StandardError; end
|
13
15
|
|
14
|
-
|
16
|
+
XH_SERVICE = 'XH_SERVICE'
|
17
|
+
|
18
|
+
LOGGER = Logger.new(STDERR)
|
19
|
+
|
20
|
+
def self.debug(*args)
|
21
|
+
LOGGER.debug(*args) if ENV['XH_DEBUG']
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.start
|
25
|
+
debug(__method__)
|
26
|
+
|
27
|
+
Client.instance.start
|
28
|
+
|
29
|
+
send_trace(title: "Started", message: "Xhummingbird Ruby SDK started.", level: 0)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.send_trace(title:, message: "", level: 1, tags: {}, service: nil)
|
33
|
+
debug(__method__)
|
34
|
+
|
15
35
|
return unless enabled?
|
16
36
|
|
17
37
|
send(
|
@@ -19,14 +39,17 @@ module Xhummingbird
|
|
19
39
|
title: title.to_s,
|
20
40
|
message: message.to_s,
|
21
41
|
trace: caller,
|
22
|
-
tags: default_tags,
|
23
|
-
timestamp: Time.now
|
42
|
+
tags: default_tags.merge(format_hash(tags)),
|
43
|
+
timestamp: Time.now,
|
44
|
+
service: service || default_service
|
24
45
|
)
|
25
|
-
rescue
|
26
|
-
|
46
|
+
rescue => e
|
47
|
+
debug(e)
|
27
48
|
end
|
28
49
|
|
29
|
-
def self.send_exception(exception, level: 2)
|
50
|
+
def self.send_exception(exception, level: 2, tags: {}, service: nil)
|
51
|
+
debug(__method__)
|
52
|
+
|
30
53
|
return unless enabled?
|
31
54
|
|
32
55
|
send(
|
@@ -34,37 +57,65 @@ module Xhummingbird
|
|
34
57
|
title: exception.class.name,
|
35
58
|
message: exception.message,
|
36
59
|
trace: exception.backtrace,
|
37
|
-
tags: default_tags,
|
38
|
-
timestamp: Time.now
|
60
|
+
tags: default_tags.merge(format_hash(tags)),
|
61
|
+
timestamp: Time.now,
|
62
|
+
service: service || default_service
|
39
63
|
)
|
40
|
-
rescue
|
41
|
-
|
64
|
+
rescue => e
|
65
|
+
debug(e)
|
42
66
|
end
|
43
67
|
|
44
68
|
def self.send_event(**args)
|
69
|
+
debug(__method__)
|
70
|
+
|
45
71
|
return unless enabled?
|
46
72
|
|
47
73
|
send(**args)
|
48
|
-
rescue
|
49
|
-
|
74
|
+
rescue => e
|
75
|
+
debug(e)
|
50
76
|
end
|
51
77
|
|
52
78
|
def self.enabled?
|
79
|
+
debug(__method__)
|
80
|
+
|
53
81
|
Client.instance.enabled?
|
54
82
|
end
|
55
83
|
|
56
84
|
def self.default_tags
|
85
|
+
debug(__method__)
|
86
|
+
|
57
87
|
{
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
88
|
+
"default/sdk" => "Ruby #{Xhummingbird::VERSION}",
|
89
|
+
"default/hostname" => Socket.gethostname,
|
90
|
+
"default/ruby_version" => RUBY_VERSION,
|
91
|
+
"default/pid" => Process.pid.to_s,
|
92
|
+
"default/thread_object_id" => Thread.current.object_id.to_s
|
62
93
|
}
|
63
94
|
end
|
64
95
|
|
65
96
|
def self.send(**args)
|
97
|
+
debug(__method__)
|
98
|
+
|
66
99
|
event = Event.new(**args)
|
67
100
|
message = Event.encode(event)
|
68
101
|
Client.instance.send(message)
|
69
102
|
end
|
103
|
+
|
104
|
+
def self.format_hash(hash)
|
105
|
+
debug(__method__)
|
106
|
+
|
107
|
+
formatted = {}
|
108
|
+
|
109
|
+
hash.each do |k, v|
|
110
|
+
formatted[k.to_s] = v.to_s
|
111
|
+
end
|
112
|
+
|
113
|
+
formatted
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.default_service
|
117
|
+
debug(__method__)
|
118
|
+
|
119
|
+
ENV.fetch(XH_SERVICE, "")
|
120
|
+
end
|
70
121
|
end
|
data/lib/xhummingbird/client.rb
CHANGED
@@ -5,41 +5,48 @@ module Xhummingbird
|
|
5
5
|
XH_SERVER = 'XH_SERVER'
|
6
6
|
|
7
7
|
def initialize
|
8
|
-
@
|
8
|
+
@pid = nil
|
9
|
+
@socket = nil
|
10
|
+
@active = false
|
9
11
|
end
|
10
12
|
|
11
13
|
def send(message)
|
12
|
-
|
14
|
+
if active?
|
15
|
+
@socket.send_string(message)
|
16
|
+
else
|
17
|
+
Xhummingbird.debug("Xhummingbird not started.")
|
18
|
+
end
|
13
19
|
end
|
14
20
|
|
15
21
|
def enabled?
|
16
|
-
@
|
22
|
+
@enabled ||= !!address
|
17
23
|
end
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
25
|
+
def start
|
26
|
+
ctx = ZMQ::Context.new
|
27
|
+
socket = ctx.socket(ZMQ::PUSH)
|
28
|
+
socket.connect(address)
|
29
|
+
@socket = socket
|
30
|
+
Xhummingbird.debug("Socket created (pid: #{$$})")
|
31
|
+
|
32
|
+
at_exit do
|
33
|
+
Xhummingbird.debug("at_exit started.")
|
34
|
+
@socket.close
|
35
|
+
Xhummingbird.debug("at_exit stopped.")
|
36
|
+
end
|
23
37
|
|
24
|
-
@
|
38
|
+
@pid = $$
|
39
|
+
@active = true
|
25
40
|
end
|
26
41
|
|
27
|
-
|
28
|
-
@mutex.synchronize do
|
29
|
-
return @socket if defined?(@socket) && @pid == Process.pid
|
30
|
-
|
31
|
-
@pid = Process.pid
|
32
|
-
|
33
|
-
ctx = ZMQ::Context.new
|
34
|
-
socket = ctx.socket(ZMQ::PUSH)
|
35
|
-
socket.connect(address)
|
36
|
-
|
37
|
-
@socket = socket
|
38
|
-
end
|
39
|
-
end
|
42
|
+
private
|
40
43
|
|
41
44
|
def address
|
42
45
|
ENV[XH_SERVER]
|
43
46
|
end
|
47
|
+
|
48
|
+
def active?
|
49
|
+
@pid == $$ && @socket && @active
|
50
|
+
end
|
44
51
|
end
|
45
52
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'rack/capture_exception'
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Xhummingbird
|
2
|
+
module Rack
|
3
|
+
class CaptureException
|
4
|
+
CONVERT_KEYS = Set.new(%w(
|
5
|
+
REQUEST_METHOD
|
6
|
+
SCRIPT_NAME
|
7
|
+
PATH_INFO
|
8
|
+
QUERY_STRING
|
9
|
+
SERVER_NAME
|
10
|
+
SERVER_PORT
|
11
|
+
rack.version
|
12
|
+
rack.url_scheme
|
13
|
+
rack.multithread
|
14
|
+
rack.multiprocess
|
15
|
+
rack.run_once
|
16
|
+
rack.hijack?
|
17
|
+
))
|
18
|
+
|
19
|
+
HTTP_HEADER_PREFIX = 'HTTP_'
|
20
|
+
|
21
|
+
def initialize(app)
|
22
|
+
@app = app
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(env)
|
26
|
+
begin
|
27
|
+
response = @app.call(env)
|
28
|
+
rescue => e
|
29
|
+
Xhummingbird.send_exception(e, tags: convert_to_rack_tags(env))
|
30
|
+
end
|
31
|
+
|
32
|
+
error = env['rack.exception'] || env['sinatra.error']
|
33
|
+
|
34
|
+
if error
|
35
|
+
level = (400..499).include?(response.first.to_i) ? 0 : 2
|
36
|
+
|
37
|
+
Xhummingbird.send_exception(error, level: level, tags: convert_to_rack_tags(env))
|
38
|
+
end
|
39
|
+
|
40
|
+
response
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def convert_to_rack_tags(env)
|
46
|
+
tags = {}
|
47
|
+
|
48
|
+
env.each do |k, v|
|
49
|
+
if CONVERT_KEYS.include?(k) || k.start_with?(HTTP_HEADER_PREFIX)
|
50
|
+
begin
|
51
|
+
tags["rack_env/" + k.to_s] = v.to_s
|
52
|
+
rescue => e
|
53
|
+
Xhummingbird.debug(e)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
tags
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/xhummingbird/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xhummingbird
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- xmisao
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi-rzmq
|
@@ -47,6 +47,7 @@ extra_rdoc_files: []
|
|
47
47
|
files:
|
48
48
|
- ".gitignore"
|
49
49
|
- ".rubocop.yml"
|
50
|
+
- ".ruby-version"
|
50
51
|
- CODE_OF_CONDUCT.md
|
51
52
|
- Gemfile
|
52
53
|
- Gemfile.lock
|
@@ -55,6 +56,7 @@ files:
|
|
55
56
|
- Rakefile
|
56
57
|
- bin/console
|
57
58
|
- bin/setup
|
59
|
+
- examples/custom_tags.rb
|
58
60
|
- examples/send_exception.rb
|
59
61
|
- examples/send_trace.rb
|
60
62
|
- examples/short_name.rb
|
@@ -63,6 +65,8 @@ files:
|
|
63
65
|
- lib/xhummingbird.rb
|
64
66
|
- lib/xhummingbird/client.rb
|
65
67
|
- lib/xhummingbird/protos/event_pb.rb
|
68
|
+
- lib/xhummingbird/rack.rb
|
69
|
+
- lib/xhummingbird/rack/capture_exception.rb
|
66
70
|
- lib/xhummingbird/short_name.rb
|
67
71
|
- lib/xhummingbird/version.rb
|
68
72
|
- xhummingbird.gemspec
|