scout_apm_logging 1.1.0 → 2.0.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +17 -2
  3. data/.rubocop.yml +1 -1
  4. data/CHANGELOG.md +6 -0
  5. data/README.md +7 -2
  6. data/lib/scout_apm/logging/config.rb +1 -1
  7. data/lib/scout_apm/logging/loggers/formatter.rb +1 -1
  8. data/lib/scout_apm/logging/loggers/opentelemetry/log_record_patch.rb +38 -0
  9. data/lib/scout_apm/logging/loggers/opentelemetry/opentelemetry.rb +8 -31
  10. data/lib/scout_apm/logging/version.rb +1 -1
  11. data/scout_apm_logging.gemspec +4 -2
  12. data/spec/integration/rails/lifecycle_spec.rb +1 -1
  13. metadata +36 -31
  14. data/lib/scout_apm/logging/loggers/opentelemetry/LICENSE +0 -201
  15. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/log_record.rb +0 -18
  16. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/logger.rb +0 -64
  17. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/logger_provider.rb +0 -31
  18. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/severity_number.rb +0 -43
  19. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/version.rb +0 -18
  20. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs.rb +0 -28
  21. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/exporter/otlp/logs_exporter.rb +0 -398
  22. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/exporter/otlp/version.rb +0 -20
  23. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/collector/logs/v1/logs_service_pb.rb +0 -43
  24. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/common/v1/common_pb.rb +0 -58
  25. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/logs/v1/logs_pb.rb +0 -91
  26. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/resource/v1/resource_pb.rb +0 -33
  27. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/batch_log_record_processor.rb +0 -223
  28. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/log_record_exporter.rb +0 -64
  29. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export.rb +0 -34
  30. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record.rb +0 -170
  31. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_data.rb +0 -31
  32. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_limits.rb +0 -49
  33. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_processor.rb +0 -52
  34. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/logger.rb +0 -98
  35. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/logger_provider.rb +0 -170
  36. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/version.rb +0 -20
  37. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs.rb +0 -29
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Generated by the protocol buffer compiler. DO NOT EDIT!
4
- # source: opentelemetry/proto/common/v1/common.proto
5
-
6
- require 'google/protobuf'
7
-
8
- Google::Protobuf::DescriptorPool.generated_pool.build do
9
- add_file("scout/opentelemetry/proto/common/v1/common.proto", :syntax => :proto3) do
10
- add_message "scout_apm.logging.loggers.opentelemetry.proto.common.v1.AnyValue" do
11
- oneof :value do
12
- optional :string_value, :string, 1
13
- optional :bool_value, :bool, 2
14
- optional :int_value, :int64, 3
15
- optional :double_value, :double, 4
16
- optional :array_value, :message, 5, "scout_apm.logging.loggers.opentelemetry.proto.common.v1.ArrayValue"
17
- optional :kvlist_value, :message, 6, "scout_apm.logging.loggers.opentelemetry.proto.common.v1.KeyValueList"
18
- optional :bytes_value, :bytes, 7
19
- end
20
- end
21
- add_message "scout_apm.logging.loggers.opentelemetry.proto.common.v1.ArrayValue" do
22
- repeated :values, :message, 1, "scout_apm.logging.loggers.opentelemetry.proto.common.v1.AnyValue"
23
- end
24
- add_message "scout_apm.logging.loggers.opentelemetry.proto.common.v1.KeyValueList" do
25
- repeated :values, :message, 1, "scout_apm.logging.loggers.opentelemetry.proto.common.v1.KeyValue"
26
- end
27
- add_message "scout_apm.logging.loggers.opentelemetry.proto.common.v1.KeyValue" do
28
- optional :key, :string, 1
29
- optional :value, :message, 2, "scout_apm.logging.loggers.opentelemetry.proto.common.v1.AnyValue"
30
- end
31
- add_message "scout_apm.logging.loggers.opentelemetry.proto.common.v1.InstrumentationScope" do
32
- optional :name, :string, 1
33
- optional :version, :string, 2
34
- repeated :attributes, :message, 3, "scout_apm.logging.loggers.opentelemetry.proto.common.v1.KeyValue"
35
- optional :dropped_attributes_count, :uint32, 4
36
- end
37
- end
38
- end
39
-
40
- module ScoutApm
41
- module Logging
42
- module Loggers
43
- module Opentelemetry
44
- module Proto
45
- module Common
46
- module V1
47
- AnyValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.common.v1.AnyValue").msgclass
48
- ArrayValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.common.v1.ArrayValue").msgclass
49
- KeyValueList = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.common.v1.KeyValueList").msgclass
50
- KeyValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.common.v1.KeyValue").msgclass
51
- InstrumentationScope = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.common.v1.InstrumentationScope").msgclass
52
- end
53
- end
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Generated by the protocol buffer compiler. DO NOT EDIT!
4
- # source: opentelemetry/proto/logs/v1/logs.proto
5
-
6
- require 'google/protobuf'
7
-
8
- require_relative '../../common/v1/common_pb'
9
- require_relative '../../resource/v1/resource_pb'
10
-
11
- Google::Protobuf::DescriptorPool.generated_pool.build do
12
- add_file("scout/opentelemetry/proto/logs/v1/logs.proto", :syntax => :proto3) do
13
- add_message "scout_apm.logging.loggers.opentelemetry.proto.logs.v1.LogsData" do
14
- repeated :resource_logs, :message, 1, "scout_apm.logging.loggers.opentelemetry.proto.logs.v1.ResourceLogs"
15
- end
16
- add_message "scout_apm.logging.loggers.opentelemetry.proto.logs.v1.ResourceLogs" do
17
- optional :resource, :message, 1, "scout_apm.logging.loggers.opentelemetry.proto.resource.v1.Resource"
18
- repeated :scope_logs, :message, 2, "scout_apm.logging.loggers.opentelemetry.proto.logs.v1.ScopeLogs"
19
- optional :schema_url, :string, 3
20
- end
21
- add_message "scout_apm.logging.loggers.opentelemetry.proto.logs.v1.ScopeLogs" do
22
- optional :scope, :message, 1, "scout_apm.logging.loggers.opentelemetry.proto.common.v1.InstrumentationScope"
23
- repeated :log_records, :message, 2, "scout_apm.logging.loggers.opentelemetry.proto.logs.v1.LogRecord"
24
- optional :schema_url, :string, 3
25
- end
26
- add_message "scout_apm.logging.loggers.opentelemetry.proto.logs.v1.LogRecord" do
27
- optional :time_unix_nano, :fixed64, 1
28
- optional :observed_time_unix_nano, :fixed64, 11
29
- optional :severity_number, :enum, 2, "scout_apm.logging.loggers.opentelemetry.proto.logs.v1.SeverityNumber"
30
- optional :severity_text, :string, 3
31
- optional :body, :message, 5, "scout_apm.logging.loggers.opentelemetry.proto.common.v1.AnyValue"
32
- repeated :attributes, :message, 6, "scout_apm.logging.loggers.opentelemetry.proto.common.v1.KeyValue"
33
- optional :dropped_attributes_count, :uint32, 7
34
- optional :flags, :fixed32, 8
35
- optional :trace_id, :bytes, 9
36
- optional :span_id, :bytes, 10
37
- end
38
- add_enum "scout_apm.logging.loggers.opentelemetry.proto.logs.v1.SeverityNumber" do
39
- value :SEVERITY_NUMBER_UNSPECIFIED, 0
40
- value :SEVERITY_NUMBER_TRACE, 1
41
- value :SEVERITY_NUMBER_TRACE2, 2
42
- value :SEVERITY_NUMBER_TRACE3, 3
43
- value :SEVERITY_NUMBER_TRACE4, 4
44
- value :SEVERITY_NUMBER_DEBUG, 5
45
- value :SEVERITY_NUMBER_DEBUG2, 6
46
- value :SEVERITY_NUMBER_DEBUG3, 7
47
- value :SEVERITY_NUMBER_DEBUG4, 8
48
- value :SEVERITY_NUMBER_INFO, 9
49
- value :SEVERITY_NUMBER_INFO2, 10
50
- value :SEVERITY_NUMBER_INFO3, 11
51
- value :SEVERITY_NUMBER_INFO4, 12
52
- value :SEVERITY_NUMBER_WARN, 13
53
- value :SEVERITY_NUMBER_WARN2, 14
54
- value :SEVERITY_NUMBER_WARN3, 15
55
- value :SEVERITY_NUMBER_WARN4, 16
56
- value :SEVERITY_NUMBER_ERROR, 17
57
- value :SEVERITY_NUMBER_ERROR2, 18
58
- value :SEVERITY_NUMBER_ERROR3, 19
59
- value :SEVERITY_NUMBER_ERROR4, 20
60
- value :SEVERITY_NUMBER_FATAL, 21
61
- value :SEVERITY_NUMBER_FATAL2, 22
62
- value :SEVERITY_NUMBER_FATAL3, 23
63
- value :SEVERITY_NUMBER_FATAL4, 24
64
- end
65
- add_enum "scout_apm.logging.loggers.opentelemetry.proto.logs.v1.LogRecordFlags" do
66
- value :LOG_RECORD_FLAGS_DO_NOT_USE, 0
67
- value :LOG_RECORD_FLAGS_TRACE_FLAGS_MASK, 255
68
- end
69
- end
70
- end
71
-
72
- module ScoutApm
73
- module Logging
74
- module Loggers
75
- module Opentelemetry
76
- module Proto
77
- module Logs
78
- module V1
79
- LogsData = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.logs.v1.LogsData").msgclass
80
- ResourceLogs = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.logs.v1.ResourceLogs").msgclass
81
- ScopeLogs = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.logs.v1.ScopeLogs").msgclass
82
- LogRecord = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.logs.v1.LogRecord").msgclass
83
- SeverityNumber = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.logs.v1.SeverityNumber").enummodule
84
- LogRecordFlags = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.logs.v1.LogRecordFlags").enummodule
85
- end
86
- end
87
- end
88
- end
89
- end
90
- end
91
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Generated by the protocol buffer compiler. DO NOT EDIT!
4
- # source: opentelemetry/proto/resource/v1/resource.proto
5
-
6
- require 'google/protobuf'
7
-
8
- require_relative '../../common/v1/common_pb'
9
-
10
- Google::Protobuf::DescriptorPool.generated_pool.build do
11
- add_file("scout/opentelemetry/proto/resource/v1/resource.proto", :syntax => :proto3) do
12
- add_message "scout_apm.logging.loggers.opentelemetry.proto.resource.v1.Resource" do
13
- repeated :attributes, :message, 1, "scout_apm.logging.loggers.opentelemetry.proto.common.v1.KeyValue"
14
- optional :dropped_attributes_count, :uint32, 2
15
- end
16
- end
17
- end
18
-
19
- module ScoutApm
20
- module Logging
21
- module Loggers
22
- module Opentelemetry
23
- module Proto
24
- module Resource
25
- module V1
26
- Resource = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("scout_apm.logging.loggers.opentelemetry.proto.resource.v1.Resource").msgclass
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
33
- end
@@ -1,223 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
- module ScoutApm
7
- module Logging
8
- module Loggers
9
- module OpenTelemetry
10
- module SDK
11
- module Logs
12
- module Export
13
- # WARNING - The spec has some differences from the LogRecord version of this processor
14
- # Implementation of the duck type LogRecordProcessor that batches
15
- # log records exported by the SDK then pushes them to the exporter
16
- # pipeline.
17
- #
18
- # Typically, the BatchLogRecordProcessor will be more suitable for
19
- # production environments than the SimpleLogRecordProcessor.
20
- class BatchLogRecordProcessor < LogRecordProcessor # rubocop:disable Metrics/ClassLength
21
- # Returns a new instance of the {BatchLogRecordProcessor}.
22
- #
23
- # @param [LogRecordExporter] exporter The (duck type) LogRecordExporter to where the
24
- # recorded LogRecords are pushed after batching.
25
- # @param [Numeric] exporter_timeout The maximum allowed time to export data.
26
- # Defaults to the value of the OTEL_BLRP_EXPORT_TIMEOUT
27
- # environment variable, if set, or 30,000 (30 seconds).
28
- # @param [Numeric] schedule_delay the delay interval between two consecutive exports.
29
- # Defaults to the value of the OTEL_BLRP_SCHEDULE_DELAY environment
30
- # variable, if set, or 1,000 (1 second).
31
- # @param [Integer] max_queue_size the maximum queue size in log records.
32
- # Defaults to the value of the OTEL_BLRP_MAX_QUEUE_SIZE environment
33
- # variable, if set, or 2048.
34
- # @param [Integer] max_export_batch_size the maximum batch size in log records.
35
- # Defaults to the value of the OTEL_BLRP_MAX_EXPORT_BATCH_SIZE environment
36
- # variable, if set, or 512.
37
- #
38
- # @return a new instance of the {BatchLogRecordProcessor}.
39
- def initialize(exporter,
40
- exporter_timeout: Float(ENV.fetch('OTEL_BLRP_EXPORT_TIMEOUT', 30_000)),
41
- schedule_delay: Float(ENV.fetch('OTEL_BLRP_SCHEDULE_DELAY', 1000)),
42
- max_queue_size: Integer(ENV.fetch('OTEL_BLRP_MAX_QUEUE_SIZE', 2048)),
43
- max_export_batch_size: Integer(ENV.fetch('OTEL_BLRP_MAX_EXPORT_BATCH_SIZE', 512)),
44
- start_thread_on_boot: String(ENV['OTEL_RUBY_BLRP_START_THREAD_ON_BOOT']) !~ /false/i)
45
- unless max_export_batch_size <= max_queue_size
46
- raise ArgumentError,
47
- 'max_export_batch_size much be less than or equal to max_queue_size'
48
- end
49
-
50
- unless ::OpenTelemetry::Common::Utilities.valid_exporter?(exporter)
51
- raise ArgumentError,
52
- "exporter #{exporter.inspect} does not appear to be a valid exporter"
53
- end
54
-
55
- @exporter = exporter
56
- @exporter_timeout_seconds = exporter_timeout / 1000.0
57
- @mutex = Mutex.new
58
- @export_mutex = Mutex.new
59
- @condition = ConditionVariable.new
60
- @keep_running = true
61
- @stopped = false
62
- @delay_seconds = schedule_delay / 1000.0
63
- @max_queue_size = max_queue_size
64
- @batch_size = max_export_batch_size
65
- @log_records = []
66
- @pid = nil
67
- @thread = nil
68
- reset_on_fork(restart_thread: start_thread_on_boot)
69
- end
70
-
71
- # Adds a log record to the batch. Thread-safe; may block on lock.
72
- def on_emit(log_record, _context)
73
- return if @stopped
74
-
75
- lock do
76
- reset_on_fork
77
- n = log_records.size + 1 - max_queue_size
78
- if n.positive?
79
- log_records.shift(n)
80
- report_dropped_log_records(n, reason: 'buffer-full')
81
- end
82
- log_records << log_record
83
- @condition.signal if log_records.size > batch_size
84
- end
85
- end
86
-
87
- # Export all emitted log records that have not yet been exported to
88
- # the configured `Exporter`.
89
- #
90
- # This method should only be called in cases where it is absolutely
91
- # necessary, such as when using some FaaS providers that may suspend
92
- # the process after an invocation, but before the `Processor` exports
93
- # the completed log records.
94
- #
95
- # @param [optional Numeric] timeout An optional timeout in seconds.
96
- # @return [Integer] SUCCESS if no error occurred, FAILURE if a
97
- # non-specific failure occurred, TIMEOUT if a timeout occurred.
98
- def force_flush(timeout: nil)
99
- start_time = ::OpenTelemetry::Common::Utilities.timeout_timestamp
100
-
101
- snapshot = lock do
102
- reset_on_fork if @keep_running
103
- log_records.shift(log_records.size)
104
- end
105
-
106
- until snapshot.empty?
107
- remaining_timeout = ::OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
108
- return TIMEOUT if remaining_timeout&.zero?
109
-
110
- batch = snapshot.shift(batch_size).map!(&:to_log_record_data)
111
- result_code = export_batch(batch, timeout: remaining_timeout)
112
- return result_code unless result_code == SUCCESS
113
- end
114
-
115
- @exporter.force_flush(timeout: ::OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
116
- ensure
117
- # Unshift the remaining log records if we timed out. We drop excess
118
- # log records from the snapshot because they're older than any
119
- # records in the buffer.
120
- lock do
121
- n = log_records.size + snapshot.size - max_queue_size
122
-
123
- if n.positive?
124
- snapshot.shift(n)
125
- report_dropped_log_records(n, reason: 'buffer-full')
126
- end
127
-
128
- log_records.unshift(*snapshot) unless snapshot.empty?
129
- @condition.signal if log_records.size > max_queue_size / 2
130
- end
131
- end
132
-
133
- # Shuts the consumer thread down and flushes the current accumulated
134
- # buffer will block until the thread is finished.
135
- #
136
- # @param [optional Numeric] timeout An optional timeout in seconds.
137
- # @return [Integer] SUCCESS if no error occurred, FAILURE if a
138
- # non-specific failure occurred, TIMEOUT if a timeout occurred.
139
- def shutdown(timeout: nil)
140
- return if @stopped
141
-
142
- start_time = ::OpenTelemetry::Common::Utilities.timeout_timestamp
143
- thread = lock do
144
- @keep_running = false
145
- @stopped = true
146
- @condition.signal
147
- @thread
148
- end
149
-
150
- thread&.join(timeout)
151
- force_flush(timeout: ::OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
152
- dropped_log_records = lock { log_records.size }
153
- report_dropped_log_records(dropped_log_records, reason: 'terminating') if dropped_log_records.positive?
154
-
155
- @exporter.shutdown(timeout: ::OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
156
- end
157
-
158
- private
159
-
160
- attr_reader :log_records, :max_queue_size, :batch_size
161
-
162
- def work
163
- loop do
164
- batch = lock do
165
- @condition.wait(@mutex, @delay_seconds) if log_records.size < batch_size && @keep_running
166
- @condition.wait(@mutex, @delay_seconds) while log_records.empty? && @keep_running
167
- return unless @keep_running
168
-
169
- fetch_batch
170
- end
171
-
172
- export_batch(batch)
173
- end
174
- end
175
-
176
- def reset_on_fork(restart_thread: true)
177
- pid = Process.pid
178
- return if @pid == pid
179
-
180
- @pid = pid
181
- log_records.clear
182
- @thread = restart_thread ? Thread.new { work } : nil
183
- rescue ThreadError => e
184
- OpenTelemetry.handle_error(exception: e, message: 'unexpected error in BatchLogRecordProcessor#reset_on_fork')
185
- end
186
-
187
- def export_batch(batch, timeout: @exporter_timeout_seconds)
188
- result_code = @export_mutex.synchronize { @exporter.export(batch, timeout: timeout) }
189
- report_result(result_code, batch)
190
- result_code
191
- rescue StandardError => e
192
- report_result(FAILURE, batch)
193
- OpenTelemetry.handle_error(exception: e, message: 'unexpected error in BatchLogRecordProcessor#export_batch')
194
- end
195
-
196
- def report_result(result_code, batch)
197
- if result_code == SUCCESS
198
- OpenTelemetry.logger.debug("Successfully exported #{batch.size} log records")
199
- else
200
- OpenTelemetry.handle_error(exception: ExportError.new("Unable to export #{batch.size} log records"))
201
- OpenTelemetry.logger.error("Result code: #{result_code}")
202
- end
203
- end
204
-
205
- def report_dropped_log_records(count, reason:)
206
- OpenTelemetry.logger.warn("#{count} log record(s) dropped. Reason: #{reason}")
207
- end
208
-
209
- def fetch_batch
210
- log_records.shift(@batch_size).map!(&:to_log_record_data)
211
- end
212
-
213
- def lock(&block)
214
- @mutex.synchronize(&block)
215
- end
216
- end
217
- end
218
- end
219
- end
220
- end
221
- end
222
- end
223
- end
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
-
7
- module ScoutApm
8
- module Logging
9
- module Loggers
10
- module OpenTelemetry
11
- module SDK
12
- module Logs
13
- module Export
14
- # LogRecordExporter describes a duck type. It is not required to
15
- # subclass this class to provide an implementation of LogRecordExporter,
16
- # provided the interface is satisfied. LogRecordExporter allows
17
- # different tracing services to export log record data in their own format.
18
- #
19
- # To export data an exporter MUST be registered to the {LoggerProvider}
20
- # using a {LogRecordProcessor} implementation.
21
- class LogRecordExporter
22
- def initialize
23
- @stopped = false
24
- end
25
-
26
- # Called to export {LogRecordData}s.
27
- #
28
- # @param [Enumerable<LogRecordData>] log_record_data the list of
29
- # {LogRecordData} to be exported.
30
- # @param [optional Numeric] timeout An optional timeout in seconds.
31
- #
32
- # @return [Integer] the result of the export.
33
- def export(log_record_data, timeout: nil)
34
- return SUCCESS unless @stopped
35
-
36
- FAILURE
37
- end
38
-
39
- # Called when {LoggerProvider#force_flush} is called, if this exporter is
40
- # registered to a {LoggerProvider} object.
41
- #
42
- # @param [optional Numeric] timeout An optional timeout in seconds.
43
- # @return [Integer] SUCCESS if no error occurred, FAILURE if a
44
- # non-specific failure occurred, TIMEOUT if a timeout occurred.
45
- def force_flush(timeout: nil)
46
- SUCCESS
47
- end
48
-
49
- # Called when {LoggerProvider#shutdown} is called, if this exporter is
50
- # registered to a {LoggerProvider} object.
51
- #
52
- # @param [optional Numeric] timeout An optional timeout in seconds.
53
- def shutdown(timeout: nil)
54
- @stopped = true
55
- SUCCESS
56
- end
57
- end
58
- end
59
- end
60
- end
61
- end
62
- end
63
- end
64
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
-
7
- module ScoutApm
8
- module Logging
9
- module Loggers
10
- module OpenTelemetry
11
- module SDK
12
- module Logs
13
- # The Export module contains the built-in exporters and log record
14
- # processors for the OpenTelemetry reference implementation.
15
- module Export
16
- ExportError = Class.new(::OpenTelemetry::Error)
17
- # The operation finished successfully.
18
- SUCCESS = 0
19
-
20
- # The operation finished with an error.
21
- FAILURE = 1
22
-
23
- # The operation timed out.
24
- TIMEOUT = 2
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
32
-
33
- require_relative 'export/log_record_exporter'
34
- require_relative 'export/batch_log_record_processor'
@@ -1,170 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
-
7
- module ScoutApm
8
- module Logging
9
- module Loggers
10
- module OpenTelemetry
11
- module SDK
12
- module Logs
13
- # Implementation of OpenTelemetry::Logs::LogRecord that records log events.
14
- class LogRecord < OpenTelemetry::Logs::LogRecord
15
- EMPTY_ATTRIBUTES = {}.freeze
16
-
17
- private_constant :EMPTY_ATTRIBUTES
18
-
19
- attr_accessor :timestamp,
20
- :observed_timestamp,
21
- :severity_text,
22
- :severity_number,
23
- :body,
24
- :attributes,
25
- :trace_id,
26
- :span_id,
27
- :trace_flags,
28
- :resource,
29
- :instrumentation_scope
30
-
31
- # Creates a new {LogRecord}.
32
- #
33
- # @param [optional Time] timestamp Time when the event occurred.
34
- # @param [optional Time] observed_timestamp Time when the event
35
- # was observed by the collection system. If nil, will first attempt
36
- # to set to `timestamp`. If `timestamp` is nil, will set to Time.now.
37
- # @param [optional OpenTelemetry::Trace::SpanContext] span_context The
38
- # OpenTelemetry::Trace::SpanContext to associate with the LogRecord.
39
- # @param [optional String] severity_text The log severity, also known as
40
- # log level.
41
- # @param [optional Integer] severity_number The numerical value of the
42
- # log severity.
43
- # @param [optional String, Numeric, Boolean, Array<String, Numeric,
44
- # Boolean>, Hash{String => String, Numeric, Boolean, Array<String,
45
- # Numeric, Boolean>}] body The body of the {LogRecord}.
46
- # @param [optional Hash{String => String, Numeric, Boolean,
47
- # Array<String, Numeric, Boolean>}] attributes Attributes to associate
48
- # with the {LogRecord}.
49
- # @param [optional String] trace_id The trace ID associated with the
50
- # current context.
51
- # @param [optional String] span_id The span ID associated with the
52
- # current context.
53
- # @param [optional OpenTelemetry::Trace::TraceFlags] trace_flags The
54
- # trace flags associated with the current context.
55
- # @param [optional OpenTelemetry::SDK::Resources::Resource] resource The
56
- # source of the log, desrived from the LoggerProvider.
57
- # @param [optional OpenTelemetry::SDK::InstrumentationScope] instrumentation_scope
58
- # The instrumentation scope, derived from the emitting Logger
59
- # @param [optional] OpenTelemetry::SDK::LogRecordLimits] log_record_limits
60
- # Attribute limits
61
- #
62
- #
63
- # @return [LogRecord]
64
- def initialize(
65
- timestamp: nil,
66
- observed_timestamp: nil,
67
- severity_text: nil,
68
- severity_number: nil,
69
- body: nil,
70
- attributes: nil,
71
- trace_id: nil,
72
- span_id: nil,
73
- trace_flags: nil,
74
- resource: nil,
75
- instrumentation_scope: nil,
76
- log_record_limits: nil
77
- )
78
- @timestamp = timestamp
79
- @observed_timestamp = observed_timestamp || timestamp || Time.now
80
- @severity_text = severity_text
81
- @severity_number = severity_number
82
- @body = body
83
- @attributes = attributes.nil? ? nil : Hash[attributes] # We need a mutable copy of attributes
84
- @trace_id = trace_id
85
- @span_id = span_id
86
- @trace_flags = trace_flags
87
- @resource = resource
88
- @instrumentation_scope = instrumentation_scope
89
- @log_record_limits = log_record_limits || LogRecordLimits::DEFAULT
90
- @total_recorded_attributes = @attributes&.size || 0
91
-
92
- trim_attributes(@attributes)
93
- end
94
-
95
- def to_log_record_data
96
- LogRecordData.new(
97
- to_integer_nanoseconds(@timestamp),
98
- to_integer_nanoseconds(@observed_timestamp),
99
- @severity_text,
100
- @severity_number,
101
- @body,
102
- @attributes,
103
- @trace_id,
104
- @span_id,
105
- @trace_flags,
106
- @resource,
107
- @instrumentation_scope,
108
- @total_recorded_attributes
109
- )
110
- end
111
-
112
- private
113
-
114
- def to_integer_nanoseconds(timestamp)
115
- return unless timestamp.is_a?(Time)
116
-
117
- (timestamp.to_r * 10**9).to_i
118
- end
119
-
120
- def trim_attributes(attributes)
121
- return if attributes.nil?
122
-
123
- # truncate total attributes
124
- truncate_attributes(attributes, @log_record_limits.attribute_count_limit)
125
-
126
- # truncate attribute values
127
- truncate_attribute_values(attributes, @log_record_limits.attribute_length_limit)
128
-
129
- # validate attributes
130
- validate_attributes(attributes)
131
-
132
- nil
133
- end
134
-
135
- def truncate_attributes(attributes, attribute_limit)
136
- excess = attributes.size - attribute_limit
137
- excess.times { attributes.shift } if excess.positive?
138
- end
139
-
140
- def validate_attributes(attrs)
141
- # Similar to Internal.valid_attributes?, but with different messages
142
- # Future refactor opportunity: https://github.com/open-telemetry/opentelemetry-ruby/issues/1739
143
- attrs.keep_if do |k, v|
144
- if !::OpenTelemetry::SDK::Internal.valid_key?(k)
145
- OpenTelemetry.handle_error(message: "invalid log record attribute key type #{k.class}, #{k} on record: '#{body}'")
146
- return false
147
- elsif !::OpenTelemetry::SDK::Internal.valid_value?(v)
148
- OpenTelemetry.handle_error(message: "invalid log record attribute value type #{v.class} for key '#{k}' on record: '#{body}'")
149
- return false
150
- end
151
-
152
- true
153
- end
154
- end
155
-
156
- def truncate_attribute_values(attributes, attribute_length_limit)
157
- return EMPTY_ATTRIBUTES if attributes.nil?
158
- return attributes if attribute_length_limit.nil?
159
-
160
- attributes.transform_values! { |value| ::OpenTelemetry::Common::Utilities.truncate_attribute_value(value, attribute_length_limit) }
161
-
162
- attributes
163
- end
164
- end
165
- end
166
- end
167
- end
168
- end
169
- end
170
- end