hoss-agent 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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 +210 -0
- data/lib/hoss.rb +21 -0
- data/lib/hoss/agent.rb +235 -0
- data/lib/hoss/central_config.rb +184 -0
- data/lib/hoss/central_config/cache_control.rb +51 -0
- data/lib/hoss/child_durations.rb +64 -0
- data/lib/hoss/config.rb +315 -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/context.rb +64 -0
- data/lib/hoss/context/request.rb +28 -0
- data/lib/hoss/context/request/socket.rb +36 -0
- data/lib/hoss/context/request/url.rb +59 -0
- data/lib/hoss/context/response.rb +47 -0
- data/lib/hoss/context/user.rb +59 -0
- data/lib/hoss/context_builder.rb +112 -0
- data/lib/hoss/deprecations.rb +39 -0
- data/lib/hoss/error.rb +49 -0
- data/lib/hoss/error/exception.rb +70 -0
- data/lib/hoss/error/log.rb +41 -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.rb +36 -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.rb +47 -0
- data/lib/hoss/metadata/system_info/container_info.rb +136 -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.rb +104 -0
- data/lib/hoss/spies/faraday.rb +106 -0
- data/lib/hoss/spies/http.rb +86 -0
- data/lib/hoss/spies/net_http.rb +101 -0
- data/lib/hoss/stacktrace.rb +33 -0
- data/lib/hoss/stacktrace/frame.rb +66 -0
- data/lib/hoss/stacktrace_builder.rb +124 -0
- data/lib/hoss/transport/base.rb +191 -0
- data/lib/hoss/transport/connection.rb +55 -0
- data/lib/hoss/transport/connection/http.rb +139 -0
- data/lib/hoss/transport/connection/proxy_pipe.rb +94 -0
- data/lib/hoss/transport/filters.rb +60 -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/headers.rb +74 -0
- data/lib/hoss/transport/serializers.rb +113 -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/user_agent.rb +48 -0
- data/lib/hoss/transport/worker.rb +330 -0
- data/lib/hoss/util.rb +54 -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/version.rb +22 -0
- metadata +147 -0
@@ -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,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,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
|
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,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
|