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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -4
  3. data/.rubocop.yml +1 -1
  4. data/CHANGELOG.md +8 -0
  5. data/NOTICE +4 -0
  6. data/lib/scout_apm/logging/config.rb +5 -131
  7. data/lib/scout_apm/logging/loggers/capture.rb +8 -6
  8. data/lib/scout_apm/logging/loggers/formatter.rb +21 -2
  9. data/lib/scout_apm/logging/loggers/opentelemetry/LICENSE +201 -0
  10. data/lib/scout_apm/logging/loggers/opentelemetry/NOTICE +9 -0
  11. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/log_record.rb +18 -0
  12. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/logger.rb +64 -0
  13. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/logger_provider.rb +31 -0
  14. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/severity_number.rb +43 -0
  15. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs/version.rb +18 -0
  16. data/lib/scout_apm/logging/loggers/opentelemetry/api/logs.rb +28 -0
  17. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/exporter/otlp/logs_exporter.rb +389 -0
  18. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/exporter/otlp/version.rb +20 -0
  19. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/collector/logs/v1/logs_service_pb.rb +43 -0
  20. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/common/v1/common_pb.rb +58 -0
  21. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/logs/v1/logs_pb.rb +91 -0
  22. data/lib/scout_apm/logging/loggers/opentelemetry/exporter/proto/resource/v1/resource_pb.rb +33 -0
  23. data/lib/scout_apm/logging/loggers/opentelemetry/opentelemetry.rb +62 -0
  24. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/batch_log_record_processor.rb +225 -0
  25. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export/log_record_exporter.rb +64 -0
  26. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/export.rb +34 -0
  27. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record.rb +115 -0
  28. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_data.rb +31 -0
  29. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/log_record_processor.rb +53 -0
  30. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/logger.rb +94 -0
  31. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/logger_provider.rb +158 -0
  32. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs/version.rb +20 -0
  33. data/lib/scout_apm/logging/loggers/opentelemetry/sdk/logs.rb +28 -0
  34. data/lib/scout_apm/logging/loggers/patches/rails_logger.rb +17 -0
  35. data/lib/scout_apm/logging/loggers/proxy.rb +22 -5
  36. data/lib/scout_apm/logging/loggers/swaps/rails.rb +4 -12
  37. data/lib/scout_apm/logging/loggers/swaps/scout.rb +2 -10
  38. data/lib/scout_apm/logging/loggers/swaps/sidekiq.rb +2 -6
  39. data/lib/scout_apm/logging/utils.rb +0 -69
  40. data/lib/scout_apm/logging/version.rb +1 -1
  41. data/lib/scout_apm_logging.rb +3 -12
  42. data/scout_apm_logging.gemspec +7 -0
  43. data/spec/data/config_test_1.yml +0 -1
  44. data/spec/data/mock_config.yml +0 -3
  45. data/spec/integration/rails/lifecycle_spec.rb +57 -23
  46. data/spec/spec_helper.rb +0 -12
  47. data/spec/unit/config_spec.rb +0 -12
  48. data/spec/unit/loggers/capture_spec.rb +0 -6
  49. metadata +127 -39
  50. data/bin/scout_apm_logging_monitor +0 -6
  51. data/lib/scout_apm/logging/monitor/_rails.rb +0 -22
  52. data/lib/scout_apm/logging/monitor/collector/checksum.rb +0 -51
  53. data/lib/scout_apm/logging/monitor/collector/configuration.rb +0 -150
  54. data/lib/scout_apm/logging/monitor/collector/downloader.rb +0 -78
  55. data/lib/scout_apm/logging/monitor/collector/extractor.rb +0 -37
  56. data/lib/scout_apm/logging/monitor/collector/manager.rb +0 -57
  57. data/lib/scout_apm/logging/monitor/monitor.rb +0 -216
  58. data/lib/scout_apm/logging/monitor_manager/manager.rb +0 -162
  59. data/lib/scout_apm/logging/state.rb +0 -69
  60. data/spec/data/empty_logs_config.yml +0 -0
  61. data/spec/data/logs_config.yml +0 -3
  62. data/spec/data/state_file.json +0 -3
  63. data/spec/integration/loggers/capture_spec.rb +0 -68
  64. data/spec/integration/monitor/collector/downloader/will_verify_checksum.rb +0 -49
  65. data/spec/integration/monitor/collector_healthcheck_spec.rb +0 -29
  66. data/spec/integration/monitor/continuous_state_collector_spec.rb +0 -31
  67. data/spec/integration/monitor/previous_collector_setup_spec.rb +0 -45
  68. data/spec/integration/monitor_manager/disable_agent_spec.rb +0 -30
  69. data/spec/integration/monitor_manager/monitor_pid_file_spec.rb +0 -38
  70. data/spec/integration/monitor_manager/single_monitor_spec.rb +0 -53
  71. data/spec/unit/monitor/collector/configuration_spec.rb +0 -64
  72. data/spec/unit/state_spec.rb +0 -20
  73. 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::MonitorManager.instance.context
9
- pid_file = context.config.value('monitor_pid_file')
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
- wait_for_process_with_timeout!('otelcol-contrib', 20)
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
- messages = lines.map { |item| item['msg'] }
57
+ local_messages = lines.map { |item| item['msg'] }
45
58
 
46
- # Verify we have all the logs
47
- expect(messages.count('[TEST] Some log')).to eq(1)
48
- expect(messages.count('[YIELD] Yield Test')).to eq(1)
49
- expect(messages.count('Another Log')).to eq(1)
50
- expect(messages.count('Should not be captured')).to eq(0)
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
- # Kill the process and ensure PID file clean up
60
- Process.kill('TERM', pid)
61
- sleep 1 # Give the process time to exit
62
- expect(File.exist?(pid_file)).to be_falsey
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
@@ -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.12
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-08-28 00:00:00.000000000 Z
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,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative '../lib/scout_apm/logging/monitor/_rails.rb'
4
- require_relative "../lib/scout_apm/logging/monitor/monitor.rb"
5
-
6
- ScoutApm::Logging::Monitor.instance.setup!
@@ -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