hoss-agent 1.0.1

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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE/Bug_report.md +40 -0
  3. data/.github/ISSUE_TEMPLATE/Feature_request.md +17 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +60 -0
  5. data/.gitignore +27 -0
  6. data/.rspec +2 -0
  7. data/Dockerfile +43 -0
  8. data/Gemfile +105 -0
  9. data/LICENSE +201 -0
  10. data/hoss-agent.gemspec +42 -0
  11. data/lib/hoss/agent.rb +231 -0
  12. data/lib/hoss/central_config/cache_control.rb +51 -0
  13. data/lib/hoss/central_config.rb +184 -0
  14. data/lib/hoss/child_durations.rb +64 -0
  15. data/lib/hoss/config/bytes.rb +42 -0
  16. data/lib/hoss/config/duration.rb +40 -0
  17. data/lib/hoss/config/options.rb +154 -0
  18. data/lib/hoss/config/regexp_list.rb +30 -0
  19. data/lib/hoss/config/wildcard_pattern_list.rb +54 -0
  20. data/lib/hoss/config.rb +304 -0
  21. data/lib/hoss/context/request/socket.rb +36 -0
  22. data/lib/hoss/context/request/url.rb +59 -0
  23. data/lib/hoss/context/request.rb +28 -0
  24. data/lib/hoss/context/response.rb +47 -0
  25. data/lib/hoss/context/user.rb +59 -0
  26. data/lib/hoss/context.rb +64 -0
  27. data/lib/hoss/context_builder.rb +112 -0
  28. data/lib/hoss/deprecations.rb +39 -0
  29. data/lib/hoss/error/exception.rb +70 -0
  30. data/lib/hoss/error/log.rb +41 -0
  31. data/lib/hoss/error.rb +49 -0
  32. data/lib/hoss/error_builder.rb +90 -0
  33. data/lib/hoss/event.rb +131 -0
  34. data/lib/hoss/instrumenter.rb +107 -0
  35. data/lib/hoss/internal_error.rb +23 -0
  36. data/lib/hoss/logging.rb +70 -0
  37. data/lib/hoss/metadata/process_info.rb +35 -0
  38. data/lib/hoss/metadata/service_info.rb +76 -0
  39. data/lib/hoss/metadata/system_info/container_info.rb +136 -0
  40. data/lib/hoss/metadata/system_info.rb +47 -0
  41. data/lib/hoss/metadata.rb +36 -0
  42. data/lib/hoss/naively_hashable.rb +38 -0
  43. data/lib/hoss/rails.rb +68 -0
  44. data/lib/hoss/railtie.rb +42 -0
  45. data/lib/hoss/report.rb +9 -0
  46. data/lib/hoss/sinatra.rb +53 -0
  47. data/lib/hoss/spies/faraday.rb +102 -0
  48. data/lib/hoss/spies/http.rb +81 -0
  49. data/lib/hoss/spies/net_http.rb +97 -0
  50. data/lib/hoss/spies.rb +104 -0
  51. data/lib/hoss/stacktrace/frame.rb +66 -0
  52. data/lib/hoss/stacktrace.rb +33 -0
  53. data/lib/hoss/stacktrace_builder.rb +124 -0
  54. data/lib/hoss/transport/base.rb +191 -0
  55. data/lib/hoss/transport/connection/http.rb +139 -0
  56. data/lib/hoss/transport/connection/proxy_pipe.rb +94 -0
  57. data/lib/hoss/transport/connection.rb +55 -0
  58. data/lib/hoss/transport/filters/hash_sanitizer.rb +77 -0
  59. data/lib/hoss/transport/filters/secrets_filter.rb +48 -0
  60. data/lib/hoss/transport/filters.rb +60 -0
  61. data/lib/hoss/transport/headers.rb +74 -0
  62. data/lib/hoss/transport/serializers/context_serializer.rb +112 -0
  63. data/lib/hoss/transport/serializers/error_serializer.rb +92 -0
  64. data/lib/hoss/transport/serializers/event_serializer.rb +73 -0
  65. data/lib/hoss/transport/serializers/metadata_serializer.rb +92 -0
  66. data/lib/hoss/transport/serializers/report_serializer.rb +33 -0
  67. data/lib/hoss/transport/serializers.rb +113 -0
  68. data/lib/hoss/transport/user_agent.rb +48 -0
  69. data/lib/hoss/transport/worker.rb +319 -0
  70. data/lib/hoss/util/inflector.rb +110 -0
  71. data/lib/hoss/util/lru_cache.rb +65 -0
  72. data/lib/hoss/util/throttle.rb +52 -0
  73. data/lib/hoss/util.rb +54 -0
  74. data/lib/hoss/version.rb +22 -0
  75. data/lib/hoss-agent.rb +210 -0
  76. data/lib/hoss.rb +21 -0
  77. metadata +147 -0
