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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 582e31f5f12893d74a24a8bc948e544778c7ad847bd95d8acd020f9617b6e27e
4
- data.tar.gz: c68df314d986f338ee06fec0f0c43c5b6024aaba74787fde79a939096fb8171a
3
+ metadata.gz: 15a88a5d49e5f283250cb3ea1a3c65cdbd6f856c4d4f8e51833f4395a930fce0
4
+ data.tar.gz: 6d433c7920f91d794aea403c0f0f6cfd3196b0c166574f250c6e4f6783cb4679
5
5
  SHA512:
6
- metadata.gz: 3efd449a0ae81617f6941e821ae60cfd7d248188b5d74ada5cc5c398a07232880c214fe41ae285d5e2fd0e106c6cb866556e91f7ccf33e91990ba7fbefa9e9eb
7
- data.tar.gz: 7fb41838d484f79b1a2738a726ee44486d1ce97e1cf72aa255ce235a42b235dca48bc8d5c3155c5ad65a807b246eac7ad3565e9331bdbcc5f2aaa575c212e1ee
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.0)
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.5-x86_64-linux)
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
@@ -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
  begin
6
8
  raise 'Something wrong'
7
9
  rescue => e
@@ -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
  Xhummingbird.send_trace(title: "SampleTrace", message: "Something happend")
6
8
 
7
9
  sleep 1 # Await sending
@@ -3,6 +3,8 @@ require 'xhummingbird/short_name'
3
3
 
4
4
  raise "Set #{XH::Client::XH_SERVER} environment variable" unless XH.enabled?
5
5
 
6
+ XH.start
7
+
6
8
  XH.send_trace(title: "ShortNameTrace", message: "Send trace from short name reference")
7
9
 
8
10
  begin
@@ -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
@@ -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
- def self.send_trace(title:, message: "", level: 1)
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
- raise Error
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
- raise Error
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
- raise Error
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
- hostname: Socket.gethostname,
59
- ruby_version: RUBY_VERSION,
60
- pid: Process.pid.to_s,
61
- thread_object_id: Thread.current.object_id.to_s
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
@@ -5,41 +5,48 @@ module Xhummingbird
5
5
  XH_SERVER = 'XH_SERVER'
6
6
 
7
7
  def initialize
8
- @mutex = Mutex.new
8
+ @pid = nil
9
+ @socket = nil
10
+ @active = false
9
11
  end
10
12
 
11
13
  def send(message)
12
- socket.send_string(message)
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
- @setup ||= !!address
22
+ @enabled ||= !!address
17
23
  end
18
24
 
19
- private
20
-
21
- def socket
22
- return @socket if defined?(@socket) && @pid == Process.pid
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
- @socket = init_socket
38
+ @pid = $$
39
+ @active = true
25
40
  end
26
41
 
27
- def init_socket
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
@@ -13,6 +13,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
13
13
  repeated :trace, :string, 4
14
14
  map :tags, :string, :string, 5
15
15
  optional :timestamp, :message, 6, "google.protobuf.Timestamp"
16
+ optional :service, :string, 7
16
17
  end
17
18
  end
18
19
  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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Xhummingbird
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.5"
5
5
  end
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.0
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-03-13 00:00:00.000000000 Z
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