hoss-agent 1.0.11

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 +210 -0
  12. data/lib/hoss.rb +21 -0
  13. data/lib/hoss/agent.rb +235 -0
  14. data/lib/hoss/central_config.rb +184 -0
  15. data/lib/hoss/central_config/cache_control.rb +51 -0
  16. data/lib/hoss/child_durations.rb +64 -0
  17. data/lib/hoss/config.rb +315 -0
  18. data/lib/hoss/config/bytes.rb +42 -0
  19. data/lib/hoss/config/duration.rb +40 -0
  20. data/lib/hoss/config/options.rb +154 -0
  21. data/lib/hoss/config/regexp_list.rb +30 -0
  22. data/lib/hoss/config/wildcard_pattern_list.rb +54 -0
  23. data/lib/hoss/context.rb +64 -0
  24. data/lib/hoss/context/request.rb +28 -0
  25. data/lib/hoss/context/request/socket.rb +36 -0
  26. data/lib/hoss/context/request/url.rb +59 -0
  27. data/lib/hoss/context/response.rb +47 -0
  28. data/lib/hoss/context/user.rb +59 -0
  29. data/lib/hoss/context_builder.rb +112 -0
  30. data/lib/hoss/deprecations.rb +39 -0
  31. data/lib/hoss/error.rb +49 -0
  32. data/lib/hoss/error/exception.rb +70 -0
  33. data/lib/hoss/error/log.rb +41 -0
  34. data/lib/hoss/error_builder.rb +90 -0
  35. data/lib/hoss/event.rb +131 -0
  36. data/lib/hoss/instrumenter.rb +107 -0
  37. data/lib/hoss/internal_error.rb +23 -0
  38. data/lib/hoss/logging.rb +70 -0
  39. data/lib/hoss/metadata.rb +36 -0
  40. data/lib/hoss/metadata/process_info.rb +35 -0
  41. data/lib/hoss/metadata/service_info.rb +76 -0
  42. data/lib/hoss/metadata/system_info.rb +47 -0
  43. data/lib/hoss/metadata/system_info/container_info.rb +136 -0
  44. data/lib/hoss/naively_hashable.rb +38 -0
  45. data/lib/hoss/rails.rb +68 -0
  46. data/lib/hoss/railtie.rb +42 -0
  47. data/lib/hoss/report.rb +9 -0
  48. data/lib/hoss/sinatra.rb +53 -0
  49. data/lib/hoss/spies.rb +104 -0
  50. data/lib/hoss/spies/faraday.rb +117 -0
  51. data/lib/hoss/spies/http.rb +93 -0
  52. data/lib/hoss/spies/net_http.rb +113 -0
  53. data/lib/hoss/stacktrace.rb +33 -0
  54. data/lib/hoss/stacktrace/frame.rb +66 -0
  55. data/lib/hoss/stacktrace_builder.rb +124 -0
  56. data/lib/hoss/transport/base.rb +191 -0
  57. data/lib/hoss/transport/connection.rb +55 -0
  58. data/lib/hoss/transport/connection/http.rb +139 -0
  59. data/lib/hoss/transport/connection/proxy_pipe.rb +94 -0
  60. data/lib/hoss/transport/filters.rb +60 -0
  61. data/lib/hoss/transport/filters/hash_sanitizer.rb +77 -0
  62. data/lib/hoss/transport/filters/secrets_filter.rb +48 -0
  63. data/lib/hoss/transport/headers.rb +74 -0
  64. data/lib/hoss/transport/serializers.rb +113 -0
  65. data/lib/hoss/transport/serializers/context_serializer.rb +112 -0
  66. data/lib/hoss/transport/serializers/error_serializer.rb +92 -0
  67. data/lib/hoss/transport/serializers/event_serializer.rb +73 -0
  68. data/lib/hoss/transport/serializers/metadata_serializer.rb +92 -0
  69. data/lib/hoss/transport/serializers/report_serializer.rb +33 -0
  70. data/lib/hoss/transport/user_agent.rb +48 -0
  71. data/lib/hoss/transport/worker.rb +330 -0
  72. data/lib/hoss/util.rb +54 -0
  73. data/lib/hoss/util/inflector.rb +110 -0
  74. data/lib/hoss/util/lru_cache.rb +65 -0
  75. data/lib/hoss/util/throttle.rb +52 -0
  76. data/lib/hoss/version.rb +22 -0
  77. metadata +147 -0
