semantic_logger_ecs_addon 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9d56d0ab9e926ca66fd4889271eb4b5157b41b2b6719b6fc22ebf2acd29745eb
4
+ data.tar.gz: 518de9e56bd832649fdf2cda28da0a0453461bafa2895ac9cf4169058625d817
5
+ SHA512:
6
+ metadata.gz: ca8f68e438c4f018e1205b513455120f8b8cefbe311b980614e4a7f739672391362b58203d99696b4d51a21e80f726488ffcb6d03893ec277822fd0caa00e47a
7
+ data.tar.gz: 30f219878394f83e632e222241a23323cb090323faafe86a0dccb0d430ad7cc4cea95cd942db3070e892b5765f911f6bd4f53893b66a64b992fd97124420f1a4
checksums.yaml.gz.sig ADDED
Binary file
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ ��=3�D�od��q&|}!������UE��d��"��0��}�J�ۮNg����{�P��GL���"���C<aB�{X����:��V�n`���g>�������O�'�\�H�`�O���$����G�i�<�;�8�-�m&�B9�`.+�p BNl�,�&���\��*���WfvI%���\����k�D愕ւo�d���@�B�P
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2021 [Illuminate Software Solutions](https://illuminate.ae).
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ <p align="center">
2
+ <img src="semantic_logger_ecs_addon.png" alt="Semantic Logger Ecs Addon Icon"/>
3
+ </p>
4
+
5
+ # Semantic Logger Ecs Addon
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/semantic_logger_ecs_addon.svg)](http://badge.fury.io/rb/semantic_logger_ecs_addon)
8
+ [![Alchemists Style Guide](https://img.shields.io/badge/code_style-alchemists-brightgreen.svg)](https://www.alchemists.io/projects/code_quality)
9
+
10
+ <!-- Tocer[start]: Auto-generated, don't remove. -->
11
+
12
+ ## Table of Contents
13
+
14
+ - [Features](#features)
15
+ - [Screencasts](#screencasts)
16
+ - [Requirements](#requirements)
17
+ - [Setup](#setup)
18
+ - [Usage](#usage)
19
+ - [Development](#development)
20
+ - [Tests](#tests)
21
+ - [Versioning](#versioning)
22
+ - [Code of Conduct](#code-of-conduct)
23
+ - [Contributions](#contributions)
24
+ - [License](#license)
25
+ - [History](#history)
26
+ - [Credits](#credits)
27
+
28
+ <!-- Tocer[finish]: Auto-generated, don't remove. -->
29
+
30
+ ## Features
31
+
32
+ ## Screencasts
33
+
34
+ ## Requirements
35
+
36
+ 1. [Ruby](https://www.ruby-lang.org)
37
+
38
+ ## Setup
39
+
40
+ To install, run:
41
+
42
+ gem install semantic_logger_ecs_addon
43
+
44
+ Add the following to your Gemfile:
45
+
46
+ gem "semantic_logger_ecs_addon"
47
+
48
+ ## Usage
49
+
50
+ ## Development
51
+
52
+ To contribute, run:
53
+
54
+ git clone https://github.com/thorion3006/semantic_logger_ecs_addon.git
55
+ cd semantic_logger_ecs_addon
56
+ bin/setup
57
+
58
+ You can also use the IRB console for direct access to all objects:
59
+
60
+ bin/console
61
+
62
+ ## Tests
63
+
64
+ To test, run:
65
+
66
+ bundle exec rake
67
+
68
+ ## Versioning
69
+
70
+ Read [Semantic Versioning](https://semver.org) for details. Briefly, it means:
71
+
72
+ - Major (X.y.z) - Incremented for any backwards incompatible public API changes.
73
+ - Minor (x.Y.z) - Incremented for new, backwards compatible, public API enhancements/fixes.
74
+ - Patch (x.y.Z) - Incremented for small, backwards compatible, bug fixes.
75
+
76
+ ## Code of Conduct
77
+
78
+ Please note that this project is released with a [CODE OF CONDUCT](CODE_OF_CONDUCT.md). By
79
+ participating in this project you agree to abide by its terms.
80
+
81
+ ## Contributions
82
+
83
+ Read [CONTRIBUTING](CONTRIBUTING.md) for details.
84
+
85
+ ## License
86
+
87
+ Copyright 2021 [Illuminate Software Solutions](https://illuminate.ae).
88
+ Read [LICENSE](LICENSE.md) for details.
89
+
90
+ ## History
91
+
92
+ Read [CHANGES](CHANGES.md) for details.
93
+ Built with [Gemsmith](https://www.alchemists.io/projects/gemsmith).
94
+
95
+ ## Credits
96
+
97
+ Developed by [Sajeev Ramasamy]() at
98
+ [Illuminate Software Solutions](https://illuminate.ae).
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ require "zeitwerk"
5
+
6
+ loader = Zeitwerk::Loader.for_gem
7
+ loader.setup
8
+
9
+ # Main namespace.
10
+ module SemanticLoggerEcsAddon
11
+ RootPath = Pathname.getwd
12
+ BacktraceCleaner = Utils::BacktraceCleaner.new
13
+ BacktraceCleaner.add_filter { |line| line.gsub(RootPath.to_s, "") }
14
+ BacktraceCleaner.add_silencer { |line| %r(puma|ruby/gems|rubygems).match?(line) }
15
+ end
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "semantic_logger/formatters/base"
4
+
5
+ module SemanticLoggerEcsAddon
6
+ module Formatters
7
+ class Base < SemanticLogger::Formatters::Base
8
+ # Fields are added by populating this hash.
9
+ attr_accessor :hash, :time_key, :log_labels, :formatted_payload
10
+
11
+ # Parameters
12
+ # time_format: [String|Symbol|nil]
13
+ # See Time#strftime for the format of this string.
14
+ # :iso_8601 Outputs an ISO8601 Formatted timestamp.
15
+ # :ms Output in miliseconds since epoch.
16
+ # nil: Returns Empty string for time ( no time is output ).
17
+ # Default: '%Y-%m-%d %H:%M:%S.%<precision>N'
18
+ # log_host: [Boolean]
19
+ # Whether or not to include hostname in logs
20
+ # Default: true
21
+ # precision: [Integer]
22
+ # How many fractional digits to log times with.
23
+ # Default: PRECISION (6, except on older JRuby, where 3)
24
+ def initialize time_key: :time, **args
25
+ @time_key = time_key
26
+ @log_application = true
27
+ super(**args)
28
+ end
29
+
30
+ # Host name
31
+ def host
32
+ log_labels[:host] = logger.host if log_host && logger.host
33
+ end
34
+
35
+ # Application name
36
+ def application
37
+ log_labels[:application] = logger.application if logger && logger.application
38
+ end
39
+
40
+ # Environment
41
+ def environment
42
+ if log_environment && logger && logger.environment
43
+ log_labels[:environment] = logger.environment
44
+ end
45
+ end
46
+
47
+ # Named Tags
48
+ def named_tags
49
+ log_labels[:named_tags] = log.named_tags if log.named_tags && !log.named_tags.empty?
50
+ end
51
+
52
+ # Date & time
53
+ def time
54
+ hash[time_key] = format_time log.time.utc
55
+ end
56
+
57
+ def labels
58
+ self.log_labels ||= {}
59
+ host
60
+ application
61
+ environment
62
+ named_tags
63
+ hash[:labels] = log_labels unless log_labels.empty?
64
+ end
65
+
66
+ # Log message
67
+ def message
68
+ hash[:message] = "#{log.name} -- #{log.cleansed_message}" if log.message
69
+ hash[:message] = "#{log.metric} -- #{log.metric_amount}" if log.metric && log.metric_amount
70
+ end
71
+
72
+ # Tags
73
+ def tags
74
+ hash[:tags] = log.tags if log.tags && !log.tags.empty?
75
+ end
76
+
77
+ # Exception
78
+ def exception
79
+ return log.exception if log.exception
80
+
81
+ unless log.payload.respond_to?(:empty?) && log.payload[:exception].class.ancestors.include?(StandardError)
82
+ return
83
+ end
84
+
85
+ log.payload[:exception]
86
+ end
87
+
88
+ def inner_exception exception
89
+ if exception.respond_to?(:cause) && exception.cause
90
+ exception.cause
91
+ elsif exception.respond_to?(:continued_exception) && exception.continued_exception
92
+ exception.continued_exception
93
+ elsif exception.respond_to?(:original_exception) && exception.original_exception
94
+ exception.original_exception
95
+ end
96
+ end
97
+
98
+ # Call the block for exception and any nested exception
99
+ def each_exception exception
100
+ # With thanks to https://github.com/bugsnag/bugsnag-ruby/blob/6348306e44323eee347896843d16c690cd7c4362/lib/bugsnag/notification.rb#L81
101
+ depth = 0
102
+ exceptions = []
103
+ e = exception
104
+ while !e.nil? && !exceptions.include?(e) && exceptions.length < 5
105
+ exceptions << e
106
+ yield e, depth
107
+
108
+ depth += 1
109
+ e = inner_exception e
110
+ end
111
+ end
112
+
113
+ def exception_hash exception
114
+ {
115
+ "error.type": exception.class.name,
116
+ "error.message": exception.message,
117
+ "error.stack_trace": BacktraceCleaner.clean(exception.backtrace)
118
+ }
119
+ end
120
+
121
+ def error_log?
122
+ !hash[:"error.type"].nil?
123
+ end
124
+
125
+ def initialize_rack_keys
126
+ formatted_payload[:request] ||= {}
127
+ formatted_payload[:response] ||= {}
128
+ formatted_payload[:metrics] ||= {}
129
+ end
130
+
131
+ def rack_request
132
+ formatted_payload[:request].merge! formatted_payload.extract!(
133
+ :controller,
134
+ :action,
135
+ :params,
136
+ :method,
137
+ :path,
138
+ :request_id
139
+ )
140
+ formatted_payload[:request][:body] = formatted_payload[:request].delete :params
141
+ end
142
+
143
+ def rack_response
144
+ formatted_payload[:response].merge! formatted_payload.extract!(:status, :status_message)
145
+ end
146
+
147
+ def rack_metrics
148
+ metrics_keys = formatted_payload.keys.select { |k| k.to_s.end_with?("_runtime") }
149
+ formatted_payload[:metrics].merge! formatted_payload.extract!(:allocations, *metrics_keys)
150
+ formatted_payload[:metrics][:object_allocations] =
151
+ formatted_payload[:metrics].delete :allocations
152
+ end
153
+
154
+ def rack_extract
155
+ return unless formatted_payload.key? :controller
156
+
157
+ initialize_rack_keys
158
+ rack_request
159
+ rack_response
160
+ rack_metrics
161
+ formatted_payload.delete :format
162
+ end
163
+
164
+ def format_payload
165
+ return unless log.payload.respond_to?(:empty?) && !log.payload.empty?
166
+
167
+ self.formatted_payload = Utils::Hash[**log.payload]
168
+
169
+ rack_extract
170
+ end
171
+
172
+ def request
173
+ hash[:"http.request.id"] = formatted_payload.dig :request, :request_id
174
+ hash[:"http.request.body.content"] = formatted_payload.dig :request, :body
175
+ hash[:"http.request.method"] = formatted_payload.dig :request, :method
176
+ end
177
+
178
+ def response
179
+ hash[:"http.response.body.content"] = formatted_payload.dig :response, :body
180
+ hash[:"http.response.status_code"] = formatted_payload.dig :response, :status
181
+ end
182
+
183
+ # Ruby file name and line number that logged the message.
184
+ def file_name_and_line
185
+ file, line = log.file_name_and_line
186
+ return unless file
187
+
188
+ hash[:"log.origin.file.name"] = file
189
+ hash[:"log.origin.file.line"] = line.to_i
190
+ end
191
+
192
+ def calculated_log_level
193
+ return log.level if log.level_index > 2
194
+
195
+ (formatted_payload.dig(:response, :status) || 0) >= 500 ? "error" : log.level
196
+ end
197
+
198
+ # ElasticAPM
199
+ def apm_agent_present_and_running?
200
+ return false unless defined?(::ElasticAPM)
201
+
202
+ ElasticAPM.running?
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module SemanticLoggerEcsAddon
6
+ module Formatters
7
+ class Json < Raw
8
+ # Default JSON time format is ISO8601
9
+ def initialize time_format: :iso_8601, precision: 3, **args
10
+ super(time_format: time_format, precision: precision, **args)
11
+ end
12
+
13
+ # Returns log messages in JSON format
14
+ def call log, logger
15
+ super(log, logger).to_json
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SemanticLoggerEcsAddon
4
+ module Formatters
5
+ class Raw < Base
6
+ def initialize time_format: :none, time_key: :@timestamp, **args
7
+ @time_key = time_key
8
+ super(time_format: time_format, time_key: @time_key, **args)
9
+ end
10
+
11
+ def base
12
+ time
13
+ labels
14
+ message
15
+ tags
16
+ end
17
+
18
+ def ecs
19
+ hash[:"ecs.version"] = "1.10"
20
+ end
21
+
22
+ def error
23
+ root = hash
24
+ each_exception exception do |e, i|
25
+ if i.zero?
26
+ root.merge! exception_hash e
27
+ else
28
+ root[:"error.cause"] = exception_hash e
29
+ root = root[:"error.cause"]
30
+ end
31
+ end
32
+ end
33
+
34
+ def event
35
+ hash[:"event.dataset"] = "#{logger.application}.log"
36
+ hash[:"event.duration"] = (log.duration || 0) * 1000000
37
+ hash[:"event.outcome"] = error_log? ? "failure" : "success"
38
+ end
39
+
40
+ def http
41
+ request
42
+ response
43
+ end
44
+
45
+ def ecs_log
46
+ hash[:"log.level"] = calculated_log_level
47
+ hash[:"log.logger"] = log.name
48
+ file_name_and_line
49
+ end
50
+
51
+ def ecs_process
52
+ hash[:"process.thread.name"] = log.thread_name
53
+ hash[:"process.pid"] = pid
54
+ end
55
+
56
+ def ecs_service
57
+ hash[:"service.name"] = logger.application
58
+ end
59
+
60
+ def ecs_source
61
+ hash[:"source.ip"] = formatted_payload.delete :remote_ip
62
+ end
63
+
64
+ def ecs_tracing
65
+ return unless apm_agent_present_and_running?
66
+
67
+ hash[:"transaction.id"] = ElasticAPM.current_transaction&.id
68
+ hash[:"trace.id"] = ElasticAPM.current_transaction&.trace_id
69
+ hash[:"span.id"] = ElasticAPM.current_span&.id
70
+ end
71
+
72
+ def ecs_url
73
+ hash[:"url.path"] = formatted_payload.dig :request, :path
74
+ end
75
+
76
+ def ecs_user
77
+ hash[:"user.email"] = formatted_payload.dig :user, :email
78
+ hash[:"user.full_name"] = formatted_payload.dig :user, :full_name
79
+ hash[:"user.id"] = formatted_payload.dig :user, :id
80
+ hash[:"user.name"] = formatted_payload.dig :user, :name
81
+ hash[:"user.domain"] = formatted_payload.dig :user, :type
82
+ end
83
+
84
+ def extras
85
+ return unless formatted_payload.respond_to?(:empty?) && !formatted_payload.empty?
86
+
87
+ hash.merge! formatted_payload.except(:request, :response, :user)
88
+ end
89
+
90
+ # Returns log messages in Hash format
91
+ def call log, logger
92
+ self.hash = {}
93
+ self.log = log
94
+ self.logger = logger
95
+ format_payload
96
+
97
+ base
98
+ ecs
99
+ error
100
+ event
101
+ http
102
+ ecs_log
103
+ ecs_process
104
+ ecs_service
105
+ ecs_source
106
+ ecs_tracing
107
+ ecs_url
108
+ ecs_user
109
+ extras
110
+
111
+ hash.compact
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SemanticLoggerEcsAddon
4
+ # Gem identity information.
5
+ module Identity
6
+ NAME = "semantic_logger_ecs_addon"
7
+ LABEL = "Semantic Logger Ecs Addon"
8
+ VERSION = "0.1.0"
9
+ VERSION_LABEL = "#{LABEL} #{VERSION}"
10
+ SUMMARY = "A semantic logger formatter that formats the logs according to Elastic Common Schema and adds APM trace data if ElasticAPM is enabled."
11
+ end
12
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SemanticLoggerEcsAddon
4
+ module Utils
5
+ # Backtraces often include many lines that are not relevant for the context
6
+ # under review. This makes it hard to find the signal amongst the backtrace
7
+ # noise, and adds debugging time. With a BacktraceCleaner, filters and
8
+ # silencers are used to remove the noisy lines, so that only the most relevant
9
+ # lines remain.
10
+ #
11
+ # Filters are used to modify lines of data, while silencers are used to remove
12
+ # lines entirely. The typical filter use case is to remove lengthy path
13
+ # information from the start of each line, and view file paths relevant to the
14
+ # app directory instead of the file system root. The typical silencer use case
15
+ # is to exclude the output of a noisy library from the backtrace, so that you
16
+ # can focus on the rest.
17
+ #
18
+ # bc = ActiveSupport::BacktraceCleaner.new
19
+ # bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix
20
+ # bc.add_silencer { |line| /puma|rubygems/.match?(line) } # skip any lines from puma or rubygems
21
+ # bc.clean(exception.backtrace) # perform the cleanup
22
+ #
23
+ # To reconfigure an existing BacktraceCleaner (like the default one in Rails)
24
+ # and show as much data as possible, you can always call
25
+ # <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the
26
+ # backtrace to a pristine state. If you need to reconfigure an existing
27
+ # BacktraceCleaner so that it does not filter or modify the paths of any lines
28
+ # of the backtrace, you can call <tt>BacktraceCleaner#remove_filters!</tt>
29
+ # These two methods will give you a completely untouched backtrace.
30
+ #
31
+ # Borrowed from ActiveSupport gem.
32
+ class BacktraceCleaner
33
+ FORMATTED_GEMS_PATTERN = %r(\A[^/]+ \([\w.]+\) )
34
+ def initialize
35
+ @filters = []
36
+ @silencers = []
37
+ add_gem_filter
38
+ add_gem_silencer
39
+ add_stdlib_silencer
40
+ end
41
+
42
+ # Returns the backtrace after all filters and silencers have been run
43
+ # against it. Filters run first, then silencers.
44
+ def clean backtrace, kind = :silent
45
+ filtered = filter_backtrace backtrace
46
+
47
+ case kind
48
+ when :silent
49
+ silence filtered
50
+ when :noise
51
+ noise filtered
52
+ else
53
+ filtered
54
+ end
55
+ end
56
+ alias filter clean
57
+
58
+ # Adds a filter from the block provided. Each line in the backtrace will be
59
+ # mapped against this filter.
60
+ #
61
+ # # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
62
+ # backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }
63
+ def add_filter &block
64
+ @filters << block
65
+ end
66
+
67
+ # Adds a silencer from the block provided. If the silencer returns +true+
68
+ # for a given line, it will be excluded from the clean backtrace.
69
+ #
70
+ # # Will reject all lines that include the word "puma", like "/gems/puma/server.rb" or "/app/my_puma_server/rb"
71
+ # backtrace_cleaner.add_silencer { |line| /puma/.match?(line) }
72
+ def add_silencer &block
73
+ @silencers << block
74
+ end
75
+
76
+ # Removes all silencers, but leaves in the filters. Useful if your
77
+ # context of debugging suddenly expands as you suspect a bug in one of
78
+ # the libraries you use.
79
+ def remove_silencers!
80
+ @silencers = []
81
+ end
82
+
83
+ # Removes all filters, but leaves in the silencers. Useful if you suddenly
84
+ # need to see entire filepaths in the backtrace that you had already
85
+ # filtered out.
86
+ def remove_filters!
87
+ @filters = []
88
+ end
89
+
90
+ private
91
+
92
+ def add_gem_filter
93
+ gems_paths = (Gem.path | [Gem.default_dir]).map { |p| Regexp.escape(p) }
94
+ return if gems_paths.empty?
95
+
96
+ gems_regexp = %r{\A(#{gems_paths.join '|'})/(bundler/)?gems/([^/]+)-([\w.]+)/(.*)}
97
+ gems_result = '\3 (\4) \5'
98
+ add_filter { |line| line.sub(gems_regexp, gems_result) }
99
+ end
100
+
101
+ def add_gem_silencer
102
+ add_silencer { |line| FORMATTED_GEMS_PATTERN.match?(line) }
103
+ end
104
+
105
+ def add_stdlib_silencer
106
+ add_silencer { |line| line.start_with?(RbConfig::CONFIG["rubylibdir"]) }
107
+ end
108
+
109
+ def filter_backtrace backtrace
110
+ @filters.each { |f| backtrace = backtrace.map { |line| f.call(line) } }
111
+
112
+ backtrace
113
+ end
114
+
115
+ def silence backtrace
116
+ @silencers.each { |s| backtrace = backtrace.reject { |line| s.call(line) } }
117
+
118
+ backtrace
119
+ end
120
+
121
+ def noise backtrace
122
+ backtrace.select { |line| @silencers.any? { |s| s.call line } }
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SemanticLoggerEcsAddon
4
+ module Utils
5
+ class Hash < ::Hash
6
+ # With thanks to https://github.com/rails/rails/blob/83217025a171593547d1268651b446d3533e2019/activesupport/lib/active_support/core_ext/hash/slice.rb#L24
7
+ # Removes and returns the key/value pairs matching the given keys.
8
+ #
9
+ # hash = { a: 1, b: 2, c: 3, d: 4 }
10
+ # hash.extract!(:a, :b) # => {:a=>1, :b=>2}
11
+ # hash # => {:c=>3, :d=>4}
12
+ def extract! *keys
13
+ keys.each_with_object self.class.new do |key, result|
14
+ result[key] = delete key if key? key
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: semantic_logger_ecs_addon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sajeev Ramasamy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIERDCCAqygAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBt0aG9y
14
+ aW9uMzAwNi9EQz1nbWFpbC9EQz1jb20wHhcNMjEwNjA4MTAyMzI4WhcNMjIwNjA4
15
+ MTAyMzI4WjAmMSQwIgYDVQQDDBt0aG9yaW9uMzAwNi9EQz1nbWFpbC9EQz1jb20w
16
+ ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC1entXzzkGYW4W906xYuTr
17
+ 6SQWJXxjPo3GrsWk2L+KXMkY94d1MyJN9IJ0LEy6M7onkmpYSzFqBQ8W+8VRaW0y
18
+ HVLX1EQRZ9hVd0LV9j5tNx2pDUfXzoxeyNllBd64Ne7r/6D93lAErATC/+v9X6QC
19
+ cHd17QBGWU8Qb0ePkYY1UvImbePdgLRwu6F2KrUPyn3ewoAvBxsAG74XU6SbORQ2
20
+ 7Hhfh9vvRAcgboXmbyPW+6Z6KN7YdBFnAwI7r/9M9cMRhWwpprTPwKNdAMR0wl+l
21
+ Bdp7Se7x8fxriTl9TTpgMScGdXIc/m2Pj48W+cnk5Wf2xlcrzXptX3UYelF8f7j3
22
+ R/Ft2OTSvG0jdYW50mGD96Om0WKM6Ggfx0Dz6pvComl2LNajTSYpHB0xj8d1L6QX
23
+ UQ2kcIERhnVMqriZauA21b2J9ZLxFf+Ddou7V2AiLMlFi9cPxgj4eHrHLiOylC29
24
+ sBztOdq1mbfofNe5ifothYpj/uMKYEdXRjlKXUITCFcCAwEAAaN9MHswCQYDVR0T
25
+ BAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFP9FcvZBAdqH9D6ECTtDk6GsVUYL
26
+ MCAGA1UdEQQZMBeBFXRob3Jpb24zMDA2QGdtYWlsLmNvbTAgBgNVHRIEGTAXgRV0
27
+ aG9yaW9uMzAwNkBnbWFpbC5jb20wDQYJKoZIhvcNAQELBQADggGBAK0XGR9ezspt
28
+ S4Dy1PZ0FeGQXjtUkXcEgY6a/BnJGie9PnHRQZx4fHeVWLH3cDTsy860rTp7tmmw
29
+ Q/5NIM05AfHabnA/HVqNj/jQt1+EpQS2DGIRNiVtD+Mk/NEyggb4nvg1AJa++IpS
30
+ XmIAlpJdGwDAsLAv8JlKVbH252QFYVNVTBaikFAQ70GOxL2PnnVPl+GrC23DCpVs
31
+ eDXVMLZlUe40RTL3Ru6mEMXASB6byp4PwQ7eCaoAUlGQwvdvW09ai0jRI4zqgsAi
32
+ sSKEjVZRRZcr6wP+zvDReTG5FSVOag1G5g0SivvltgjWqDy2EmY41Qp08jtLu+iQ
33
+ m3Fy3/MP/izFtIvuQAJaZH+1l83GFI//m8V53ZH7Gg+1VFPlXXmpGQIMR9yZSDBe
34
+ ewungQjw99puFMSK2d/NFj2L2oSvamT0vGoiH63zwx02vLziB6Jbn34/tuDEqUQ9
35
+ WEUeG6yA2jP44YUZzNP+Xbjpzr/RvJxAmFw+7SNkHkmP3csIS+0TIg==
36
+ -----END CERTIFICATE-----
37
+ date: 2021-06-27 00:00:00.000000000 Z
38
+ dependencies:
39
+ - !ruby/object:Gem::Dependency
40
+ name: semantic_logger
41
+ requirement: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - "~>"
44
+ - !ruby/object:Gem::Version
45
+ version: '4.4'
46
+ type: :runtime
47
+ prerelease: false
48
+ version_requirements: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '4.4'
53
+ - !ruby/object:Gem::Dependency
54
+ name: zeitwerk
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.4'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '2.4'
67
+ description:
68
+ email:
69
+ - thorion3006@gmail.com
70
+ executables: []
71
+ extensions: []
72
+ extra_rdoc_files:
73
+ - README.md
74
+ - LICENSE.md
75
+ files:
76
+ - LICENSE.md
77
+ - README.md
78
+ - lib/semantic_logger_ecs_addon.rb
79
+ - lib/semantic_logger_ecs_addon/formatters/base.rb
80
+ - lib/semantic_logger_ecs_addon/formatters/json.rb
81
+ - lib/semantic_logger_ecs_addon/formatters/raw.rb
82
+ - lib/semantic_logger_ecs_addon/identity.rb
83
+ - lib/semantic_logger_ecs_addon/utils/backtrace_cleaner.rb
84
+ - lib/semantic_logger_ecs_addon/utils/hash.rb
85
+ homepage: https://github.com/thorion3006/semantic_logger_ecs_addon
86
+ licenses:
87
+ - MIT
88
+ metadata:
89
+ bug_tracker_uri: https://github.com/thorion3006/semantic_logger_ecs_addon/issues
90
+ changelog_uri: https://github.com/thorion3006/semantic_logger_ecs_addon/blob/master/CHANGES.md
91
+ documentation_uri: https://github.com/thorion3006/semantic_logger_ecs_addon
92
+ source_code_uri: https://github.com/thorion3006/semantic_logger_ecs_addon
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '2.7'
102
+ - - "<"
103
+ - !ruby/object:Gem::Version
104
+ version: '4'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubygems_version: 3.2.15
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: A semantic logger formatter that formats the logs according to Elastic Common
115
+ Schema and adds APM trace data if ElasticAPM is enabled.
116
+ test_files: []
metadata.gz.sig ADDED
Binary file