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.
- checksums.yaml +7 -0
- data/.github/ISSUE_TEMPLATE/Bug_report.md +40 -0
- data/.github/ISSUE_TEMPLATE/Feature_request.md +17 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +60 -0
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/Dockerfile +43 -0
- data/Gemfile +105 -0
- data/LICENSE +201 -0
- data/hoss-agent.gemspec +42 -0
- data/lib/hoss/agent.rb +231 -0
- data/lib/hoss/central_config/cache_control.rb +51 -0
- data/lib/hoss/central_config.rb +184 -0
- data/lib/hoss/child_durations.rb +64 -0
- data/lib/hoss/config/bytes.rb +42 -0
- data/lib/hoss/config/duration.rb +40 -0
- data/lib/hoss/config/options.rb +154 -0
- data/lib/hoss/config/regexp_list.rb +30 -0
- data/lib/hoss/config/wildcard_pattern_list.rb +54 -0
- data/lib/hoss/config.rb +304 -0
- data/lib/hoss/context/request/socket.rb +36 -0
- data/lib/hoss/context/request/url.rb +59 -0
- data/lib/hoss/context/request.rb +28 -0
- data/lib/hoss/context/response.rb +47 -0
- data/lib/hoss/context/user.rb +59 -0
- data/lib/hoss/context.rb +64 -0
- data/lib/hoss/context_builder.rb +112 -0
- data/lib/hoss/deprecations.rb +39 -0
- data/lib/hoss/error/exception.rb +70 -0
- data/lib/hoss/error/log.rb +41 -0
- data/lib/hoss/error.rb +49 -0
- data/lib/hoss/error_builder.rb +90 -0
- data/lib/hoss/event.rb +131 -0
- data/lib/hoss/instrumenter.rb +107 -0
- data/lib/hoss/internal_error.rb +23 -0
- data/lib/hoss/logging.rb +70 -0
- data/lib/hoss/metadata/process_info.rb +35 -0
- data/lib/hoss/metadata/service_info.rb +76 -0
- data/lib/hoss/metadata/system_info/container_info.rb +136 -0
- data/lib/hoss/metadata/system_info.rb +47 -0
- data/lib/hoss/metadata.rb +36 -0
- data/lib/hoss/naively_hashable.rb +38 -0
- data/lib/hoss/rails.rb +68 -0
- data/lib/hoss/railtie.rb +42 -0
- data/lib/hoss/report.rb +9 -0
- data/lib/hoss/sinatra.rb +53 -0
- data/lib/hoss/spies/faraday.rb +102 -0
- data/lib/hoss/spies/http.rb +81 -0
- data/lib/hoss/spies/net_http.rb +97 -0
- data/lib/hoss/spies.rb +104 -0
- data/lib/hoss/stacktrace/frame.rb +66 -0
- data/lib/hoss/stacktrace.rb +33 -0
- data/lib/hoss/stacktrace_builder.rb +124 -0
- data/lib/hoss/transport/base.rb +191 -0
- data/lib/hoss/transport/connection/http.rb +139 -0
- data/lib/hoss/transport/connection/proxy_pipe.rb +94 -0
- data/lib/hoss/transport/connection.rb +55 -0
- data/lib/hoss/transport/filters/hash_sanitizer.rb +77 -0
- data/lib/hoss/transport/filters/secrets_filter.rb +48 -0
- data/lib/hoss/transport/filters.rb +60 -0
- data/lib/hoss/transport/headers.rb +74 -0
- data/lib/hoss/transport/serializers/context_serializer.rb +112 -0
- data/lib/hoss/transport/serializers/error_serializer.rb +92 -0
- data/lib/hoss/transport/serializers/event_serializer.rb +73 -0
- data/lib/hoss/transport/serializers/metadata_serializer.rb +92 -0
- data/lib/hoss/transport/serializers/report_serializer.rb +33 -0
- data/lib/hoss/transport/serializers.rb +113 -0
- data/lib/hoss/transport/user_agent.rb +48 -0
- data/lib/hoss/transport/worker.rb +319 -0
- data/lib/hoss/util/inflector.rb +110 -0
- data/lib/hoss/util/lru_cache.rb +65 -0
- data/lib/hoss/util/throttle.rb +52 -0
- data/lib/hoss/util.rb +54 -0
- data/lib/hoss/version.rb +22 -0
- data/lib/hoss-agent.rb +210 -0
- data/lib/hoss.rb +21 -0
- metadata +147 -0
@@ -0,0 +1,154 @@
|
|
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 Config
|
22
|
+
# @api private
|
23
|
+
module Options
|
24
|
+
# @api private
|
25
|
+
class Option
|
26
|
+
def initialize(
|
27
|
+
key,
|
28
|
+
value: nil,
|
29
|
+
type: :string,
|
30
|
+
default: nil,
|
31
|
+
converter: nil
|
32
|
+
)
|
33
|
+
@key = key
|
34
|
+
@type = type
|
35
|
+
@default = default
|
36
|
+
@converter = converter
|
37
|
+
|
38
|
+
set(value || default)
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :key, :value, :default, :type
|
42
|
+
|
43
|
+
def set(value)
|
44
|
+
@value = normalize(value)
|
45
|
+
end
|
46
|
+
|
47
|
+
def env_key
|
48
|
+
"HOSS_#{key.upcase}"
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
54
|
+
def normalize(val)
|
55
|
+
return if val.nil?
|
56
|
+
|
57
|
+
if @converter
|
58
|
+
return @converter.call(val)
|
59
|
+
end
|
60
|
+
|
61
|
+
case type
|
62
|
+
when :string then val.to_s
|
63
|
+
when :int then val.to_i
|
64
|
+
when :float then val.to_f
|
65
|
+
when :bool then normalize_bool(val)
|
66
|
+
when :list then normalize_list(val)
|
67
|
+
when :dict then normalize_dict(val)
|
68
|
+
when :url then normalize_url(val)
|
69
|
+
else
|
70
|
+
# raise "Unknown options type '#{type.inspect}'"
|
71
|
+
val
|
72
|
+
end
|
73
|
+
end
|
74
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
75
|
+
|
76
|
+
def normalize_bool(val)
|
77
|
+
return val unless val.is_a?(String)
|
78
|
+
!%w[0 false].include?(val.strip.downcase)
|
79
|
+
end
|
80
|
+
|
81
|
+
def normalize_list(val)
|
82
|
+
return Array(val) unless val.is_a?(String)
|
83
|
+
val.split(/[ ,]/)
|
84
|
+
end
|
85
|
+
|
86
|
+
def normalize_dict(val)
|
87
|
+
return val unless val.is_a?(String)
|
88
|
+
Hash[val.split(/[&,]/).map { |kv| kv.split('=') }]
|
89
|
+
end
|
90
|
+
|
91
|
+
def normalize_url(val)
|
92
|
+
val = val.to_s
|
93
|
+
val.end_with?('/') ? val.chomp('/') : val
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# @api private
|
98
|
+
module ClassMethods
|
99
|
+
def schema
|
100
|
+
@schema ||= {}
|
101
|
+
end
|
102
|
+
|
103
|
+
def option(key, **args)
|
104
|
+
schema[key] = args
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# @api private
|
109
|
+
module InstanceMethods
|
110
|
+
def load_schema
|
111
|
+
Hash[self.class.schema.map do |key, args|
|
112
|
+
[key, Option.new(key, **args)]
|
113
|
+
end]
|
114
|
+
end
|
115
|
+
|
116
|
+
def method_missing(name, *value)
|
117
|
+
name_str = name.to_s
|
118
|
+
|
119
|
+
if name_str.end_with?('=')
|
120
|
+
key = name_str[0...-1].to_sym
|
121
|
+
set(key, value.first)
|
122
|
+
|
123
|
+
elsif name_str.end_with?('?')
|
124
|
+
key = name_str[0...-1].to_sym
|
125
|
+
options.key?(key) ? options[key].value : super
|
126
|
+
|
127
|
+
elsif options.key?(name)
|
128
|
+
options.fetch(name).value
|
129
|
+
|
130
|
+
else
|
131
|
+
super
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def [](key)
|
136
|
+
options[key]
|
137
|
+
end
|
138
|
+
alias :get :[]
|
139
|
+
|
140
|
+
def set(key, value)
|
141
|
+
options.fetch(key.to_sym).set(value)
|
142
|
+
rescue KeyError
|
143
|
+
warn format("Unknown option '%s'", key)
|
144
|
+
nil
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.extended(kls)
|
149
|
+
kls.instance_eval { extend ClassMethods }
|
150
|
+
kls.class_eval { include InstanceMethods }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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 Config
|
22
|
+
# @api private
|
23
|
+
class RegexpList
|
24
|
+
def call(value)
|
25
|
+
value = value.is_a?(String) ? value.split(',') : Array(value)
|
26
|
+
value.map(&Regexp.method(:new))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,54 @@
|
|
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 Config
|
22
|
+
# @api private
|
23
|
+
class WildcardPatternList
|
24
|
+
# @api private
|
25
|
+
class WildcardPattern
|
26
|
+
def initialize(str)
|
27
|
+
@pattern = convert(str)
|
28
|
+
end
|
29
|
+
|
30
|
+
def match?(other)
|
31
|
+
!!@pattern.match(other)
|
32
|
+
end
|
33
|
+
|
34
|
+
alias :match :match?
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def convert(str)
|
39
|
+
parts =
|
40
|
+
str.chars.each_with_object([]) do |char, arr|
|
41
|
+
arr << (char == '*' ? '.*' : Regexp.escape(char))
|
42
|
+
end
|
43
|
+
|
44
|
+
Regexp.new('\A' + parts.join + '\Z', Regexp::IGNORECASE)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def call(value)
|
49
|
+
value = value.is_a?(String) ? value.split(',') : Array(value)
|
50
|
+
value.map(&WildcardPattern.method(:new))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/hoss/config.rb
ADDED
@@ -0,0 +1,304 @@
|
|
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/config/options'
|
21
|
+
require 'hoss/config/duration'
|
22
|
+
require 'hoss/config/bytes'
|
23
|
+
require 'hoss/config/regexp_list'
|
24
|
+
require 'hoss/config/wildcard_pattern_list'
|
25
|
+
|
26
|
+
module Hoss
|
27
|
+
# @api private
|
28
|
+
class Config
|
29
|
+
extend Options
|
30
|
+
|
31
|
+
DEPRECATED_OPTIONS = %i[].freeze
|
32
|
+
|
33
|
+
# rubocop:disable Metrics/LineLength, Layout/ExtraSpacing
|
34
|
+
option :config_file, type: :string, default: 'config/hoss.yml'
|
35
|
+
option :api_host, type: :url, default: ENV['HOSS_API_HOST'] || 'https://app.hoss.com'
|
36
|
+
option :api_key, type: :string
|
37
|
+
option :ingress_host, type: :string, default: ENV['HOSS_INGRESS_HOST'] || 'https://ingress.hoss.com/v1'
|
38
|
+
option :max_queue_size, type: :int, default: 3000
|
39
|
+
option :batch_size, type: :int, default: ENV['HOSS_BATCH_SIZE'] || 512000
|
40
|
+
option :max_event_retries, type: :int, default: 100
|
41
|
+
option :remote_config_fetch_interval, type: :int, default: 300
|
42
|
+
option :agentConfig, type: :dict
|
43
|
+
|
44
|
+
|
45
|
+
option :central_config, type: :bool, default: true
|
46
|
+
option :capture_body, type: :string, default: 'off'
|
47
|
+
option :capture_headers, type: :bool, default: true
|
48
|
+
option :capture_env, type: :bool, default: true
|
49
|
+
option :current_user_email_method, type: :string, default: 'email'
|
50
|
+
option :current_user_id_method, type: :string, default: 'id'
|
51
|
+
option :current_user_username_method, type: :string, default: 'username'
|
52
|
+
option :custom_key_filters, type: :list, default: [], converter: RegexpList.new
|
53
|
+
option :default_labels, type: :dict, default: {}
|
54
|
+
option :disable_start_message, type: :bool, default: false
|
55
|
+
option :disable_instrumentations, type: :list, default: %w[]
|
56
|
+
option :enabled, type: :bool, default: true
|
57
|
+
option :environment, type: :string, default: ENV['RAILS_ENV'] || ENV['RACK_ENV']
|
58
|
+
option :framework_name, type: :string
|
59
|
+
option :framework_version, type: :string
|
60
|
+
option :filter_exception_types, type: :list, default: []
|
61
|
+
option :global_labels, type: :dict
|
62
|
+
option :hostname, type: :string
|
63
|
+
option :http_compression, type: :bool, default: true
|
64
|
+
option :instrument, type: :bool, default: true
|
65
|
+
option :log_level, type: :int, default: Logger::DEBUG
|
66
|
+
option :log_path, type: :string, default: '-'
|
67
|
+
option :pool_size, type: :int, default: 1
|
68
|
+
option :proxy_address, type: :string
|
69
|
+
option :proxy_headers, type: :dict
|
70
|
+
option :proxy_password, type: :string
|
71
|
+
option :proxy_port, type: :int
|
72
|
+
option :proxy_username, type: :string
|
73
|
+
option :recording, type: :bool, default: true
|
74
|
+
option :sanitize_field_names, type: :list, default: [], converter: WildcardPatternList.new
|
75
|
+
option :server_ca_cert, type: :string
|
76
|
+
option :service_name, type: :string
|
77
|
+
option :service_node_name, type: :string
|
78
|
+
option :service_version, type: :string
|
79
|
+
option :span_frames_min_duration, type: :float, default: '5ms', converter: Duration.new(default_unit: 'ms')
|
80
|
+
option :stack_trace_limit, type: :int, default: 999_999
|
81
|
+
option :verify_server_cert, type: :bool, default: true
|
82
|
+
|
83
|
+
# rubocop:enable Metrics/LineLength, Layout/ExtraSpacing
|
84
|
+
def initialize(options = {})
|
85
|
+
@options = load_schema
|
86
|
+
|
87
|
+
if options.is_a? String
|
88
|
+
assign(api_key: options)
|
89
|
+
else
|
90
|
+
assign(options)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Pick out config_file specifically as we need it now to load it,
|
94
|
+
# but still need the other env vars to have precedence
|
95
|
+
env = load_env
|
96
|
+
if (env_config_file = env.delete(:config_file))
|
97
|
+
self.config_file = env_config_file
|
98
|
+
end
|
99
|
+
|
100
|
+
assign(load_config_file)
|
101
|
+
assign(env)
|
102
|
+
|
103
|
+
warn '[HOSS] No API Key provided' unless self.api_key
|
104
|
+
|
105
|
+
yield self if block_given?
|
106
|
+
|
107
|
+
self.logger ||= build_logger
|
108
|
+
|
109
|
+
@__view_paths ||= []
|
110
|
+
@__root_path ||= Dir.pwd
|
111
|
+
end
|
112
|
+
|
113
|
+
attr_accessor :__view_paths, :__root_path
|
114
|
+
attr_accessor :logger
|
115
|
+
|
116
|
+
attr_reader :options
|
117
|
+
|
118
|
+
def assign(update)
|
119
|
+
return unless update
|
120
|
+
update.each { |key, value| send(:"#{key}=", value) }
|
121
|
+
end
|
122
|
+
|
123
|
+
def available_instrumentations
|
124
|
+
%w[
|
125
|
+
http
|
126
|
+
net_http
|
127
|
+
faraday
|
128
|
+
]
|
129
|
+
end
|
130
|
+
|
131
|
+
def enabled_instrumentations
|
132
|
+
available_instrumentations - disable_instrumentations
|
133
|
+
end
|
134
|
+
|
135
|
+
def method_missing(name, *args)
|
136
|
+
return super unless DEPRECATED_OPTIONS.include?(name)
|
137
|
+
warn "The option `#{name}' has been removed."
|
138
|
+
end
|
139
|
+
|
140
|
+
def replace_options(new_options)
|
141
|
+
return if new_options.nil? || new_options.empty?
|
142
|
+
options_copy = @options.dup
|
143
|
+
new_options.each do |key, value|
|
144
|
+
options_copy.fetch(key.to_sym).set(value)
|
145
|
+
end
|
146
|
+
@options = options_copy
|
147
|
+
end
|
148
|
+
|
149
|
+
def app=(app)
|
150
|
+
case app_type?(app)
|
151
|
+
when :sinatra
|
152
|
+
set_sinatra(app)
|
153
|
+
when :rails
|
154
|
+
set_rails(app)
|
155
|
+
else
|
156
|
+
self.service_name = 'ruby'
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def use_ssl?
|
161
|
+
api_host.start_with?('https')
|
162
|
+
end
|
163
|
+
|
164
|
+
def span_frames_min_duration?
|
165
|
+
span_frames_min_duration != 0
|
166
|
+
end
|
167
|
+
|
168
|
+
def span_frames_min_duration=(value)
|
169
|
+
super
|
170
|
+
@span_frames_min_duration_us = nil
|
171
|
+
end
|
172
|
+
|
173
|
+
def span_frames_min_duration_us
|
174
|
+
@span_frames_min_duration_us ||= span_frames_min_duration * 1_000_000
|
175
|
+
end
|
176
|
+
|
177
|
+
def ssl_context
|
178
|
+
return unless use_ssl?
|
179
|
+
|
180
|
+
@ssl_context ||=
|
181
|
+
OpenSSL::SSL::SSLContext.new.tap do |context|
|
182
|
+
if server_ca_cert
|
183
|
+
context.ca_file = server_ca_cert
|
184
|
+
else
|
185
|
+
context.cert_store =
|
186
|
+
OpenSSL::X509::Store.new.tap(&:set_default_paths)
|
187
|
+
end
|
188
|
+
|
189
|
+
context.verify_mode =
|
190
|
+
if verify_server_cert
|
191
|
+
OpenSSL::SSL::VERIFY_PEER
|
192
|
+
else
|
193
|
+
OpenSSL::SSL::VERIFY_NONE
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def inspect
|
199
|
+
super.split.first + '>'
|
200
|
+
end
|
201
|
+
|
202
|
+
# Deprecations
|
203
|
+
|
204
|
+
def default_tags=(value)
|
205
|
+
warn '[DEPRECATED] The option default_tags has been renamed to ' \
|
206
|
+
'default_labels.'
|
207
|
+
self.default_labels = value
|
208
|
+
end
|
209
|
+
|
210
|
+
def custom_key_filters=(value)
|
211
|
+
unless value == self.class.schema[:custom_key_filters][:default]
|
212
|
+
warn '[DEPRECATED] The option custom_key_filters is being removed. ' \
|
213
|
+
'See sanitize_field_names for an alternative.'
|
214
|
+
end
|
215
|
+
|
216
|
+
set(:custom_key_filters, value)
|
217
|
+
end
|
218
|
+
|
219
|
+
def disabled_instrumentations
|
220
|
+
disable_instrumentations
|
221
|
+
end
|
222
|
+
|
223
|
+
def active
|
224
|
+
enabled
|
225
|
+
end
|
226
|
+
alias active? active
|
227
|
+
|
228
|
+
def disabled_instrumentations=(value)
|
229
|
+
warn '[DEPRECATED] The option disabled_instrumentations has been ' \
|
230
|
+
'renamed to disable_instrumentations to align with other agents.'
|
231
|
+
self.disable_instrumentations = value
|
232
|
+
end
|
233
|
+
|
234
|
+
def active=(value)
|
235
|
+
warn '[DEPRECATED] The option active has been renamed to enabled ' \
|
236
|
+
'to align with other agents and with the remote config.'
|
237
|
+
self.enabled = value
|
238
|
+
end
|
239
|
+
|
240
|
+
private
|
241
|
+
|
242
|
+
def load_config_file
|
243
|
+
filename = File.join(@__root_path || Dir.pwd, config_file)
|
244
|
+
return unless File.exist?(filename)
|
245
|
+
read = File.read(filename)
|
246
|
+
evaled = ERB.new(read).result
|
247
|
+
YAML.safe_load(evaled)
|
248
|
+
end
|
249
|
+
|
250
|
+
def load_env
|
251
|
+
@options.values.each_with_object({}) do |option, opts|
|
252
|
+
next unless (value = ENV[option.env_key])
|
253
|
+
opts[option.key] = value
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def build_logger
|
258
|
+
Logger.new(log_path == '-' ? STDOUT : log_path).tap do |logger|
|
259
|
+
logger.level = log_level
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def app_type?(app)
|
264
|
+
if defined?(::Rails::Application) && app.is_a?(::Rails::Application)
|
265
|
+
return :rails
|
266
|
+
end
|
267
|
+
|
268
|
+
if app.is_a?(Class) && app.superclass.to_s == 'Sinatra::Base'
|
269
|
+
return :sinatra
|
270
|
+
end
|
271
|
+
|
272
|
+
nil
|
273
|
+
end
|
274
|
+
|
275
|
+
def set_sinatra(app)
|
276
|
+
self.service_name = format_name(service_name || app.to_s)
|
277
|
+
self.framework_name = framework_name || 'Sinatra'
|
278
|
+
self.framework_version = framework_version || ::Sinatra::VERSION
|
279
|
+
self.__root_path = Dir.pwd
|
280
|
+
end
|
281
|
+
|
282
|
+
def set_rails(app)
|
283
|
+
self.service_name ||= format_name(service_name || rails_app_name(app))
|
284
|
+
self.framework_name ||= 'Ruby on Rails'
|
285
|
+
self.framework_version ||= ::Rails::VERSION::STRING
|
286
|
+
self.logger ||= ::Rails.logger
|
287
|
+
|
288
|
+
self.__root_path = ::Rails.root.to_s
|
289
|
+
self.__view_paths = app.config.paths['app/views'].existent
|
290
|
+
end
|
291
|
+
|
292
|
+
def rails_app_name(app)
|
293
|
+
if ::Rails::VERSION::MAJOR >= 6
|
294
|
+
app.class.module_parent_name
|
295
|
+
else
|
296
|
+
app.class.parent_name
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
def format_name(str)
|
301
|
+
str&.gsub('::', '_')
|
302
|
+
end
|
303
|
+
end
|
304
|
+
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 Context
|
23
|
+
# @api private
|
24
|
+
class Request
|
25
|
+
# @api private
|
26
|
+
class Socket
|
27
|
+
def initialize(req)
|
28
|
+
@remote_addr = req.env['REMOTE_ADDR']
|
29
|
+
@encrypted = req.scheme == 'https'
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :remote_addr, :encrypted
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
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
|
+
# @api private
|
22
|
+
class Context
|
23
|
+
# @api private
|
24
|
+
class Request
|
25
|
+
# @api private
|
26
|
+
class Url
|
27
|
+
SKIPPED_PORTS = {
|
28
|
+
'http' => 80,
|
29
|
+
'https' => 443
|
30
|
+
}.freeze
|
31
|
+
|
32
|
+
def initialize(req)
|
33
|
+
@protocol = req.scheme
|
34
|
+
@hostname = req.host
|
35
|
+
@port = req.port.to_s
|
36
|
+
@pathname = req.path
|
37
|
+
@search = req.query_string
|
38
|
+
@hash = nil
|
39
|
+
@full = build_full_url req
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :protocol, :hostname, :port, :pathname, :search, :hash,
|
43
|
+
:full
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def build_full_url(req)
|
48
|
+
url = "#{req.scheme}://#{req.host}"
|
49
|
+
|
50
|
+
if req.port != SKIPPED_PORTS[req.scheme]
|
51
|
+
url += ":#{req.port}"
|
52
|
+
end
|
53
|
+
|
54
|
+
url + req.fullpath
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,28 @@
|
|
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 Request
|
24
|
+
attr_accessor :body, :cookies, :env, :headers, :http_version, :method,
|
25
|
+
:socket, :url
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|