5
5
Bundler . require
6
6
7
7
ENV [ "RAILS_ENV" ] = "development"
8
+ ENV [ "DATABASE_URL" ] = "sqlite3::memory:"
8
9
9
- require "action_controller"
10
+ require "action_controller/railtie"
11
+ require "active_record/railtie"
12
+ require "active_job/railtie"
10
13
11
14
class RailsMiniApp < Rails ::Application
12
15
config . hosts = nil
@@ -17,6 +20,12 @@ class RailsMiniApp < Rails::Application
17
20
config . api_only = true
18
21
config . force_ssl = false
19
22
23
+ config . active_record . logger = Logger . new ( $stdout)
24
+ config . active_record . migration_error = :page_load
25
+
26
+ config . active_job . queue_adapter = :inline
27
+ config . active_job . logger = Logger . new ( $stdout)
28
+
20
29
initializer :configure_sentry do
21
30
Sentry . init do |config |
22
31
config . dsn = ENV [ "SENTRY_DSN" ]
@@ -30,12 +39,71 @@ class RailsMiniApp < Rails::Application
30
39
config . release = "sentry-ruby-rails-mini-#{ Time . now . utc } "
31
40
32
41
config . transport . transport_class = Sentry ::DebugTransport
33
- config . sdk_debug_transport_log_file = "/workspace/sentry/log/sentry_debug_events.log"
34
42
config . background_worker_threads = 0
43
+
44
+ config . enable_logs = true
45
+ config . structured_logger_class = Sentry ::DebugStructuredLogger
46
+ config . sdk_debug_structured_logger_log_file = "/workspace/sentry/log/sentry_debug_logs.log"
47
+ config . rails . structured_logging . enabled = true
48
+ config . rails . structured_logging . attach_to = [ :active_record , :action_controller , :active_job ]
35
49
end
36
50
end
37
51
end
38
52
53
+ class Post < ActiveRecord ::Base
54
+ end
55
+
56
+ class User < ActiveRecord ::Base
57
+ end
58
+
59
+ class ApplicationJob < ActiveJob ::Base
60
+ retry_on ActiveRecord ::Deadlocked
61
+
62
+ discard_on ActiveJob ::DeserializationError
63
+ end
64
+
65
+ class SampleJob < ApplicationJob
66
+ queue_as :default
67
+
68
+ def perform ( message = "Hello from ActiveJob!" )
69
+ Rails . logger . info ( "SampleJob executed with message: #{ message } " )
70
+
71
+ Post . count
72
+ User . count
73
+
74
+ message
75
+ end
76
+ end
77
+
78
+ class DatabaseJob < ApplicationJob
79
+ queue_as :default
80
+
81
+ def perform ( post_title = "Test Post" )
82
+ Rails . logger . info ( "DatabaseJob creating post: #{ post_title } " )
83
+
84
+ post = Post . create! ( title : post_title , content : "Content for #{ post_title } " )
85
+ found_post = Post . find ( post . id )
86
+
87
+ Rails . logger . info ( "DatabaseJob found post: #{ found_post . title } " )
88
+
89
+ found_post
90
+ end
91
+ end
92
+
93
+ class FailingJob < ApplicationJob
94
+ queue_as :default
95
+
96
+ def perform ( should_fail = true )
97
+ Rails . logger . info ( "FailingJob started" )
98
+
99
+ if should_fail
100
+ raise StandardError , "Intentional job failure for testing"
101
+ end
102
+
103
+ "Job completed successfully"
104
+ end
105
+ end
106
+
39
107
class ErrorController < ActionController ::Base
40
108
before_action :set_cors_headers
41
109
@@ -61,7 +129,8 @@ def health
61
129
status : "ok" ,
62
130
timestamp : Time . now . utc . iso8601 ,
63
131
sentry_initialized : Sentry . initialized? ,
64
- log_file_writable : check_log_file_writable
132
+ log_file_writable : check_log_file_writable ,
133
+ structured_log_file_writable : check_structured_log_file_writable
65
134
}
66
135
end
67
136
@@ -80,6 +149,123 @@ def check_log_file_writable
80
149
false
81
150
end
82
151
152
+ def check_structured_log_file_writable
153
+ log_file_path = "/workspace/sentry/log/sentry_debug_logs.log"
154
+ File . writable? ( File . dirname ( log_file_path ) ) &&
155
+ ( !File . exist? ( log_file_path ) || File . writable? ( log_file_path ) )
156
+ rescue
157
+ false
158
+ end
159
+
160
+ def set_cors_headers
161
+ response . headers [ 'Access-Control-Allow-Origin' ] = '*'
162
+ response . headers [ 'Access-Control-Allow-Methods' ] = 'GET, POST, PUT, DELETE, OPTIONS'
163
+ response . headers [ 'Access-Control-Allow-Headers' ] = 'Content-Type, Authorization, sentry-trace, baggage'
164
+ end
165
+ end
166
+
167
+ class PostsController < ActionController ::Base
168
+ before_action :set_cors_headers
169
+ before_action :ensure_database_setup
170
+
171
+ def index
172
+ posts = Post . all . to_a
173
+
174
+ Sentry . logger . info ( "Posts index accessed" , posts_count : posts . length )
175
+
176
+ render json : {
177
+ posts : posts . map { |p | { id : p . id , title : p . title , content : p . content } }
178
+ }
179
+ end
180
+
181
+ def create
182
+ post = Post . create! ( post_params )
183
+
184
+ Sentry . logger . info ( "Post created" , post_id : post . id , title : post . title )
185
+
186
+ render json : { post : { id : post . id , title : post . title , content : post . content } } , status : :created
187
+ rescue ActiveRecord ::RecordInvalid => e
188
+ render json : { error : e . message } , status : :unprocessable_entity
189
+ end
190
+
191
+ def show
192
+ post = Post . find ( params [ :id ] )
193
+ render json : { post : { id : post . id , title : post . title , content : post . content } }
194
+ rescue ActiveRecord ::RecordNotFound
195
+ render json : { error : "Post not found" } , status : :not_found
196
+ end
197
+
198
+ private
199
+
200
+ def post_params
201
+ params . require ( :post ) . permit ( :title , :content )
202
+ end
203
+
204
+ def ensure_database_setup
205
+ unless ActiveRecord ::Base . connection . table_exists? ( 'posts' )
206
+ setup_database
207
+ end
208
+ end
209
+
210
+ def set_cors_headers
211
+ response . headers [ 'Access-Control-Allow-Origin' ] = '*'
212
+ response . headers [ 'Access-Control-Allow-Methods' ] = 'GET, POST, PUT, DELETE, OPTIONS'
213
+ response . headers [ 'Access-Control-Allow-Headers' ] = 'Content-Type, Authorization, sentry-trace, baggage'
214
+ end
215
+ end
216
+
217
+ class JobsController < ActionController ::Base
218
+ before_action :set_cors_headers
219
+ before_action :ensure_database_setup
220
+
221
+ def sample_job
222
+ job = SampleJob . perform_later ( "Hello from Rails mini app!" )
223
+
224
+ Sentry . logger . info ( "SampleJob enqueued" , job_id : job . job_id )
225
+
226
+ render json : {
227
+ message : "SampleJob enqueued successfully" ,
228
+ job_id : job . job_id ,
229
+ job_class : job . class . name
230
+ }
231
+ end
232
+
233
+ def database_job
234
+ title = params [ :title ] || "Test Post from Job"
235
+ job = DatabaseJob . perform_later ( title )
236
+
237
+ Sentry . logger . info ( "DatabaseJob enqueued" , job_id : job . job_id , post_title : title )
238
+
239
+ render json : {
240
+ message : "DatabaseJob enqueued successfully" ,
241
+ job_id : job . job_id ,
242
+ job_class : job . class . name ,
243
+ post_title : title
244
+ }
245
+ end
246
+
247
+ def failing_job
248
+ should_fail = params [ :should_fail ] != "false"
249
+ job = FailingJob . perform_later ( should_fail )
250
+
251
+ Sentry . logger . info ( "FailingJob enqueued" , job_id : job . job_id , should_fail : should_fail )
252
+
253
+ render json : {
254
+ message : "FailingJob enqueued successfully" ,
255
+ job_id : job . job_id ,
256
+ job_class : job . class . name ,
257
+ should_fail : should_fail
258
+ }
259
+ end
260
+
261
+ private
262
+
263
+ def ensure_database_setup
264
+ unless ActiveRecord ::Base . connection . table_exists? ( 'posts' )
265
+ setup_database
266
+ end
267
+ end
268
+
83
269
def set_cors_headers
84
270
response . headers [ 'Access-Control-Allow-Origin' ] = '*'
85
271
response . headers [ 'Access-Control-Allow-Methods' ] = 'GET, POST, PUT, DELETE, OPTIONS'
@@ -89,12 +275,41 @@ def set_cors_headers
89
275
90
276
RailsMiniApp . initialize!
91
277
278
+ def setup_database
279
+ ActiveRecord ::Schema . define do
280
+ create_table :posts , force : true do |t |
281
+ t . string :title , null : false
282
+ t . text :content
283
+ t . timestamps
284
+ end
285
+
286
+ create_table :users , force : true do |t |
287
+ t . string :name , null : false
288
+ t . string :email
289
+ t . timestamps
290
+ end
291
+ end
292
+
293
+ Post . create! ( title : "Welcome Post" , content : "Welcome to the Rails mini app!" )
294
+ Post . create! ( title : "Sample Post" , content : "This is a sample post for testing." )
295
+ User . create! ( name :
"Test User" , email :
"[email protected] " )
296
+ end
297
+
298
+ setup_database
299
+
92
300
RailsMiniApp . routes . draw do
93
301
get '/health' , to : 'events#health'
94
302
get '/error' , to : 'error#error'
95
303
get '/trace_headers' , to : 'events#trace_headers'
96
304
97
- # Add CORS headers for cross-origin requests from JS app
305
+ get '/posts' , to : 'posts#index'
306
+ post '/posts' , to : 'posts#create'
307
+ get '/posts/:id' , to : 'posts#show'
308
+
309
+ post '/jobs/sample' , to : 'jobs#sample_job'
310
+ post '/jobs/database' , to : 'jobs#database_job'
311
+ post '/jobs/failing' , to : 'jobs#failing_job'
312
+
98
313
match '*path' , to : proc { |env |
99
314
[ 200 , {
100
315
'Access-Control-Allow-Origin' => '*' ,
0 commit comments