@@ -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
@@ -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
@@ -0,0 +1,107 @@
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/child_durations'
21
+ require 'hoss/event'
22
+
23
+ module Hoss
24
+ # @api private
25
+ class Instrumenter
26
+ EVENT_KEY = :__elastic_instrumenter_events_key
27
+
28
+ include Logging
29
+
30
+ # @api private
31
+ class Current
32
+ def initialize
33
+ self.events = []
34
+ end
35
+
36
+ def events
37
+ Thread.current[EVENT_KEY] ||= []
38
+ end
39
+
40
+ def events=(events)
41
+ Thread.current[EVENT_KEY] ||= []
42
+ Thread.current[EVENT_KEY] = events
43
+ end
44
+ end
45
+
46
+ def initialize(config, metrics:, stacktrace_builder:, &enqueue)
47
+ @config = config
48
+ @stacktrace_builder = stacktrace_builder
49
+ @enqueue = enqueue
50
+ @metrics = metrics
51
+
52
+ @current = Current.new
53
+ end
54
+
55
+ attr_reader :stacktrace_builder, :enqueue
56
+
57
+ def start
58
+ debug 'Starting instrumenter'
59
+ # We call register! on @subscriber in case the
60
+ # instrumenter was stopped and started again
61
+ @subscriber&.register!
62
+ end
63
+
64
+ def stop
65
+ debug 'Stopping instrumenter'
66
+
67
+ current_events.pop until current_events.empty?
68
+
69
+ @subscriber&.unregister!
70
+ end
71
+
72
+ def handle_forking!
73
+ stop
74
+ start
75
+ end
76
+
77
+ def subscriber=(subscriber)
78
+ debug 'Registering subscriber'
79
+ @subscriber = subscriber
80
+ @subscriber.register!
81
+ end
82
+
83
+
84
+ # events
85
+
86
+ def current_events
87
+ @current.events
88
+ end
89
+
90
+ def current_event
91
+ current_events.last
92
+ end
93
+
94
+ def start_event
95
+ event = Event.new
96
+ current_events.push event
97
+ event.start
98
+ end
99
+
100
+ def end_event
101
+ return unless (event = current_events.pop)
102
+ event.done
103
+ enqueue.call event
104
+ event
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,23 @@
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 InternalError < StandardError; end
22
+ class ExistingTransactionError < InternalError; end
23
+ 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
+ # @api private
22
+ module Logging
23
+ PREFIX = '[Hoss] '
24
+
25
+ LEVELS = {
26
+ debug: Logger::DEBUG,
27
+ info: Logger::INFO,
28
+ warn: Logger::WARN,
29
+ error: Logger::ERROR,
30
+ fatal: Logger::FATAL
31
+ }.freeze
32
+
33
+ def debug(msg, *args, &block)
34
+ log(:debug, msg, *args, &block)
35
+ end
36
+
37
+ def info(msg, *args, &block)
38
+ log(:info, msg, *args, &block)
39
+ end
40
+
41
+ def warn(msg, *args, &block)
42
+ log(:warn, msg, *args, &block)
43
+ end
44
+
45
+ def error(msg, *args, &block)
46
+ log(:error, msg, *args, &block)
47
+ end
48
+
49
+ def fatal(msg, *args, &block)
50
+ log(:fatal, msg, *args, &block)
51
+ end
52
+
53
+ private
54
+
55
+ def log(lvl, msg, *args)
56
+ return unless (logger = @config&.logger)
57
+ return unless LEVELS[lvl] >= (@config&.log_level || 0)
58
+
59
+ formatted_msg = prepend_prefix(format(msg.to_s, *args))
60
+
61
+ return logger.send(lvl, formatted_msg) unless block_given?
62
+
63
+ logger.send(lvl, "#{formatted_msg}\n#{yield}")
64
+ end
65
+
66
+ def prepend_prefix(str)
67
+ "#{PREFIX}#{str}"
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,36 @@
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 Metadata
23
+ def initialize(config)
24
+ @service = ServiceInfo.new(config)
25
+ @process = ProcessInfo.new(config)
26
+ @system = SystemInfo.new(config)
27
+ @labels = config.global_labels
28
+ end
29
+
30
+ attr_reader :service, :process, :system, :labels
31
+ end
32
+ end
33
+
34
+ require 'hoss/metadata/service_info'
35
+ require 'hoss/metadata/system_info'
36
+ require 'hoss/metadata/process_info'