scout_apm_logging 0.0.12 → 1.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/.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,68 +0,0 @@
|
|
1
|
-
require 'logger'
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
require_relative '../../../lib/scout_apm/logging/loggers/capture'
|
6
|
-
|
7
|
-
describe ScoutApm::Logging::Loggers::Capture do
|
8
|
-
it 'should find the logger, capture the log destination, and rotate collector configs' do
|
9
|
-
ENV['SCOUT_MONITOR_INTERVAL'] = '10'
|
10
|
-
ENV['SCOUT_MONITOR_INTERVAL_DELAY'] = '10'
|
11
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
12
|
-
|
13
|
-
context = ScoutApm::Logging::MonitorManager.instance.context
|
14
|
-
|
15
|
-
state_file_location = context.config.value('monitor_state_file')
|
16
|
-
collector_pid_location = context.config.value('collector_pid_file')
|
17
|
-
ScoutApm::Logging::Utils.ensure_directory_exists(state_file_location)
|
18
|
-
|
19
|
-
first_logger = ScoutTestLogger.new('/tmp/first_file.log')
|
20
|
-
first_logger_basename = File.basename(first_logger.instance_variable_get(:@logdev).filename.to_s)
|
21
|
-
first_logger_updated_path = File.join(context.config.value('logs_proxy_log_dir'), first_logger_basename)
|
22
|
-
TestLoggerWrapper.logger = first_logger
|
23
|
-
|
24
|
-
similuate_railtie
|
25
|
-
|
26
|
-
# Give the process time to initialize, download the collector, and start it
|
27
|
-
wait_for_process_with_timeout!('otelcol-contrib', 20)
|
28
|
-
|
29
|
-
expect(`pgrep otelcol-contrib --runstates D,R,S`).not_to be_empty
|
30
|
-
collector_pid = File.read(collector_pid_location)
|
31
|
-
|
32
|
-
content = File.read(state_file_location)
|
33
|
-
data = JSON.parse(content)
|
34
|
-
expect(data['logs_monitored']).to eq([first_logger_updated_path])
|
35
|
-
|
36
|
-
second_logger = ScoutTestLogger.new('/tmp/second_file.log')
|
37
|
-
second_logger_basename = File.basename(second_logger.instance_variable_get(:@logdev).filename.to_s)
|
38
|
-
second_logger_updated_path = File.join(context.config.value('logs_proxy_log_dir'), second_logger_basename)
|
39
|
-
TestLoggerWrapper.logger = second_logger
|
40
|
-
|
41
|
-
similuate_railtie
|
42
|
-
|
43
|
-
content = File.read(state_file_location)
|
44
|
-
data = JSON.parse(content)
|
45
|
-
|
46
|
-
expect(data['logs_monitored'].sort).to eq([first_logger_updated_path, second_logger_updated_path])
|
47
|
-
|
48
|
-
# Need to wait for the delay first health check, next monitor interval to restart the collector, and then for
|
49
|
-
# the collector to restart
|
50
|
-
sleep 25
|
51
|
-
wait_for_process_with_timeout!('otelcol-contrib', 20)
|
52
|
-
|
53
|
-
expect(`pgrep otelcol-contrib --runstates D,R,S`).not_to be_empty
|
54
|
-
new_collector_pid = File.read(collector_pid_location)
|
55
|
-
|
56
|
-
# Should have restarted the collector based on the change
|
57
|
-
expect(new_collector_pid).not_to eq(collector_pid)
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def similuate_railtie
|
63
|
-
context = ScoutApm::Logging::MonitorManager.instance.context
|
64
|
-
|
65
|
-
ScoutApm::Logging::Loggers::Capture.new(context).setup!
|
66
|
-
ScoutApm::Logging::MonitorManager.new.setup!
|
67
|
-
end
|
68
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require_relative '../../../../../lib/scout_apm/logging/monitor/collector/downloader'
|
4
|
-
|
5
|
-
describe ScoutApm::Logging::Collector::Downloader do
|
6
|
-
it 'should validate checksum, and correct download if neccessary' do
|
7
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
8
|
-
ENV['SCOUT_LOGS_MONITORED'] = '["/tmp/test.log"]'
|
9
|
-
|
10
|
-
otelcol_contrib_path = '/tmp/scout_apm/otelcol-contrib'
|
11
|
-
ScoutApm::Logging::Utils.ensure_directory_exists(otelcol_contrib_path)
|
12
|
-
|
13
|
-
File.write(otelcol_contrib_path, 'fake content')
|
14
|
-
|
15
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time start: #{Time.now}"
|
16
|
-
ScoutApm::Logging::MonitorManager.instance.setup!
|
17
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time after setup: #{Time.now}"
|
18
|
-
|
19
|
-
# Give the process time to initialize, download the collector, and start it
|
20
|
-
wait_for_process_with_timeout!('otelcol-contrib', 20)
|
21
|
-
|
22
|
-
download_time = File.mtime(otelcol_contrib_path)
|
23
|
-
|
24
|
-
expect(`pgrep otelcol-contrib --runstates D,R,S`).not_to be_empty
|
25
|
-
|
26
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'false'
|
27
|
-
|
28
|
-
ScoutApm::Logging::MonitorManager.new.setup!
|
29
|
-
|
30
|
-
sleep 5 # Give the process time to exit
|
31
|
-
|
32
|
-
expect(File.exist?(ScoutApm::Logging::MonitorManager.instance.context.config.value('monitor_pid_file'))).to be_falsey
|
33
|
-
expect(`pgrep otelcol-contrib --runstates D,R,S`).to be_empty
|
34
|
-
expect(`pgrep scout_apm_log_monitor --runstates D,R,S`).to be_empty
|
35
|
-
|
36
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
37
|
-
|
38
|
-
ScoutApm::Logging::MonitorManager.new.setup!
|
39
|
-
|
40
|
-
# Give the process time to exit, and for the healthcheck to restart it
|
41
|
-
wait_for_process_with_timeout!('otelcol-contrib', 30)
|
42
|
-
|
43
|
-
expect(`pgrep otelcol-contrib --runstates D,R,S`).not_to be_empty
|
44
|
-
|
45
|
-
recheck_time = File.mtime(otelcol_contrib_path)
|
46
|
-
|
47
|
-
expect(download_time).to eq(recheck_time)
|
48
|
-
end
|
49
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require_relative '../../../lib/scout_apm/logging/monitor/monitor'
|
4
|
-
|
5
|
-
describe ScoutApm::Logging::Monitor do
|
6
|
-
it 'should recreate collector process on healthcheck if it has exited' do
|
7
|
-
ENV['SCOUT_MONITOR_INTERVAL'] = '10'
|
8
|
-
ENV['SCOUT_MONITOR_INTERVAL_DELAY'] = '10'
|
9
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
10
|
-
ENV['SCOUT_LOGS_MONITORED'] = '["/tmp/test.log"]'
|
11
|
-
|
12
|
-
ScoutApm::Logging::Utils.ensure_directory_exists('/tmp/scout_apm/scout_apm_log_monitor.pid')
|
13
|
-
|
14
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time start: #{Time.now}"
|
15
|
-
ScoutApm::Logging::MonitorManager.instance.setup!
|
16
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time after setup: #{Time.now}"
|
17
|
-
|
18
|
-
# Give the process time to initialize, download the collector, and start it
|
19
|
-
wait_for_process_with_timeout!('otelcol-contrib', 20)
|
20
|
-
|
21
|
-
expect(`pgrep otelcol-contrib --runstates D,R,S`).not_to be_empty
|
22
|
-
|
23
|
-
# Bypass gracefull shutdown
|
24
|
-
`pkill -9 otelcol-contrib`
|
25
|
-
|
26
|
-
# Give the process time to exit, and for the healthcheck to restart it
|
27
|
-
wait_for_process_with_timeout!('otelcol-contrib', 30)
|
28
|
-
end
|
29
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require_relative '../../../lib/scout_apm/logging/monitor/monitor'
|
4
|
-
|
5
|
-
describe ScoutApm::Logging::Monitor do
|
6
|
-
it "Should not restart the collector if the state hasn't changed" do
|
7
|
-
ENV['SCOUT_MONITOR_INTERVAL'] = '10'
|
8
|
-
ENV['SCOUT_MONITOR_INTERVAL_DELAY'] = '10'
|
9
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
10
|
-
ENV['SCOUT_LOGS_MONITORED'] = '["/tmp/test.log"]'
|
11
|
-
|
12
|
-
context = ScoutApm::Logging::MonitorManager.instance.context
|
13
|
-
collector_pid_location = context.config.value('collector_pid_file')
|
14
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time start: #{Time.now}"
|
15
|
-
ScoutApm::Logging::MonitorManager.instance.setup!
|
16
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time after setup: #{Time.now}"
|
17
|
-
# Give the process time to initialize, download the collector, and start it
|
18
|
-
wait_for_process_with_timeout!('otelcol-contrib', 20)
|
19
|
-
|
20
|
-
expect(`pgrep otelcol-contrib --runstates D,R,S`).not_to be_empty
|
21
|
-
collector_pid = File.read(collector_pid_location)
|
22
|
-
|
23
|
-
# Give time for the monitor interval to run.
|
24
|
-
sleep 30
|
25
|
-
|
26
|
-
expect(`pgrep otelcol-contrib --runstates D,R,S`).not_to be_empty
|
27
|
-
second_read_pid = File.read(collector_pid_location)
|
28
|
-
|
29
|
-
expect(second_read_pid).to eq(collector_pid)
|
30
|
-
end
|
31
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require_relative '../../../lib/scout_apm/logging/monitor/monitor'
|
4
|
-
|
5
|
-
describe ScoutApm::Logging::Monitor do
|
6
|
-
it 'should use previous collector setup if monitor daemon exits' do
|
7
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
8
|
-
ENV['SCOUT_LOGS_MONITORED'] = '["/tmp/test.log"]'
|
9
|
-
|
10
|
-
monitor_pid_location = ScoutApm::Logging::MonitorManager.instance.context.config.value('monitor_pid_file')
|
11
|
-
collector_pid_location = ScoutApm::Logging::MonitorManager.instance.context.config.value('collector_pid_file')
|
12
|
-
ScoutApm::Logging::Utils.ensure_directory_exists(monitor_pid_location)
|
13
|
-
|
14
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time start: #{Time.now}"
|
15
|
-
ScoutApm::Logging::MonitorManager.instance.setup!
|
16
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time after setup: #{Time.now}"
|
17
|
-
|
18
|
-
# Give the process time to initialize, download the collector, and start it
|
19
|
-
wait_for_process_with_timeout!('otelcol-contrib', 20)
|
20
|
-
|
21
|
-
monitor_pid = File.read(monitor_pid_location)
|
22
|
-
|
23
|
-
otelcol_pid = `pgrep otelcol-contrib --runstates D,R,S`.strip!
|
24
|
-
stored_otelcol_pid = File.read(collector_pid_location)
|
25
|
-
expect(otelcol_pid).to eq(stored_otelcol_pid)
|
26
|
-
|
27
|
-
`kill -9 #{monitor_pid}`
|
28
|
-
|
29
|
-
# Create a separate monitor manager instance, or else we won't reload
|
30
|
-
# the configuraiton state.
|
31
|
-
ScoutApm::Logging::MonitorManager.new.setup!
|
32
|
-
|
33
|
-
sleep 5
|
34
|
-
|
35
|
-
expect(`pgrep -f /app/bin/scout_apm_logging_monitor --runstates D,R,S`).not_to be_empty
|
36
|
-
|
37
|
-
new_monitor_pid = File.read(monitor_pid_location)
|
38
|
-
expect(new_monitor_pid).not_to eq(monitor_pid)
|
39
|
-
|
40
|
-
should_be_same_otelcol_pid = `pgrep otelcol-contrib --runstates D,R,S`.strip!
|
41
|
-
should_be_same_stored_otelcol_pid = File.read(collector_pid_location)
|
42
|
-
expect(should_be_same_otelcol_pid).to eq(otelcol_pid)
|
43
|
-
expect(should_be_same_stored_otelcol_pid).to eq(stored_otelcol_pid)
|
44
|
-
end
|
45
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require_relative '../../../lib/scout_apm/logging/monitor/collector/manager'
|
4
|
-
|
5
|
-
describe ScoutApm::Logging::Collector::Manager do
|
6
|
-
it 'If monitor is false, it should remove the daemon and collector process if they are present' do
|
7
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
8
|
-
ENV['SCOUT_LOGS_MONITORED'] = '["/tmp/test.log"]'
|
9
|
-
|
10
|
-
expect(`pgrep otelcol-contrib --runstates D,R,S`).to be_empty
|
11
|
-
|
12
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time start: #{Time.now}"
|
13
|
-
ScoutApm::Logging::MonitorManager.instance.setup!
|
14
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time after setup: #{Time.now}"
|
15
|
-
|
16
|
-
wait_for_process_with_timeout!('otelcol-contrib', 20)
|
17
|
-
|
18
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'false'
|
19
|
-
|
20
|
-
ScoutApm::Logging::MonitorManager.new.setup!
|
21
|
-
|
22
|
-
sleep 5 # Give the process time to exit
|
23
|
-
|
24
|
-
expect(File.exist?(ScoutApm::Logging::MonitorManager.instance.context.config.value('monitor_pid_file'))).to be_falsey
|
25
|
-
expect(`pgrep otelcol-contrib --runstates D,R,S`).to be_empty
|
26
|
-
expect(`pgrep scout_apm_log_monitor --runstates D,R,S`).to be_empty
|
27
|
-
|
28
|
-
ENV.delete('SCOUT_LOGS_MONITOR')
|
29
|
-
end
|
30
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require_relative '../../../lib/scout_apm/logging/monitor/collector/manager'
|
4
|
-
|
5
|
-
describe ScoutApm::Logging::Collector::Manager do
|
6
|
-
it 'should recreate the monitor process if monitor.pid file is errant' do
|
7
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
8
|
-
ENV['SCOUT_LOGS_MONITORED'] = '["/tmp/test.log"]'
|
9
|
-
|
10
|
-
ScoutApm::Logging::Utils.ensure_directory_exists('/tmp/scout_apm/scout_apm_log_monitor.pid')
|
11
|
-
|
12
|
-
# A high enough number to not be a PID of a running process
|
13
|
-
pid_file_path = '/tmp/scout_apm/scout_apm_log_monitor.pid'
|
14
|
-
File.open(pid_file_path, 'w') do |file|
|
15
|
-
file.write('123456')
|
16
|
-
end
|
17
|
-
|
18
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time start: #{Time.now}"
|
19
|
-
ScoutApm::Logging::MonitorManager.instance.setup!
|
20
|
-
ScoutApm::Logging::MonitorManager.instance.context.logger.info "Time after setup: #{Time.now}"
|
21
|
-
|
22
|
-
# Give the process time to initialize, download the collector, and start it
|
23
|
-
wait_for_process_with_timeout!('otelcol-contrib', 20)
|
24
|
-
|
25
|
-
new_pid = File.read(pid_file_path).to_i
|
26
|
-
|
27
|
-
expect(new_pid).not_to eq(12_345)
|
28
|
-
|
29
|
-
# Check if the process with the stored PID is running
|
30
|
-
expect(Process.kill(0, new_pid)).to be_truthy
|
31
|
-
ENV.delete('SCOUT_LOGS_MONITOR')
|
32
|
-
|
33
|
-
# Kill the process and ensure PID file clean up
|
34
|
-
Process.kill('TERM', new_pid)
|
35
|
-
Process.kill('TERM', `pgrep otelcol-contrib --runstates D,R,S`.to_i)
|
36
|
-
sleep 1 # Give the process time to exit
|
37
|
-
end
|
38
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# This is really meant to simulate multiple processes calling the MonitorManager setup.
|
2
|
-
# Trying to create **multiple fake** rails environments is a bit challening
|
3
|
-
# (such as a rails app and a couple rails runners).
|
4
|
-
|
5
|
-
# See: https://github.com/rails/rails/blob/6d126e03dbbf5d30fa97b580f7dee46343537b7b/railties/test/isolation/abstract_unit.rb#L339
|
6
|
-
|
7
|
-
# We simulate the ultimate outcome here -- ie Railtie invoking the setup.
|
8
|
-
require 'spec_helper'
|
9
|
-
|
10
|
-
describe ScoutApm::Logging do
|
11
|
-
it 'Should only create a single monitor daemon if manager is called multiple times' do
|
12
|
-
ENV['SCOUT_LOGS_MONITOR'] = 'true'
|
13
|
-
ENV['SCOUT_LOGS_MONITORED'] = '["/tmp/test.log"]'
|
14
|
-
|
15
|
-
pid_file = ScoutApm::Logging::MonitorManager.instance.context.config.value('monitor_pid_file')
|
16
|
-
expect(File.exist?(pid_file)).to be_falsey
|
17
|
-
|
18
|
-
context = ScoutApm::Logging::MonitorManager.instance.context
|
19
|
-
|
20
|
-
pids = 3.times.map do
|
21
|
-
fork do
|
22
|
-
puts 'fork attempting to gain lock'
|
23
|
-
ScoutApm::Logging::Utils.attempt_exclusive_lock(context) do
|
24
|
-
puts 'obtained lock'
|
25
|
-
ScoutApm::Logging::MonitorManager.new.setup!
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
pids.each { |pid| Process.wait(pid) }
|
31
|
-
|
32
|
-
wait_for_process_with_timeout!('otelcol-contrib', 20)
|
33
|
-
|
34
|
-
# The file lock really should be gone at this point.
|
35
|
-
expect(File.exist?(context.config.value('manager_lock_file'))).to be_falsey
|
36
|
-
expect(File.exist?(pid_file)).to be_truthy
|
37
|
-
|
38
|
-
original_pid = File.read(pid_file).to_i
|
39
|
-
expect(ScoutApm::Logging::Utils.check_process_liveliness(original_pid, 'scout_apm_logging_monitor')).to be_truthy
|
40
|
-
|
41
|
-
# Another process comes in and tries to start it again
|
42
|
-
ScoutApm::Logging::Utils.attempt_exclusive_lock(context) do
|
43
|
-
puts 'obtained lock later on'
|
44
|
-
ScoutApm::Logging::MonitorManager.new.setup!
|
45
|
-
end
|
46
|
-
|
47
|
-
expect(File.exist?(context.config.value('manager_lock_file'))).to be_falsey
|
48
|
-
expect(File.exist?(pid_file)).to be_truthy
|
49
|
-
updated_pid = File.read(pid_file).to_i
|
50
|
-
expect(updated_pid).to eq(original_pid)
|
51
|
-
expect(ScoutApm::Logging::Utils.check_process_liveliness(original_pid, 'scout_apm_logging_monitor')).to be_truthy
|
52
|
-
end
|
53
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
require_relative '../../../../lib/scout_apm/logging/monitor/collector/configuration'
|
6
|
-
|
7
|
-
describe ScoutApm::Logging::Collector::Configuration do
|
8
|
-
it 'creates the correct configuration for the otelcol' do
|
9
|
-
context = ScoutApm::Logging::Context.new
|
10
|
-
setup_collector_config!(context)
|
11
|
-
|
12
|
-
expect(File.exist?(context.config.value('collector_config_file'))).to be_truthy
|
13
|
-
config = YAML.load_file(context.config.value('collector_config_file'))
|
14
|
-
|
15
|
-
expect(config['exporters']['otlp']['endpoint']).to eq('https://otlp.scoutotel.com:4317')
|
16
|
-
expect(config['exporters']['otlp']['headers']['x-telemetryhub-key']).to eq('00001000010000abc')
|
17
|
-
expect(config['receivers']['filelog']['include']).to eq(['/tmp/fake_log_file.log'])
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'merges in a logs config correctly' do
|
21
|
-
ENV['SCOUT_LOGS_CONFIG'] = File.expand_path('../../../data/logs_config.yml', __dir__)
|
22
|
-
|
23
|
-
context = ScoutApm::Logging::Context.new
|
24
|
-
setup_collector_config!(context)
|
25
|
-
|
26
|
-
expect(File.exist?(context.config.value('collector_config_file'))).to be_truthy
|
27
|
-
config = YAML.load_file(context.config.value('collector_config_file'))
|
28
|
-
|
29
|
-
expect(config['exporters']['otlp']['endpoint']).to eq('https://otlp.scoutotel.com:4317')
|
30
|
-
expect(config['exporters']['otlp']['headers']['x-telemetryhub-key']).to eq('00001000010000abc')
|
31
|
-
expect(config['receivers']['filelog']['include']).to eq(['/tmp/fake_log_file.log'])
|
32
|
-
|
33
|
-
# Verify merge and consistent keys
|
34
|
-
expect(config['extensions']['file_storage/otc']['directory']).to eq('/dev/null')
|
35
|
-
expect(config['extensions']['file_storage/otc']['timeout']).to eq('10s')
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'handles an empty logs config file well' do
|
39
|
-
ENV['SCOUT_LOGS_CONFIG'] = File.expand_path('../../../data/empty_logs_config.yml', __dir__)
|
40
|
-
|
41
|
-
context = ScoutApm::Logging::Context.new
|
42
|
-
setup_collector_config!(context)
|
43
|
-
|
44
|
-
expect(File.exist?(context.config.value('collector_config_file'))).to be_truthy
|
45
|
-
config = YAML.load_file(context.config.value('collector_config_file'))
|
46
|
-
|
47
|
-
expect(config['exporters']['otlp']['endpoint']).to eq('https://otlp.scoutotel.com:4317')
|
48
|
-
expect(config['exporters']['otlp']['headers']['x-telemetryhub-key']).to eq('00001000010000abc')
|
49
|
-
expect(config['receivers']['filelog']['include']).to eq(['/tmp/fake_log_file.log'])
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def setup_collector_config!(context)
|
55
|
-
ENV['SCOUT_MONITOR_STATE_FILE'] = File.expand_path('../../../data/state_file.json', __dir__)
|
56
|
-
conf_file = File.expand_path('../../../data/mock_config.yml', __dir__)
|
57
|
-
context.config = ScoutApm::Logging::Config.with_file(context, conf_file)
|
58
|
-
|
59
|
-
ScoutApm::Logging::Utils.ensure_directory_exists(context.config.value('collector_config_file'))
|
60
|
-
|
61
|
-
collector_config = ScoutApm::Logging::Collector::Configuration.new(context)
|
62
|
-
collector_config.setup!
|
63
|
-
end
|
64
|
-
end
|
data/spec/unit/state_spec.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ScoutApm::Logging::Config do
|
4
|
-
it 'flushes and loads the state' do
|
5
|
-
context = ScoutApm::Logging::Context.new
|
6
|
-
conf_file = File.expand_path('../data/config_test_1.yml', __dir__)
|
7
|
-
conf = ScoutApm::Logging::Config.with_file(context, conf_file)
|
8
|
-
|
9
|
-
context.config = conf
|
10
|
-
|
11
|
-
ScoutApm::Logging::Config::ConfigDynamic.set_value('health_check_port', 1234)
|
12
|
-
|
13
|
-
context.config.state.flush_state!
|
14
|
-
|
15
|
-
data = ScoutApm::Logging::Config::State.new(context).load_state_from_file
|
16
|
-
|
17
|
-
expect(data['health_check_port']).to eq(context.config.value('health_check_port'))
|
18
|
-
expect(data['logs_monitored']).to eq(context.config.value('logs_monitored'))
|
19
|
-
end
|
20
|
-
end
|
data/tooling/checksums.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
###
|
2
|
-
# Calculates the checksums for the otelcol-contrib files
|
3
|
-
# Usage: ruby tooling/checksums.rb <version>
|
4
|
-
##
|
5
|
-
# frozen_string_literal: true
|
6
|
-
|
7
|
-
require 'digest'
|
8
|
-
require 'fileutils'
|
9
|
-
require 'net/http'
|
10
|
-
require 'pp'
|
11
|
-
|
12
|
-
DOUBLES = [
|
13
|
-
'darwin_amd64',
|
14
|
-
'darwin_arm64',
|
15
|
-
'linux_amd64',
|
16
|
-
'linux_arm64'
|
17
|
-
]
|
18
|
-
|
19
|
-
version = ARGV[0]
|
20
|
-
|
21
|
-
current_directory = Dir.pwd
|
22
|
-
unless current_directory.include?("/tooling")
|
23
|
-
tooling_directory = File.join(current_directory, "/tooling")
|
24
|
-
FileUtils.cd(tooling_directory)
|
25
|
-
end
|
26
|
-
|
27
|
-
def download_source_checksums(url, destination)
|
28
|
-
uri = URI(url)
|
29
|
-
|
30
|
-
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
31
|
-
request = Net::HTTP::Get.new(uri)
|
32
|
-
http.request(request) do |response|
|
33
|
-
return download_source_checksums(response['location'], destination) if response.code == '302'
|
34
|
-
|
35
|
-
File.open(destination, 'wb') do |file|
|
36
|
-
response.read_body do |chunk|
|
37
|
-
file.write(chunk)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def validate_and_return_checksums(version)
|
45
|
-
checksum_file_url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v#{version}/opentelemetry-collector-releases_otelcol-contrib_checksums.txt"
|
46
|
-
destination = "./opentelemetry-collector-releases_otelcol-contrib_checksums.txt"
|
47
|
-
|
48
|
-
download_source_checksums(checksum_file_url, destination)
|
49
|
-
|
50
|
-
contents = File.read(destination)
|
51
|
-
lines = contents.split("\n")
|
52
|
-
pairs = lines.each_with_object({}) do |item, hash|
|
53
|
-
value, key = item.split
|
54
|
-
hash[key] = value
|
55
|
-
end
|
56
|
-
|
57
|
-
|
58
|
-
relavent_pairs = {}
|
59
|
-
DOUBLES.each do |double|
|
60
|
-
file_name = "otelcol-contrib_#{version}_#{double}.tar.gz"
|
61
|
-
file_location = "./#{file_name}"
|
62
|
-
|
63
|
-
local_checksum = Digest::SHA256.file(file_location).hexdigest
|
64
|
-
source_checksum = pairs[file_name]
|
65
|
-
|
66
|
-
if source_checksum != local_checksum
|
67
|
-
puts "#{double} contains different checksums: Local checksum #{local_checksum} -- Source checksum #{source_checksum}"
|
68
|
-
raise "Different checksums for #{double}"
|
69
|
-
end
|
70
|
-
|
71
|
-
relavent_pairs[double] = local_checksum
|
72
|
-
end
|
73
|
-
|
74
|
-
relavent_pairs
|
75
|
-
end
|
76
|
-
|
77
|
-
def download_collector(url, destination)
|
78
|
-
uri = URI(url)
|
79
|
-
|
80
|
-
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
81
|
-
request = Net::HTTP::Get.new(uri)
|
82
|
-
http.request(request) do |response|
|
83
|
-
return download_collector(response['location'], destination) if response.code == '302'
|
84
|
-
|
85
|
-
File.open(destination, 'wb') do |file|
|
86
|
-
response.read_body do |chunk|
|
87
|
-
file.write(chunk)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
DOUBLES.each do |double|
|
95
|
-
host_os, architecture = double.split('_')
|
96
|
-
|
97
|
-
url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v#{version}/otelcol-contrib_#{version}_#{host_os}_#{architecture}.tar.gz"
|
98
|
-
|
99
|
-
destination = "./otelcol-contrib_#{version}_#{host_os}_#{architecture}.tar.gz"
|
100
|
-
|
101
|
-
download_collector(url, destination)
|
102
|
-
end
|
103
|
-
|
104
|
-
checksums = validate_and_return_checksums(version)
|
105
|
-
|
106
|
-
pp checksums
|