xhummingbird 0.1.0 → 0.1.5

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 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