scout_apm_logging 0.0.12 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +8 -0
- data/NOTICE +4 -0
- data/lib/scout_apm/logging/config.rb +5 -131
- data/lib/scout_apm/logging/loggers/capture.rb +8 -6
- data/lib/scout_apm/logging/loggers/formatter.rb +21 -2
- data/lib/scout_apm/logging/loggers/opentelemetry/LICENSE +201 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/NOTICE +9 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/log_record.rb +18 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/logger.rb +64 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/logger_provider.rb +31 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/severity_number.rb +43 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/version.rb +18 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/api/logs.rb +28 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/exporter/otlp/logs_exporter.rb +389 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/exporter/otlp/version.rb +20 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/collector/logs/v1/logs_service_pb.rb +43 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/common/v1/common_pb.rb +58 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/logs/v1/logs_pb.rb +91 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/resource/v1/resource_pb.rb +33 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/opentelemetry.rb +62 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/batch_log_record_processor.rb +225 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/log_record_exporter.rb +64 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export.rb +34 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record.rb +115 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_data.rb +31 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_processor.rb +53 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/logger.rb +94 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/logger_provider.rb +158 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/version.rb +20 -0
- data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs.rb +28 -0
- data/lib/scout_apm/logging/loggers/patches/rails_logger.rb +17 -0
- data/lib/scout_apm/logging/loggers/proxy.rb +22 -5
- data/lib/scout_apm/logging/loggers/swaps/rails.rb +4 -12
- data/lib/scout_apm/logging/loggers/swaps/scout.rb +2 -10
- data/lib/scout_apm/logging/loggers/swaps/sidekiq.rb +2 -6
- data/lib/scout_apm/logging/utils.rb +0 -69
- data/lib/scout_apm/logging/version.rb +1 -1
- data/lib/scout_apm_logging.rb +3 -12
- data/scout_apm_logging.gemspec +7 -0
- data/spec/data/config_test_1.yml +0 -1
- data/spec/data/mock_config.yml +0 -3
- data/spec/integration/rails/lifecycle_spec.rb +57 -23
- data/spec/spec_helper.rb +0 -12
- data/spec/unit/config_spec.rb +0 -12
- data/spec/unit/loggers/capture_spec.rb +0 -6
- metadata +127 -39
- data/bin/scout_apm_logging_monitor +0 -6
- data/lib/scout_apm/logging/monitor/_rails.rb +0 -22
- data/lib/scout_apm/logging/monitor/collector/checksum.rb +0 -51
- data/lib/scout_apm/logging/monitor/collector/configuration.rb +0 -150
- data/lib/scout_apm/logging/monitor/collector/downloader.rb +0 -78
- data/lib/scout_apm/logging/monitor/collector/extractor.rb +0 -37
- data/lib/scout_apm/logging/monitor/collector/manager.rb +0 -57
- data/lib/scout_apm/logging/monitor/monitor.rb +0 -216
- data/lib/scout_apm/logging/monitor_manager/manager.rb +0 -162
- data/lib/scout_apm/logging/state.rb +0 -69
- data/spec/data/empty_logs_config.yml +0 -0
- data/spec/data/logs_config.yml +0 -3
- data/spec/data/state_file.json +0 -3
- data/spec/integration/loggers/capture_spec.rb +0 -68
- data/spec/integration/monitor/collector/downloader/will_verify_checksum.rb +0 -49
- data/spec/integration/monitor/collector_healthcheck_spec.rb +0 -29
- data/spec/integration/monitor/continuous_state_collector_spec.rb +0 -31
- data/spec/integration/monitor/previous_collector_setup_spec.rb +0 -45
- data/spec/integration/monitor_manager/disable_agent_spec.rb +0 -30
- data/spec/integration/monitor_manager/monitor_pid_file_spec.rb +0 -38
- data/spec/integration/monitor_manager/single_monitor_spec.rb +0 -53
- data/spec/unit/monitor/collector/configuration_spec.rb +0 -64
- data/spec/unit/state_spec.rb +0 -20
- data/tooling/checksums.rb +0 -106
@@ -1,32 +1,45 @@
|
|
1
|
+
require 'webmock/rspec'
|
2
|
+
|
1
3
|
require 'spec_helper'
|
4
|
+
require 'zlib'
|
5
|
+
require 'stringio'
|
2
6
|
require_relative '../../rails/app'
|
3
7
|
|
4
8
|
describe ScoutApm::Logging do
|
9
|
+
before do
|
10
|
+
@file_path = '/app/response_body.txt'
|
11
|
+
# Capture the outgoing HTTP request to inspect its values
|
12
|
+
stub_request(:post, 'https://otlp-devel.scoutotel.com:4318/v1/logs')
|
13
|
+
.to_return do |request|
|
14
|
+
# We have to write to the file, as we are applying the patch in the fork, and
|
15
|
+
# need to run the expectations in the main process.
|
16
|
+
File.open(@file_path, 'a+') do |file|
|
17
|
+
msgs = transform_body_to_msgs(request.body)
|
18
|
+
file.puts(msgs)
|
19
|
+
end
|
20
|
+
{ body: '', headers: {}, status: 200 }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
5
24
|
it 'checks the Rails lifecycle for creating the daemon and collector processes' do
|
6
25
|
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
26
|
+
ENV['SCOUT_LOGS_REPORTING_ENDPOINT_HTTP'] = 'https://otlp-devel.scoutotel.com:4318/v1/logs'
|
7
27
|
|
8
|
-
context = ScoutApm::Logging::
|
9
|
-
|
10
|
-
expect(File.exist?(pid_file)).to be_falsey
|
28
|
+
context = ScoutApm::Logging::Context.new
|
29
|
+
context.config = ScoutApm::Logging::Config.with_file(context, context.config.value('config_file'))
|
11
30
|
|
12
31
|
rails_pid = fork do
|
13
32
|
initialize_app
|
14
33
|
end
|
15
34
|
|
16
|
-
|
17
|
-
|
18
|
-
# Check if the monitor PID file exists
|
19
|
-
expect(File.exist?(pid_file)).to be_truthy
|
20
|
-
|
21
|
-
# Read the PID from the PID file
|
22
|
-
pid = File.read(pid_file).to_i
|
23
|
-
|
24
|
-
# Check if the process with the stored PID is running
|
25
|
-
expect(ScoutApm::Logging::Utils.check_process_liveliness(pid, 'scout_apm_logging_monitor')).to be_truthy
|
35
|
+
# TODO: Improve check to wait for Rails initialization.
|
36
|
+
sleep 5
|
26
37
|
|
27
38
|
# Call the app to generate the logs
|
28
39
|
`curl localhost:8080`
|
29
40
|
|
41
|
+
sleep 5
|
42
|
+
|
30
43
|
proxy_dir = context.config.value('logs_proxy_log_dir')
|
31
44
|
files = Dir.entries(proxy_dir) - ['.', '..']
|
32
45
|
log_file = File.join(proxy_dir, files[0])
|
@@ -41,24 +54,45 @@ describe ScoutApm::Logging do
|
|
41
54
|
end
|
42
55
|
end
|
43
56
|
|
44
|
-
|
57
|
+
local_messages = lines.map { |item| item['msg'] }
|
45
58
|
|
46
|
-
# Verify we have all the logs
|
47
|
-
expect(
|
48
|
-
expect(
|
49
|
-
expect(
|
50
|
-
expect(
|
59
|
+
# Verify we have all the logs in the local log file
|
60
|
+
expect(local_messages.count('[TEST] Some log')).to eq(1)
|
61
|
+
expect(local_messages.count('[YIELD] Yield Test')).to eq(1)
|
62
|
+
expect(local_messages.count('Another Log')).to eq(1)
|
63
|
+
expect(local_messages.count('Should not be captured')).to eq(0)
|
51
64
|
|
52
65
|
log_locations = lines.map { |item| item['log_location'] }.compact
|
53
66
|
|
54
67
|
# Verify that log attributes aren't persisted
|
55
68
|
expect(log_locations.size).to eq(1)
|
56
69
|
|
70
|
+
# Verify the logs are sent to the receiver
|
71
|
+
receiver_contents = File.readlines(@file_path, chomp: true)
|
72
|
+
expect(receiver_contents.count('[TEST] Some log')).to eq(1)
|
73
|
+
expect(receiver_contents.count('[YIELD] Yield Test')).to eq(1)
|
74
|
+
expect(receiver_contents.count('Another Log')).to eq(1)
|
75
|
+
expect(receiver_contents.count('Should not be captured')).to eq(0)
|
76
|
+
|
57
77
|
# Kill the rails process. We use kill as using any other signal throws a long log line.
|
58
78
|
Process.kill('KILL', rails_pid)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def transform_body_to_msgs(body)
|
84
|
+
gz = Zlib::GzipReader.new(StringIO.new(body))
|
85
|
+
uncompressed = gz.read
|
86
|
+
|
87
|
+
value = ScoutApm::Logging::Loggers::Opentelemetry::Proto::Collector::Logs::V1::ExportLogsServiceRequest.decode(uncompressed)
|
88
|
+
value_hash = value.to_h
|
89
|
+
|
90
|
+
value_hash[:resource_logs].map do |item|
|
91
|
+
item[:scope_logs].map do |sl|
|
92
|
+
sl[:log_records].map do |log|
|
93
|
+
log[:body][:string_value]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end.flatten
|
63
97
|
end
|
64
98
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -23,20 +23,8 @@ end
|
|
23
23
|
RSpec.configure do |config|
|
24
24
|
ENV["SCOUT_LOG_FILE_PATH"] = "STDOUT"
|
25
25
|
ENV["SCOUT_LOG_LEVEL"] = "debug"
|
26
|
-
ENV["SCOUT_COLLECTOR_LOG_LEVEL"] = "info"
|
27
26
|
|
28
27
|
config.after(:each) do
|
29
28
|
RSpec::Mocks.space.reset_all
|
30
29
|
end
|
31
30
|
end
|
32
|
-
|
33
|
-
def wait_for_process_with_timeout!(name, timeout_time)
|
34
|
-
Timeout::timeout(timeout_time) do
|
35
|
-
loop do
|
36
|
-
break if `pgrep #{name} --runstates D,R,S`.strip != ""
|
37
|
-
sleep 0.1
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
sleep 1
|
42
|
-
end
|
data/spec/unit/config_spec.rb
CHANGED
@@ -8,18 +8,6 @@ describe ScoutApm::Logging::Config do
|
|
8
8
|
|
9
9
|
expect(conf.value('log_level')).to eq('debug')
|
10
10
|
expect(conf.value('logs_monitor')).to eq(true)
|
11
|
-
expect(conf.value('monitor_pid_file')).to eq('/tmp/scout_apm/scout_apm_log_monitor.pid')
|
12
11
|
expect(conf.value('logs_ingest_key')).to eq('00001000010000abc')
|
13
|
-
expect(conf.value('logs_monitored')).to eq(['/tmp/fake_log_file.log'])
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'loads the state file into the config' do
|
17
|
-
ENV['SCOUT_MONITOR_STATE_FILE'] = File.expand_path('../data/state_file.json', __dir__)
|
18
|
-
|
19
|
-
context = ScoutApm::Logging::Context.new
|
20
|
-
conf_file = File.expand_path('../data/config_test_1.yml', __dir__)
|
21
|
-
conf = ScoutApm::Logging::Config.with_file(context, conf_file)
|
22
|
-
|
23
|
-
expect(conf.value('health_check_port')).to eq(1234)
|
24
12
|
end
|
25
13
|
end
|
@@ -16,8 +16,6 @@ end
|
|
16
16
|
|
17
17
|
describe ScoutApm::Logging::Loggers::Capture do
|
18
18
|
it 'should swap the STDOUT logger and create a proxy logger' do
|
19
|
-
ENV['SCOUT_MONITOR_INTERVAL'] = '10'
|
20
|
-
ENV['SCOUT_MONITOR_INTERVAL_DELAY'] = '10'
|
21
19
|
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
22
20
|
ENV['SCOUT_LOGS_CAPTURE_LEVEL'] = 'debug'
|
23
21
|
|
@@ -47,10 +45,6 @@ describe ScoutApm::Logging::Loggers::Capture do
|
|
47
45
|
# Shouldn't capture. While the log_capture_level was set to debug,
|
48
46
|
# the original logger instance had a higher log level of info.
|
49
47
|
expect(content).not_to include('SHOULD NOT CAPTURE')
|
50
|
-
|
51
|
-
state_file = File.read(context.config.value('monitor_state_file'))
|
52
|
-
state_data = JSON.parse(state_file)
|
53
|
-
expect(state_data['logs_monitored']).to eq([log_path])
|
54
48
|
end
|
55
49
|
|
56
50
|
expect(output_from_log).to include('TEST')
|
metadata
CHANGED
@@ -1,15 +1,99 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scout_apm_logging
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scout APM
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: googleapis-common-protos-types
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: google-protobuf
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "<"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.18'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "<"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.18'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: opentelemetry-api
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: opentelemetry-common
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: opentelemetry-instrumentation-base
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: opentelemetry-sdk
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.2'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.2'
|
13
97
|
- !ruby/object:Gem::Dependency
|
14
98
|
name: scout_apm
|
15
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +150,20 @@ dependencies:
|
|
66
150
|
- - '='
|
67
151
|
- !ruby/object:Gem::Version
|
68
152
|
version: 1.30.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: webmock
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
69
167
|
description: Sets up log monitoring for Scout APM Ruby clients.
|
70
168
|
email:
|
71
169
|
- support@scoutapp.com
|
@@ -79,9 +177,9 @@ files:
|
|
79
177
|
- CHANGELOG.md
|
80
178
|
- Dockerfile
|
81
179
|
- Gemfile
|
180
|
+
- NOTICE
|
82
181
|
- README.md
|
83
182
|
- Rakefile
|
84
|
-
- bin/scout_apm_logging_monitor
|
85
183
|
- gems/rails.gemfile
|
86
184
|
- lib/scout_apm/logging/config.rb
|
87
185
|
- lib/scout_apm/logging/context.rb
|
@@ -89,45 +187,48 @@ files:
|
|
89
187
|
- lib/scout_apm/logging/loggers/capture.rb
|
90
188
|
- lib/scout_apm/logging/loggers/formatter.rb
|
91
189
|
- lib/scout_apm/logging/loggers/logger.rb
|
190
|
+
- lib/scout_apm/logging/loggers/opentelemetry/LICENSE
|
191
|
+
- lib/scout_apm/logging/loggers/opentelemetry/NOTICE
|
192
|
+
- lib/scout_apm/logging/loggers/opentelemetry/api/logs.rb
|
193
|
+
- lib/scout_apm/logging/loggers/opentelemetry/api/logs/log_record.rb
|
194
|
+
- lib/scout_apm/logging/loggers/opentelemetry/api/logs/logger.rb
|
195
|
+
- lib/scout_apm/logging/loggers/opentelemetry/api/logs/logger_provider.rb
|
196
|
+
- lib/scout_apm/logging/loggers/opentelemetry/api/logs/severity_number.rb
|
197
|
+
- lib/scout_apm/logging/loggers/opentelemetry/api/logs/version.rb
|
198
|
+
- lib/scout_apm/logging/loggers/opentelemetry/exporter/exporter/otlp/logs_exporter.rb
|
199
|
+
- lib/scout_apm/logging/loggers/opentelemetry/exporter/exporter/otlp/version.rb
|
200
|
+
- lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/collector/logs/v1/logs_service_pb.rb
|
201
|
+
- lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/common/v1/common_pb.rb
|
202
|
+
- lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/logs/v1/logs_pb.rb
|
203
|
+
- lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/resource/v1/resource_pb.rb
|
204
|
+
- lib/scout_apm/logging/loggers/opentelemetry/opentelemetry.rb
|
205
|
+
- lib/scout_apm/logging/loggers/opentelemetry/sdk/logs.rb
|
206
|
+
- lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export.rb
|
207
|
+
- lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/batch_log_record_processor.rb
|
208
|
+
- lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/log_record_exporter.rb
|
209
|
+
- lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record.rb
|
210
|
+
- lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_data.rb
|
211
|
+
- lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_processor.rb
|
212
|
+
- lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/logger.rb
|
213
|
+
- lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/logger_provider.rb
|
214
|
+
- lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/version.rb
|
215
|
+
- lib/scout_apm/logging/loggers/patches/rails_logger.rb
|
92
216
|
- lib/scout_apm/logging/loggers/patches/tagged_logging.rb
|
93
217
|
- lib/scout_apm/logging/loggers/proxy.rb
|
94
218
|
- lib/scout_apm/logging/loggers/swaps/rails.rb
|
95
219
|
- lib/scout_apm/logging/loggers/swaps/scout.rb
|
96
220
|
- lib/scout_apm/logging/loggers/swaps/sidekiq.rb
|
97
|
-
- lib/scout_apm/logging/monitor/_rails.rb
|
98
|
-
- lib/scout_apm/logging/monitor/collector/checksum.rb
|
99
|
-
- lib/scout_apm/logging/monitor/collector/configuration.rb
|
100
|
-
- lib/scout_apm/logging/monitor/collector/downloader.rb
|
101
|
-
- lib/scout_apm/logging/monitor/collector/extractor.rb
|
102
|
-
- lib/scout_apm/logging/monitor/collector/manager.rb
|
103
|
-
- lib/scout_apm/logging/monitor/monitor.rb
|
104
|
-
- lib/scout_apm/logging/monitor_manager/manager.rb
|
105
|
-
- lib/scout_apm/logging/state.rb
|
106
221
|
- lib/scout_apm/logging/utils.rb
|
107
222
|
- lib/scout_apm/logging/version.rb
|
108
223
|
- lib/scout_apm_logging.rb
|
109
224
|
- scout_apm_logging.gemspec
|
110
225
|
- spec/data/config_test_1.yml
|
111
|
-
- spec/data/empty_logs_config.yml
|
112
|
-
- spec/data/logs_config.yml
|
113
226
|
- spec/data/mock_config.yml
|
114
|
-
- spec/data/state_file.json
|
115
|
-
- spec/integration/loggers/capture_spec.rb
|
116
|
-
- spec/integration/monitor/collector/downloader/will_verify_checksum.rb
|
117
|
-
- spec/integration/monitor/collector_healthcheck_spec.rb
|
118
|
-
- spec/integration/monitor/continuous_state_collector_spec.rb
|
119
|
-
- spec/integration/monitor/previous_collector_setup_spec.rb
|
120
|
-
- spec/integration/monitor_manager/disable_agent_spec.rb
|
121
|
-
- spec/integration/monitor_manager/monitor_pid_file_spec.rb
|
122
|
-
- spec/integration/monitor_manager/single_monitor_spec.rb
|
123
227
|
- spec/integration/rails/lifecycle_spec.rb
|
124
228
|
- spec/rails/app.rb
|
125
229
|
- spec/spec_helper.rb
|
126
230
|
- spec/unit/config_spec.rb
|
127
231
|
- spec/unit/loggers/capture_spec.rb
|
128
|
-
- spec/unit/monitor/collector/configuration_spec.rb
|
129
|
-
- spec/unit/state_spec.rb
|
130
|
-
- tooling/checksums.rb
|
131
232
|
homepage: https://github.com/scoutapp/scout_apm_ruby_logging
|
132
233
|
licenses:
|
133
234
|
- MIT
|
@@ -153,22 +254,9 @@ specification_version: 4
|
|
153
254
|
summary: Ruby Logging Support
|
154
255
|
test_files:
|
155
256
|
- spec/data/config_test_1.yml
|
156
|
-
- spec/data/empty_logs_config.yml
|
157
|
-
- spec/data/logs_config.yml
|
158
257
|
- spec/data/mock_config.yml
|
159
|
-
- spec/data/state_file.json
|
160
|
-
- spec/integration/loggers/capture_spec.rb
|
161
|
-
- spec/integration/monitor/collector/downloader/will_verify_checksum.rb
|
162
|
-
- spec/integration/monitor/collector_healthcheck_spec.rb
|
163
|
-
- spec/integration/monitor/continuous_state_collector_spec.rb
|
164
|
-
- spec/integration/monitor/previous_collector_setup_spec.rb
|
165
|
-
- spec/integration/monitor_manager/disable_agent_spec.rb
|
166
|
-
- spec/integration/monitor_manager/monitor_pid_file_spec.rb
|
167
|
-
- spec/integration/monitor_manager/single_monitor_spec.rb
|
168
258
|
- spec/integration/rails/lifecycle_spec.rb
|
169
259
|
- spec/rails/app.rb
|
170
260
|
- spec/spec_helper.rb
|
171
261
|
- spec/unit/config_spec.rb
|
172
262
|
- spec/unit/loggers/capture_spec.rb
|
173
|
-
- spec/unit/monitor/collector/configuration_spec.rb
|
174
|
-
- spec/unit/state_spec.rb
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# We start the monitor process outside the context of Rails, and ultimately don't use
|
4
|
-
# it for anything related to starting the collector. However, when we load the config/scout_apm.yml file,
|
5
|
-
# we support ERB, and users may be using Rails.env methods for naming the app, or configuring whether
|
6
|
-
# monitor should be enabled for a specific environment.
|
7
|
-
|
8
|
-
require 'active_support'
|
9
|
-
|
10
|
-
# https://github.com/rails/rails/blob/v7.2.1/railties/lib/rails.rb#L76
|
11
|
-
module Rails
|
12
|
-
class << self
|
13
|
-
def env
|
14
|
-
# EnvironmentInquirer was added in Rails 6.1
|
15
|
-
@env ||= if const_defined?('::ActiveSupport::EnvironmentInquirer')
|
16
|
-
::ActiveSupport::EnvironmentInquirer.new(ENV['RAILS_ENV'].presence || ENV['RACK_ENV'].presence || 'development')
|
17
|
-
else
|
18
|
-
::ActiveSupport::StringInquirer.new(ENV['RAILS_ENV'].presence || ENV['RACK_ENV'].presence || 'development')
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ScoutApm
|
4
|
-
module Logging
|
5
|
-
module Collector
|
6
|
-
# Contains logic around verifying the checksum of the otelcol-contrib binary.
|
7
|
-
class Checksum
|
8
|
-
attr_reader :context
|
9
|
-
|
10
|
-
KNOWN_CHECKSUMS = {
|
11
|
-
'darwin_amd64' => '5456734e124221e7ff775c52bd3693d05b3fac43ebe06b22aa5f220f1962ed8c',
|
12
|
-
'darwin_arm64' => 'f9564560798ac5c099885903f303fcda97b7ea649ec299e075b72f3805873879',
|
13
|
-
'linux_amd64' => '326772622016f7ff7e966a7ae8a0f439dc49a3d80b6d79a82b62608af447e851',
|
14
|
-
'linux_arm64' => '73d797817540363a37f27e32270f98053ed17b1df36df2d30db1715ce40f4cff'
|
15
|
-
}.freeze
|
16
|
-
|
17
|
-
def initialize(context)
|
18
|
-
@context = context
|
19
|
-
end
|
20
|
-
|
21
|
-
def verified_checksum?(should_log_failures: false)
|
22
|
-
return false unless File.exist?(collector_tar_path)
|
23
|
-
|
24
|
-
checksum = `sha256sum #{collector_tar_path}`.split(' ').first
|
25
|
-
same_checksum_result = checksum == KNOWN_CHECKSUMS[double]
|
26
|
-
|
27
|
-
log_failed_checksum if !same_checksum_result && should_log_failures
|
28
|
-
same_checksum_result
|
29
|
-
end
|
30
|
-
|
31
|
-
def log_failed_checksum
|
32
|
-
if KNOWN_CHECKSUMS.key?(double)
|
33
|
-
context.logger.error('Checksum verification failed for otelcol.tar.gz.')
|
34
|
-
else
|
35
|
-
context.logger.error("Checksum verification failed for otelcol.tar.gz. Unknown architecture: #{double}")
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def double
|
42
|
-
"#{Utils.get_host_os}_#{Utils.get_architecture}"
|
43
|
-
end
|
44
|
-
|
45
|
-
def collector_tar_path
|
46
|
-
"#{context.config.value('collector_download_dir')}/otelcol.tar.gz"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,150 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ScoutApm
|
4
|
-
module Logging
|
5
|
-
module Collector
|
6
|
-
# Adds a method to Hash similar to that of the Rails deep_merge.
|
7
|
-
module HashDeepMerge
|
8
|
-
refine Hash do
|
9
|
-
def deep_merge(second)
|
10
|
-
merger = proc { |_, v1, v2|
|
11
|
-
if v1.is_a?(Hash) && v2.is_a?(Hash)
|
12
|
-
v1.merge(v2, &merger)
|
13
|
-
elsif v1.is_a?(Array) && v2.is_a?(Array)
|
14
|
-
v1 | v2
|
15
|
-
else
|
16
|
-
[:undefined, nil, :nil].include?(v2) ? v1 : v2
|
17
|
-
end
|
18
|
-
}
|
19
|
-
merge(second.to_h, &merger)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Creates the configuration to be used when launching the collector.
|
25
|
-
class Configuration
|
26
|
-
using HashDeepMerge
|
27
|
-
|
28
|
-
attr_reader :context
|
29
|
-
|
30
|
-
def initialize(context)
|
31
|
-
@context = context
|
32
|
-
end
|
33
|
-
|
34
|
-
def setup!
|
35
|
-
create_storage_directories
|
36
|
-
|
37
|
-
create_config_file
|
38
|
-
end
|
39
|
-
|
40
|
-
def create_config_file
|
41
|
-
contents = YAML.dump(combined_contents)
|
42
|
-
File.write(config_file, contents)
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def create_storage_directories
|
48
|
-
# Sending queue storage directory
|
49
|
-
Utils.ensure_directory_exists(context.config.value('collector_sending_queue_storage_dir'))
|
50
|
-
# Offset storage directory
|
51
|
-
Utils.ensure_directory_exists(context.config.value('collector_offset_storage_dir'))
|
52
|
-
end
|
53
|
-
|
54
|
-
def combined_contents
|
55
|
-
default_contents = YAML.safe_load(config_contents)
|
56
|
-
|
57
|
-
default_contents.deep_merge(loaded_config_contents)
|
58
|
-
end
|
59
|
-
|
60
|
-
def loaded_config_contents
|
61
|
-
config_path = context.config.value('logs_config')
|
62
|
-
|
63
|
-
if config_path && File.exist?(config_path)
|
64
|
-
YAML.load_file(config_path) || {}
|
65
|
-
elsif File.exist?(assumed_config_file_path)
|
66
|
-
YAML.load_file(assumed_config_file_path) || {}
|
67
|
-
else
|
68
|
-
{}
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def config_file
|
73
|
-
context.config.value('collector_config_file')
|
74
|
-
end
|
75
|
-
|
76
|
-
def config_contents # rubocop:disable Metrics/AbcSize
|
77
|
-
<<~CONFIG
|
78
|
-
receivers:
|
79
|
-
filelog:
|
80
|
-
include: [#{context.config.value('logs_monitored').join(',')}]
|
81
|
-
storage: file_storage/filelogreceiver
|
82
|
-
operators:
|
83
|
-
- type: json_parser
|
84
|
-
severity:
|
85
|
-
parse_from: attributes.severity
|
86
|
-
timestamp:
|
87
|
-
parse_from: attributes.time
|
88
|
-
layout: "%Y-%m-%dT%H:%M:%S.%LZ"
|
89
|
-
processors:
|
90
|
-
transform:
|
91
|
-
log_statements:
|
92
|
-
- context: log
|
93
|
-
statements:
|
94
|
-
# Copy original body to raw_bytes attribute.
|
95
|
-
- 'set(attributes["raw_bytes"], body)'
|
96
|
-
# Replace the body with the log message.
|
97
|
-
- 'set(body, attributes["msg"])'
|
98
|
-
# Remove the msg attribute.
|
99
|
-
- 'delete_key(attributes, "msg")'
|
100
|
-
# Move service.name attribute to resource attribute.
|
101
|
-
- 'set(resource.attributes["service.name"], attributes["service.name"])'
|
102
|
-
batch:
|
103
|
-
exporters:
|
104
|
-
otlp:
|
105
|
-
endpoint: #{context.config.value('logs_reporting_endpoint')}
|
106
|
-
headers:
|
107
|
-
x-telemetryhub-key: #{context.config.value('logs_ingest_key')}
|
108
|
-
sending_queue:
|
109
|
-
storage: file_storage/otc
|
110
|
-
extensions:
|
111
|
-
health_check:
|
112
|
-
endpoint: #{health_check_endpoint}
|
113
|
-
file_storage/filelogreceiver:
|
114
|
-
directory: #{context.config.value('collector_offset_storage_dir')}
|
115
|
-
file_storage/otc:
|
116
|
-
directory: #{context.config.value('collector_sending_queue_storage_dir')}
|
117
|
-
timeout: 10s
|
118
|
-
service:
|
119
|
-
extensions:
|
120
|
-
- health_check
|
121
|
-
- file_storage/filelogreceiver
|
122
|
-
- file_storage/otc
|
123
|
-
pipelines:
|
124
|
-
logs:
|
125
|
-
receivers:
|
126
|
-
- filelog
|
127
|
-
processors:
|
128
|
-
- transform
|
129
|
-
- batch
|
130
|
-
exporters:
|
131
|
-
- otlp
|
132
|
-
telemetry:
|
133
|
-
metrics:
|
134
|
-
level: none
|
135
|
-
logs:
|
136
|
-
level: #{context.config.value('collector_log_level')}
|
137
|
-
CONFIG
|
138
|
-
end
|
139
|
-
|
140
|
-
def health_check_endpoint
|
141
|
-
"localhost:#{context.config.value('health_check_port')}"
|
142
|
-
end
|
143
|
-
|
144
|
-
def assumed_config_file_path
|
145
|
-
"#{context.application_root}/config/scout_logs_config.yml"
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|