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.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +17 -2
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +6 -0
- data/README.md +7 -2
- data/lib/scout_apm/logging/config.rb +1 -1
- data/lib/scout_apm/logging/loggers/formatter.rb +1 -1
- data/lib/scout_apm/logging/loggers/opentelemetry/log_record_patch.rb +38 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/opentelemetry.rb +8 -31
- data/lib/scout_apm/logging/version.rb +1 -1
- data/scout_apm_logging.gemspec +4 -2
- data/spec/integration/rails/lifecycle_spec.rb +1 -1
- metadata +36 -31
- data/lib/scout_apm/logging/loggers/opentelemetry/LICENSE +0 -201
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/log_record.rb +0 -18
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/logger.rb +0 -64
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/logger_provider.rb +0 -31
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/severity_number.rb +0 -43
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/version.rb +0 -18
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs.rb +0 -28
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/exporter/otlp/logs_exporter.rb +0 -398
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/exporter/otlp/version.rb +0 -20
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/collector/logs/v1/logs_service_pb.rb +0 -43
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/common/v1/common_pb.rb +0 -58
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/logs/v1/logs_pb.rb +0 -91
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/resource/v1/resource_pb.rb +0 -33
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/batch_log_record_processor.rb +0 -223
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/log_record_exporter.rb +0 -64
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export.rb +0 -34
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record.rb +0 -170
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_data.rb +0 -31
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_limits.rb +0 -49
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_processor.rb +0 -52
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/logger.rb +0 -98
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/logger_provider.rb +0 -170
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/version.rb +0 -20
- 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
|
data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/batch_log_record_processor.rb
DELETED
@@ -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
|