55Bundler . require
66
77ENV [ "RAILS_ENV" ] = "development"
8+ ENV [ "DATABASE_URL" ] = "sqlite3::memory:"
89
9- require "action_controller"
10+ require "action_controller/railtie"
11+ require "active_record/railtie"
12+ require "active_job/railtie"
1013
1114class RailsMiniApp < Rails ::Application
1215 config . hosts = nil
@@ -17,6 +20,12 @@ class RailsMiniApp < Rails::Application
1720 config . api_only = true
1821 config . force_ssl = false
1922
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+
2029 initializer :configure_sentry do
2130 Sentry . init do |config |
2231 config . dsn = ENV [ "SENTRY_DSN" ]
@@ -30,12 +39,71 @@ class RailsMiniApp < Rails::Application
3039 config . release = "sentry-ruby-rails-mini-#{ Time . now . utc } "
3140
3241 config . transport . transport_class = Sentry ::DebugTransport
33- config . sdk_debug_transport_log_file = "/workspace/sentry/log/sentry_debug_events.log"
3442 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 ]
3549 end
3650 end
3751end
3852
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+
39107class ErrorController < ActionController ::Base
40108 before_action :set_cors_headers
41109
@@ -61,7 +129,8 @@ def health
61129 status : "ok" ,
62130 timestamp : Time . now . utc . iso8601 ,
63131 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
65134 }
66135 end
67136
@@ -80,6 +149,123 @@ def check_log_file_writable
80149 false
81150 end
82151
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+
83269 def set_cors_headers
84270 response . headers [ 'Access-Control-Allow-Origin' ] = '*'
85271 response . headers [ 'Access-Control-Allow-Methods' ] = 'GET, POST, PUT, DELETE, OPTIONS'
@@ -89,12 +275,41 @@ def set_cors_headers
89275
90276RailsMiniApp . initialize!
91277
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 : "test@example.com" )
296+ end
297+
298+ setup_database
299+
92300RailsMiniApp . routes . draw do
93301 get '/health' , to : 'events#health'
94302 get '/error' , to : 'error#error'
95303 get '/trace_headers' , to : 'events#trace_headers'
96304
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+
98313 match '*path' , to : proc { |env |
99314 [ 200 , {
100315 'Access-Control-Allow-Origin' => '*' ,
0 commit comments