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.
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