@@ -0,0 +1,47 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ # frozen_string_literal: true
19
+
20
+ module Hoss
21
+ class Context
22
+ # @api private
23
+ class Response
24
+ def initialize(
25
+ status_code,
26
+ headers: {},
27
+ headers_sent: true,
28
+ finished: true
29
+ )
30
+ @status_code = status_code
31
+ @headers_sent = headers_sent
32
+ @finished = finished
33
+
34
+ self.headers = headers
35
+ end
36
+
37
+ attr_accessor :status_code, :headers_sent, :finished
38
+ attr_reader :headers
39
+
40
+ def headers=(headers)
41
+ @headers = headers&.each_with_object({}) do |(k, v), hsh|
42
+ hsh[k] = v.to_s
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,59 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ # frozen_string_literal: true
19
+
20
+ module Hoss
21
+ class Context
22
+ # @api private
23
+ class User
24
+ def initialize(id: nil, email: nil, username: nil)
25
+ @id = id
26
+ @email = email
27
+ @username = username
28
+ end
29
+
30
+ def self.infer(config, record)
31
+ return unless record
32
+
33
+ new(
34
+ id: safe_get(record, config.current_user_id_method)&.to_s,
35
+ email: safe_get(record, config.current_user_email_method),
36
+ username: safe_get(record, config.current_user_username_method)
37
+ )
38
+ end
39
+
40
+ attr_accessor :id, :email, :username
41
+
42
+ def empty?
43
+ !id && !email && !username
44
+ end
45
+
46
+ def any?
47
+ !empty?
48
+ end
49
+
50
+ class << self
51
+ private
52
+
53
+ def safe_get(record, method_name)
54
+ record.respond_to?(method_name) ? record.send(method_name) : nil
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,64 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ # frozen_string_literal: true
19
+
20
+ require 'hoss/context/request'
21
+ require 'hoss/context/request/socket'
22
+ require 'hoss/context/request/url'
23
+ require 'hoss/context/response'
24
+ require 'hoss/context/user'
25
+
26
+ module Hoss
27
+ # @api private
28
+ class Context
29
+ def initialize(custom: {}, labels: {}, user: nil, service: nil)
30
+ @custom = custom
31
+ @labels = labels
32
+ @user = user || User.new
33
+ @service = service
34
+ end
35
+
36
+ Service = Struct.new(:framework)
37
+ Framework = Struct.new(:name, :version)
38
+
39
+ attr_accessor :request
40
+ attr_accessor :response
41
+ attr_accessor :user
42
+ attr_reader :custom
43
+ attr_reader :labels
44
+ attr_reader :service
45
+
46
+ # rubocop:disable Metrics/CyclomaticComplexity
47
+ def empty?
48
+ return false if labels.any?
49
+ return false if custom.any?
50
+ return false if user.any?
51
+ return false if service
52
+ return false if request || response
53
+
54
+ true
55
+ end
56
+ # rubocop:enable Metrics/CyclomaticComplexity
57
+
58
+ def set_service(framework_name: nil, framework_version: nil)
59
+ @service = Service.new(
60
+ Framework.new(framework_name, framework_version)
61
+ )
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,112 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ # frozen_string_literal: true
19
+
20
+ module Hoss
21
+ # @api private
22
+ class ContextBuilder
23
+ MAX_BODY_LENGTH = 2048
24
+ SKIPPED = '[SKIPPED]'
25
+
26
+ def initialize(config)
27
+ @config = config
28
+ end
29
+
30
+ attr_reader :config
31
+
32
+ def build(rack_env:, for_type:)
33
+ Context.new.tap do |context|
34
+ apply_to_request(context, rack_env: rack_env, for_type: for_type)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def apply_to_request(context, rack_env:, for_type:)
41
+ req = rails_req?(rack_env) ? rack_env : Rack::Request.new(rack_env)
42
+
43
+ context.request = Context::Request.new unless context.request
44
+ request = context.request
45
+
46
+ request.socket = Context::Request::Socket.new(req)
47
+ request.http_version = build_http_version rack_env
48
+ request.method = req.request_method
49
+ request.url = Context::Request::Url.new(req)
50
+
51
+ request.body = should_capture_body?(for_type) ? get_body(req) : SKIPPED
52
+
53
+ headers, env = get_headers_and_env(rack_env)
54
+ request.headers = headers if config.capture_headers?
55
+ request.env = env if config.capture_env?
56
+
57
+ request.cookies = req.cookies.dup
58
+
59
+ context
60
+ end
61
+
62
+ def should_capture_body?(for_type)
63
+ option = config.capture_body
64
+
65
+ return true if option == 'all'
66
+ return true if option == 'transactions' && for_type == :transaction
67
+ return true if option == 'errors' && for_type == :error
68
+
69
+ false
70
+ end
71
+
72
+ def get_body(req)
73
+ case req.media_type
74
+ when 'application/x-www-form-urlencoded', 'multipart/form-data'
75
+ req.POST.dup
76
+ else
77
+ body = req.body.read
78
+ req.body.rewind
79
+ body.byteslice(0, MAX_BODY_LENGTH).force_encoding('utf-8')
80
+ end
81
+ end
82
+
83
+ def rails_req?(env)
84
+ defined?(ActionDispatch::Request) && env.is_a?(ActionDispatch::Request)
85
+ end
86
+
87
+ def get_headers_and_env(rack_env)
88
+ # In Rails < 5 ActionDispatch::Request inherits from Hash
89
+ headers =
90
+ rack_env.respond_to?(:headers) ? rack_env.headers : rack_env
91
+
92
+ headers.each_with_object([{}, {}]) do |(key, value), (http, env)|
93
+ next unless key == key.upcase
94
+
95
+ if key.start_with?('HTTP_')
96
+ http[camel_key(key)] = value
97
+ else
98
+ env[key] = value
99
+ end
100
+ end
101
+ end
102
+
103
+ def camel_key(key)
104
+ key.gsub(/^HTTP_/, '').split('_').map(&:capitalize).join('-')
105
+ end
106
+
107
+ def build_http_version(rack_env)
108
+ return unless (http_version = rack_env['HTTP_VERSION'])
109
+ http_version.gsub(%r{HTTP/}, '')
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,39 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ # frozen_string_literal: true
19
+
20
+ module Hoss
21
+ # @api private
22
+ module Deprecations
23
+ def deprecate(name, replacement = nil)
24
+ alias_name = "#{name.to_s.chomp('=')}__deprecated_"
25
+ alias_name += '=' if name.to_s.end_with?('=')
26
+
27
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
28
+ alias :"#{alias_name}" :"#{name}"
29
+
30
+ def #{name}(*args, &block)
31
+ warn "[HOSS] [DEPRECATED] `#{name}' is being removed. " \
32
+ "#{replacement && "See `#{replacement}'."}" \
33
+ "\nCalled from \#{caller.first}"
34
+ send("#{alias_name}", *args, &block)
35
+ end
36
+ RUBY
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,70 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ # frozen_string_literal: true
19
+
20
+ module Hoss
21
+ class Error
22
+ # @api private
23
+ class Exception
24
+ MOD_SPLIT = '::'
25
+
26
+ def initialize(attrs = nil)
27
+ return unless attrs
28
+
29
+ attrs.each do |key, val|
30
+ send(:"#{key}=", val)
31
+ end
32
+ end
33
+
34
+ def self.from_exception(exception, **attrs)
35
+ new({
36
+ message: exception.message.to_s,
37
+ type: exception.class.to_s,
38
+ module: format_module(exception),
39
+ cause: exception.cause && Exception.from_exception(exception.cause)
40
+ }.merge(attrs))
41
+ end
42
+
43
+ attr_accessor(
44
+ :attributes,
45
+ :code,
46
+ :handled,
47
+ :message,
48
+ :module,
49
+ :stacktrace,
50
+ :type,
51
+ :cause
52
+ )
53
+
54
+ def inspect
55
+ '<Hoss::Error::Exception' \
56
+ " type:#{type}" \
57
+ " message:#{message}" \
58
+ '>'
59
+ end
60
+
61
+ class << self
62
+ private
63
+
64
+ def format_module(exception)
65
+ exception.class.to_s.split(MOD_SPLIT)[0...-1].join(MOD_SPLIT)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,41 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ # frozen_string_literal: true
19
+
20
+ module Hoss
21
+ class Error
22
+ # @api private
23
+ class Log
24
+ def initialize(message, attrs = {})
25
+ @message = message
26
+
27
+ attrs.each do |key, val|
28
+ send(:"#{key}=", val)
29
+ end
30
+ end
31
+
32
+ attr_accessor(
33
+ :level,
34
+ :logger_name,
35
+ :message,
36
+ :param_message,
37
+ :stacktrace
38
+ )
39
+ end
40
+ end
41
+ end
data/lib/hoss/error.rb ADDED
@@ -0,0 +1,49 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ # frozen_string_literal: true
19
+
20
+ require 'hoss/stacktrace'
21
+ require 'hoss/context'
22
+ require 'hoss/error/exception'
23
+ require 'hoss/error/log'
24
+
25
+ module Hoss
26
+ # @api private
27
+ class Error
28
+ def initialize(culprit: nil, context: nil)
29
+ @id = SecureRandom.hex(16)
30
+ @culprit = culprit
31
+ @timestamp = Util.micros
32
+ @context = context
33
+ end
34
+
35
+ attr_accessor :id, :culprit, :exception, :log, :transaction_id,
36
+ :transaction, :context, :parent_id, :trace_id
37
+ attr_reader :timestamp
38
+
39
+ def inspect
40
+ "<Hoss::Error id:#{id}" \
41
+ " culprit:#{culprit}" \
42
+ " timestamp:#{timestamp}" \
43
+ " transaction_id:#{transaction_id}" \
44
+ " trace_id:#{trace_id}" \
45
+ " exception:#{exception.inspect}" \
46
+ '>'
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,90 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ # frozen_string_literal: true
19
+
20
+ module Hoss
21
+ # @api private
22
+ class ErrorBuilder
23
+ def initialize(agent)
24
+ @agent = agent
25
+ end
26
+
27
+ def build_exception(exception, context: nil, handled: true)
28
+ error = Error.new context: context || Context.new
29
+ error.exception =
30
+ Error::Exception.from_exception(exception, handled: handled)
31
+
32
+ Util.reverse_merge!(error.context.labels, @agent.config.default_labels)
33
+
34
+ if exception.backtrace
35
+ add_stacktrace error, :exception, exception.backtrace
36
+ end
37
+
38
+ add_current_transaction_fields error, Hoss.current_transaction
39
+
40
+ error
41
+ end
42
+
43
+ def build_log(message, context: nil, backtrace: nil, **attrs)
44
+ error = Error.new context: context || Context.new
45
+ error.log = Error::Log.new(message, **attrs)
46
+
47
+ if backtrace
48
+ add_stacktrace error, :log, backtrace
49
+ end
50
+
51
+ add_current_transaction_fields error, Hoss.current_transaction
52
+
53
+ error
54
+ end
55
+
56
+ private
57
+
58
+ def add_stacktrace(error, kind, backtrace)
59
+ stacktrace =
60
+ @agent.stacktrace_builder.build(backtrace, type: :error)
61
+ return unless stacktrace
62
+
63
+ case kind
64
+ when :exception
65
+ error.exception.stacktrace = stacktrace
66
+ when :log
67
+ error.log.stacktrace = stacktrace
68
+ end
69
+
70
+ error.culprit = stacktrace.frames.first&.function
71
+ end
72
+
73
+ def add_current_transaction_fields(error, transaction)
74
+ return unless transaction
75
+
76
+ error.transaction_id = transaction.id
77
+ error.transaction = {
78
+ sampled: transaction.sampled?,
79
+ type: transaction.type
80
+ }
81
+ error.trace_id = transaction.trace_id
82
+ error.parent_id = Hoss.current_span&.id || transaction.id
83
+
84
+ return unless transaction.context
85
+
86
+ Util.reverse_merge!(error.context.labels, transaction.context.labels)
87
+ Util.reverse_merge!(error.context.custom, transaction.context.custom)
88
+ end
89
+ end
90
+ end
data/lib/hoss/event.rb ADDED
@@ -0,0 +1,131 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ # frozen_string_literal: true
19
+
20
+ # require 'hoss/span/context'
21
+
22
+ module Hoss
23
+ # @api private
24
+ class Event
25
+ extend Forwardable
26
+ include ChildDurations::Methods
27
+
28
+ DEFAULT_TYPE = 'custom'
29
+
30
+ class Request
31
+ extend Forwardable
32
+ def initialize
33
+ @headers = {}
34
+ end
35
+ attr_accessor(
36
+ :method,
37
+ :url,
38
+ :headers,
39
+ :body,
40
+ :received_at
41
+ )
42
+ end
43
+
44
+ class Response
45
+ extend Forwardable
46
+ def initialize
47
+ @headers = {}
48
+ end
49
+ attr_accessor(
50
+ :status_code,
51
+ :headers,
52
+ :body,
53
+ :received_at
54
+ )
55
+ end
56
+
57
+ class Error
58
+ extend Forwardable
59
+ ConnectionTimeout = 'CONNECTION_TIMEOUT'
60
+ RequestTimeout = 'REQUEST_TIMEOUT'
61
+ ConnectionError = 'CONNECTION_ERROR'
62
+ def initialize(type)
63
+ @type = type
64
+ end
65
+ attr_accessor(
66
+ :type,
67
+ :received_at
68
+ )
69
+ end
70
+
71
+ # rubocop:disable Metrics/ParameterLists
72
+ def initialize
73
+ @id = SecureRandom.uuid
74
+ @request = Request.new
75
+ # @response = Response.new
76
+ @filtered = false
77
+ @retries = 0
78
+ end
79
+ # rubocop:enable Metrics/ParameterLists
80
+
81
+ attr_accessor(
82
+ :request,
83
+ :response,
84
+ :error,
85
+ :filtered,
86
+ :retries,
87
+ )
88
+
89
+ attr_reader(
90
+ :id
91
+ )
92
+
93
+ # life cycle
94
+
95
+ def start(clock_start = Util.monotonic_micros)
96
+ @timestamp = Util.micros
97
+ @clock_start = clock_start
98
+ self
99
+ end
100
+
101
+ def stop(clock_end = Util.monotonic_micros)
102
+ @duration ||= (clock_end - @clock_start)
103
+ @self_time = @duration - child_durations.duration
104
+ self
105
+ end
106
+
107
+ def done(clock_end: Util.monotonic_micros)
108
+ stop clock_end
109
+ self
110
+ end
111
+
112
+ def stopped?
113
+ !!duration
114
+ end
115
+
116
+ def started?
117
+ !!timestamp
118
+ end
119
+
120
+ def running?
121
+ started? && !stopped?
122
+ end
123
+
124
+ # relations
125
+
126
+ def inspect
127
+ "<Hoss::Event id:#{id.inspect}" \
128
+ '>'
129
+ end
130
+ end
131
+ end