contextualized_logs 0.0.1.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +480 -0
  4. data/Rakefile +28 -0
  5. data/app/assets/config/manifest.js +3 -0
  6. data/app/assets/javascripts/application.js +16 -0
  7. data/app/assets/javascripts/cable.js +13 -0
  8. data/app/assets/stylesheets/application.css +15 -0
  9. data/app/channels/application_cable/channel.rb +4 -0
  10. data/app/channels/application_cable/connection.rb +4 -0
  11. data/app/controllers/application_controller.rb +2 -0
  12. data/app/controllers/model_controller.rb +26 -0
  13. data/app/helpers/application_helper.rb +2 -0
  14. data/app/jobs/application_job.rb +2 -0
  15. data/app/mailers/application_mailer.rb +4 -0
  16. data/app/models/application_record.rb +3 -0
  17. data/app/models/model.rb +4 -0
  18. data/app/views/layouts/application.html.erb +15 -0
  19. data/app/views/layouts/mailer.html.erb +13 -0
  20. data/app/views/layouts/mailer.text.erb +1 -0
  21. data/app/workers/model_worker.rb +13 -0
  22. data/config/application.rb +19 -0
  23. data/config/boot.rb +4 -0
  24. data/config/cable.yml +10 -0
  25. data/config/credentials.yml.enc +1 -0
  26. data/config/database.yml +25 -0
  27. data/config/environment.rb +5 -0
  28. data/config/environments/development.rb +62 -0
  29. data/config/environments/production.rb +94 -0
  30. data/config/environments/test.rb +47 -0
  31. data/config/initializers/application_controller_renderer.rb +8 -0
  32. data/config/initializers/assets.rb +14 -0
  33. data/config/initializers/backtrace_silencers.rb +7 -0
  34. data/config/initializers/content_security_policy.rb +25 -0
  35. data/config/initializers/cookies_serializer.rb +5 -0
  36. data/config/initializers/filter_parameter_logging.rb +4 -0
  37. data/config/initializers/inflections.rb +16 -0
  38. data/config/initializers/mime_types.rb +4 -0
  39. data/config/initializers/sidekiq.rb +23 -0
  40. data/config/initializers/wrap_parameters.rb +14 -0
  41. data/config/locales/en.yml +33 -0
  42. data/config/master.key +1 -0
  43. data/config/puma.rb +37 -0
  44. data/config/routes.rb +3 -0
  45. data/config/spring.rb +6 -0
  46. data/config/storage.yml +34 -0
  47. data/db/development.sqlite3 +0 -0
  48. data/db/migrate/20200424081113_create_model.rb +7 -0
  49. data/db/schema.rb +19 -0
  50. data/db/seeds.rb +7 -0
  51. data/db/test.sqlite3 +0 -0
  52. data/lib/contextualized_logs/contextualized_controller.rb +63 -0
  53. data/lib/contextualized_logs/contextualized_logger.rb +90 -0
  54. data/lib/contextualized_logs/contextualized_model.rb +54 -0
  55. data/lib/contextualized_logs/contextualized_worker.rb +41 -0
  56. data/lib/contextualized_logs/current_context.rb +99 -0
  57. data/lib/contextualized_logs/railtie.rb +9 -0
  58. data/lib/contextualized_logs/sidekiq/middleware/client/inject_current_context.rb +38 -0
  59. data/lib/contextualized_logs/sidekiq/middleware/server/restore_current_context.rb +43 -0
  60. data/lib/contextualized_logs/version.rb +3 -0
  61. data/lib/contextualized_logs.rb +11 -0
  62. data/lib/tasks/contextualized_logs_tasks.rake +4 -0
  63. metadata +123 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2999bdeabefea3e6d361b02314d3746a98f2205e2af9b1ca48abd66cbeb2338d
4
+ data.tar.gz: 6dd09536859433929a51c184571af703611c69d10beddf6e7ba78280905288a6
5
+ SHA512:
6
+ metadata.gz: 119a4ec8c01cf01261b122bcd9f0a8526e0c888ab25444ae0f20487e1528f282e8f58592c424a8b78f1b0fa198265be1168aa0304348ad185c26d10419d2ea98
7
+ data.tar.gz: bf2d43f375f0b1b1800b7febc9bcfcb76827ec4143a49487059d307e4dd2f5bf651f4434a6230007acdb4e0420aa29a5000e9e2f819e61fcf1fd63011a419341
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2020 Hugues Bernet-Rollande
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,480 @@
1
+ # ContextualizedLogs
2
+
3
+ Online logging solution (like [Datadog](https://www.datadoghq.com)) have drastically transform the way we log.
4
+
5
+ An app will nowdays logs dozen (hundred) of logs per requests.
6
+
7
+ The issue is often to correlate this logs, with the initiating request (or job) and add shared metadata on this logs.
8
+
9
+ Here come `ContextualizedLogs`.
10
+
11
+ The main idea is to enhance your logs from your controller (including `ContextualizedController`, which use a before action), which will add the params to your logs (and some metadata about the request itself, like `request.uuid`).
12
+
13
+ This metadata are stored in a `ActiveSupport::CurrentAttributes` which is a singleton (reset per request).
14
+
15
+ Each subsequent logs in this thread (request) will also be enriched with this metadata, making it easier to find all the logs associated with a request (`uuid`, `ip`, `params.xxx`).
16
+
17
+ On top of this, logs can also be enriched by the ActiveRecord model they use (`create` or `find`) (models including `ContextualizedModel`). So any time a contextualized model is created or find, some metadata related to the model (`id`, ...) will also be added to the logs.
18
+
19
+ Allowing you to find all logs which "touched" this models.
20
+
21
+ All logs are (by default in json format)
22
+
23
+ ```ruby
24
+ class MyController < ApplicationController
25
+ include ContextualizedLogs::ContextualizedController
26
+ end
27
+ ```
28
+
29
+ ```
30
+ curl --referer 'referer' --user-agent 'user_agent' -H "Origin: http://localhost" http://localhost/my_controller?param=a
31
+
32
+ # development.log
33
+ {
34
+ syslog: {
35
+ env: 'development',
36
+ host: 'localhost'
37
+ },
38
+ type: 'INFO',
39
+ time: '2020-04-24T19:52:51.452+02:00',
40
+ log_type: 'log',
41
+ resource_name: 'mycontroller_show',
42
+ http: {
43
+ referer: 'referer',
44
+ request_id: 'xxxx-xxxx-xxxx-xxxx'
45
+ useragent: 'user_agent',
46
+ origin: 'http://localhost'
47
+ },
48
+ network: {
49
+ client: {
50
+ ip: '127.0.0.1',
51
+ remote_addr: '127.0.0.1',
52
+ remote_ip: '127.0.0.1',
53
+ x_forwarded_for: '127.0.0.1'
54
+ }
55
+ }
56
+ }
57
+ ```
58
+
59
+ ```ruby
60
+ class User < ActiveRecord::Base
61
+ include ContextualizedLogs::ContextualizedModel
62
+ contextualizable { user_ids: :id }
63
+ end
64
+
65
+ class UserController < ApplicationController
66
+ include ContextualizedLogs::ContextualizedController
67
+ contextualized_model true
68
+
69
+ def show
70
+ User.find(params[:id])
71
+ end
72
+ end
73
+ ```
74
+
75
+ ```
76
+ curl http://localhost/users/1
77
+
78
+ # development.log
79
+ {
80
+ syslog: {
81
+ env: 'development',
82
+ host: 'localhost'
83
+ },
84
+ type: 'INFO',
85
+ time: '2020-04-24T19:52:51.452+02:00',
86
+ log_type: 'log',
87
+ context_values: {
88
+ user_ids: [1]
89
+ },
90
+ resource_name: 'mycontroller_show',
91
+ http: {
92
+ request_id: 'xxxx-xxxx-xxxx-xxxx'
93
+ },
94
+ network: {
95
+ client: {
96
+ ip: '127.0.0.1',
97
+ remote_addr: '127.0.0.1',
98
+ remote_ip: '127.0.0.1',
99
+ x_forwarded_for: '127.0.0.1'
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ ```ruby
106
+ class User < ActiveRecord::Base
107
+ include ContextualizedLogs::ContextualizedModel
108
+ contextualizable { user_ids: :id }
109
+ end
110
+
111
+ class UserTracker < ActiveRecord::Base
112
+ include ContextualizedLogs::ContextualizedModel
113
+
114
+ belongs_to :user
115
+
116
+ contextualizable { user_tracker_ids: :id }
117
+ end
118
+
119
+ class UserController < ApplicationController
120
+ include ContextualizedLogs::ContextualizedController
121
+ contextualized_model true
122
+
123
+ def show
124
+ user_id = params[:id]
125
+ User.find(user_id)
126
+ UserTrackerWorker.perform_async(user_id, 'show')
127
+ end
128
+ end
129
+
130
+ class UserTrackerWorker
131
+ include Sidekiq::Worker
132
+ include ContextualizedLogs::ContextualizedWorker
133
+ contextualized_worker true
134
+ contextualized_model true
135
+ def self.contextualize_args(args)
136
+ { user_id: args.first, action: args.last }
137
+ end
138
+
139
+ def perform(user_id, action)
140
+ UserTracker.create(user_id: user_id, action: action)
141
+ end
142
+ end
143
+ ```
144
+
145
+ ```
146
+ curl http://localhost/users/1
147
+
148
+ # development.log
149
+ {
150
+ syslog: {
151
+ env: 'development',
152
+ host: 'localhost'
153
+ },
154
+ type: 'INFO',
155
+ time: '2020-04-24T19:52:51.452+02:00',
156
+ log_type: 'log',
157
+ context_values: {
158
+ user_ids: [1]
159
+ },
160
+ enqueued_jobs_ids: ['1234-xxxx-xxxx-xxxx']
161
+ resource_name: 'mycontroller_show',
162
+ http: {
163
+ request_id: 'xxxx-xxxx-xxxx-xxxx'
164
+ },
165
+ network: {
166
+ client: {
167
+ ip: '127.0.0.1',
168
+ remote_addr: '127.0.0.1',
169
+ remote_ip: '127.0.0.1',
170
+ x_forwarded_for: '127.0.0.1'
171
+ }
172
+ }
173
+ }
174
+ {
175
+ syslog: {
176
+ env: 'development',
177
+ host: 'localhost'
178
+ },
179
+ type: 'INFO',
180
+ time: '2020-04-24T19:52:51.452+02:00',
181
+ log_type: 'log',
182
+ message: 'sidekiq: completing job UserWorker: 1234-xxxx-xxxx-xxxx, on queue default',
183
+ job: {
184
+ worker: 'UserWorker',
185
+ id: '1234-xxxx-xxxx-xxxx',
186
+ args: {
187
+ user_id: 1,
188
+ action: 'show'
189
+ }
190
+ }
191
+ context_values: {
192
+ user_ids: [1],
193
+ user_tracker_ids: [1]
194
+ },
195
+ enqueued_jobs_ids: ['xxxx-xxxx-xxxx-xxxx']
196
+ resource_name: 'mycontroller_show',
197
+ http: {
198
+ request_id: 'xxxx-xxxx-xxxx-xxxx'
199
+ },
200
+ network: {
201
+ client: {
202
+ ip: '127.0.0.1',
203
+ remote_addr: '127.0.0.1',
204
+ remote_ip: '127.0.0.1',
205
+ x_forwarded_for: '127.0.0.1'
206
+ }
207
+ }
208
+ }
209
+ {
210
+ syslog: {
211
+ env: 'development',
212
+ host: 'localhost'
213
+ },
214
+ type: 'INFO',
215
+ time: '2020-04-24T19:52:51.452+02:00',
216
+ log_type: 'log',
217
+ message: 'sidekiq: completing job UserWorker: 1234-xxxx-xxxx-xxxx, on queue default',
218
+ job: {
219
+ worker: 'UserWorker',
220
+ id: '1234-xxxx-xxxx-xxxx',
221
+ args: {
222
+ user_id: 1,
223
+ action: 'show'
224
+ }
225
+ }
226
+ context_values: {
227
+ user_ids: [1],
228
+ user_tracker_ids: [1]
229
+ },
230
+ enqueued_jobs_ids: ['xxxx-xxxx-xxxx-xxxx']
231
+ resource_name: 'mycontroller_show',
232
+ http: {
233
+ request_id: 'xxxx-xxxx-xxxx-xxxx'
234
+ },
235
+ network: {
236
+ client: {
237
+ ip: '127.0.0.1',
238
+ remote_addr: '127.0.0.1',
239
+ remote_ip: '127.0.0.1',
240
+ x_forwarded_for: '127.0.0.1'
241
+ }
242
+ }
243
+ }
244
+ ```
245
+
246
+ ## Demo
247
+
248
+ ### start rails
249
+ ```
250
+ bin/setup
251
+ bin/rails server
252
+ ```
253
+
254
+ ### start sidekiq
255
+ ```
256
+ bundle exec sidekiq
257
+ ```
258
+
259
+ ### tail logs
260
+ ```
261
+ tail -f log/development
262
+ ```
263
+
264
+ ### do some requests
265
+ ```
266
+ curl -X POST -d '{"value": "value"}' -H 'Content-Type: application/json' "http://localhost:3000/model"
267
+ curl "http://localhost:3000/model/1"
268
+ curl "http://localhost:3000/model"
269
+ curl -X DELETE "http://localhost:3000/model/1"
270
+ ```
271
+
272
+ ## Usage
273
+
274
+ ### ContextualizedLogger
275
+
276
+ In order to enrich your logs, you needs to use (subclass of `ActiveSupport::Logger`) `ContextualizedLogger`
277
+
278
+ > ContextualizedLogger logs by default some request metadata following Datadog naming convention
279
+ > https://docs.hq.com/logs/processing/attributes_naming_convention/#source-code
280
+
281
+ ```
282
+ Rails.application.configure do
283
+ config.logger = ContextualizedLogs::ContextualizedLogger.new("log/#{Rails.env}.log")
284
+ end
285
+ ````
286
+
287
+ ### ContextualizedController
288
+
289
+ ```
290
+ class Controller < ApplicationController
291
+ include ContextualizedLogs::ContextualizedController
292
+ end
293
+ ```
294
+
295
+ **All** (from the controller or any service, model, ... it used) this controller logs will now be enriched with some controller related metadata.
296
+
297
+ ### ContextualizedModel
298
+
299
+ ```
300
+ class Model < ActiveRecord::Base
301
+ include ContextualizedLogs::ContextualizedModel
302
+
303
+ # cherry picking which model value/column should be added to CurrentContext metadata
304
+ contextualizable keys: {model_ids: :id}
305
+ end
306
+ ```
307
+
308
+ If `ContextualizedLogs::CurrentContext.contextualized_model_enabled` is enable on the current tread, any Model which is created or find will add `{ context_values: { model_ids: ids } }`.
309
+ So if you fetch model (`id == 1`), and create model (`id == 2`), your logs will now contain `{ context_values: { model_ids: [1, 2] } }`.
310
+
311
+ ### ContextualizedWorker
312
+
313
+ ```
314
+ class Worker
315
+ include ContextualizedLogs::ContextualizedWorker
316
+ contextualized_worker true # enable logging of job enqueuing, performing, completing and failure
317
+ contextualized_model true # enable logging of any (contextualized) model found or created while performing job
318
+
319
+ # enable adding jobs args (cherry picked) to log metadata (CurrentContext) to be logged alongs any job logs
320
+ def self.contextualize_args(args)
321
+ { first: args.first }
322
+ end
323
+ end
324
+ ```
325
+
326
+ If `ContextualizedLogs::CurrentContext.contextualized_model_enabled` is enable on the current tread, any Model which is created or find will add `{ context_values: { model_ids: ids } }`.
327
+ So if you fetch model (`id == 1`), and create model (`id == 2`), your logs will now contain `{ context_values: { model_ids: [1, 2] } }`.
328
+
329
+ #### Metadata Customization
330
+
331
+ If you wish to logs different predefined metadata (`request.uuid`, `request.ip`, ...)
332
+
333
+ ## Installation
334
+
335
+ Add this line to your application's Gemfile:
336
+
337
+ ```ruby
338
+ gem 'contextualized_logs'
339
+ ```
340
+
341
+ And then execute:
342
+
343
+ $ bundle install
344
+
345
+
346
+ ## Roadmap
347
+
348
+ - [x] contextualized logger
349
+ - [x] contextualized controller
350
+ - [x] contextualized model
351
+ - [x] contextualized worker
352
+ - [ ] lograge
353
+
354
+ ## Specs
355
+
356
+ ```
357
+ $ rake
358
+ The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
359
+ /Users/hugues/.rvm/rubies/ruby-2.5.1/bin/ruby -I/Users/hugues/.rvm/gems/ruby-2.5.1/gems/rspec-core-3.8.2/lib:/Users/hugues/.rvm/gems/ruby-2.5.1/gems/rspec-support-3.8.3/lib /Users/hugues/.rvm/gems/ruby-2.5.1/gems/rspec-core-3.8.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
360
+
361
+ DummyController
362
+ should set request details
363
+ should NOT set enable model context values
364
+ should set resource_name
365
+ should set request details
366
+
367
+ ContextualizedModelDummyController
368
+ should set request details
369
+ should set enable model context values
370
+
371
+ ContextualizedLogs::ContextualizedLogger
372
+ format log
373
+ includes stack
374
+ format exception
375
+ inject context
376
+ dump
377
+ respect severity debug (default)
378
+ dump message
379
+ dump exception
380
+
381
+ ContextualizedLogs::ContextualizedModel
382
+ .contextualizable
383
+ set contextualizable keys
384
+ .contextualize
385
+ with contextualized_model_enabled == true
386
+ set contextualizable values
387
+ with contextualized_model_enabled == false
388
+ set contextualizable values
389
+ with CurrentContext.contextualized_model_enabled == true
390
+ behaves like after_create context
391
+ .after_create
392
+ set context
393
+ behaves like after_find context
394
+ .after_find
395
+ does
396
+ with CurrentContext.contextualized_model_enabled == false
397
+ behaves like after_create context
398
+ .after_create
399
+ set context
400
+ behaves like after_find context
401
+ .after_find
402
+ does
403
+
404
+ ContextualizedLogs::Sidekiq::Middleware::Client::InjectCurrentContext
405
+ ContextualizedWorker
406
+ with uncontextualized worker
407
+ DOES NOT change job context
408
+ DOES NOT log job enqueued
409
+ DOES NOT enable model context values
410
+ behaves like it client yield
411
+ should eq true
412
+ with contextualized worker
413
+ DOES change job context
414
+ DOES log job enqueued
415
+ behaves like it client yield
416
+ should eq true
417
+ with contextualized model
418
+ DOES enable model context values
419
+
420
+ ContextualizedLogs::Sidekiq::Middleware::Server::RestoreCurrentContext
421
+ with uncontextualized worker
422
+ DOES NOT log job
423
+ DOES NOT log job failure
424
+ behaves like it server yield
425
+ should eq true
426
+ behaves like enable model context values
427
+ enable model context values
428
+ with contextualized worker
429
+ behaves like it server yield
430
+ should eq true
431
+ behaves like log job failure
432
+ log job failure
433
+ behaves like log with context
434
+ log with context
435
+ behaves like enable model context values
436
+ enable model context values
437
+ with contextualized model worker
438
+ behaves like it server yield
439
+ should eq true
440
+ behaves like log job failure
441
+ log job failure
442
+ behaves like log with context
443
+ log with context
444
+ behaves like enable model context values
445
+ enable model context values
446
+ with contextualized model worker
447
+ log with args
448
+ behaves like it server yield
449
+ should eq true
450
+ behaves like log job failure
451
+ log job failure
452
+ behaves like log with context
453
+ log with context
454
+ behaves like enable model context values
455
+ enable model context values
456
+
457
+ ContextualizedLogs
458
+ has a version number
459
+
460
+ Finished in 0.73283 seconds (files took 1.34 seconds to load)
461
+ 46 examples, 0 failures
462
+ ```
463
+
464
+ ## Development
465
+
466
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
467
+
468
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
469
+
470
+ ## Contributing
471
+
472
+ Bug reports and pull requests are welcome on GitHub at https://github.com/huguesbr/contextualized_logs. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
473
+
474
+ ## License
475
+
476
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
477
+
478
+ ## Code of Conduct
479
+
480
+ Everyone interacting in the sidekiq_lockable_job project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/huguesbr/sidekiq_lockable_job/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'ContextualizedLogs'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ require 'bundler/gem_tasks'
18
+ require "rspec/core/rake_task"
19
+
20
+ # RSpec::Core::RakeTask.new(:spec)
21
+ #
22
+ task :default => :spec
23
+ # # Add your own tasks in files placed in lib/tasks ending in .rake,
24
+ # # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
25
+ #
26
+ require_relative 'config/application'
27
+ #
28
+ Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../javascripts .js
3
+ //= link_directory ../stylesheets .css
@@ -0,0 +1,16 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
5
+ // vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require rails-ujs
14
+ //= require activestorage
15
+ //= require turbolinks
16
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ // Action Cable provides the framework to deal with WebSockets in Rails.
2
+ // You can generate new channels where WebSocket features live using the `rails generate channel` command.
3
+ //
4
+ //= require action_cable
5
+ //= require_self
6
+ //= require_tree ./channels
7
+
8
+ (function() {
9
+ this.App || (this.App = {});
10
+
11
+ App.cable = ActionCable.createConsumer();
12
+
13
+ }).call(this);
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
6
+ * vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Connection < ActionCable::Connection::Base
3
+ end
4
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::API
2
+ end
@@ -0,0 +1,26 @@
1
+ class ModelController < ApplicationController
2
+ include ContextualizedLogs::ContextualizedController
3
+ contextualized_model true
4
+
5
+ def index
6
+ models = Model.all.map { |model| { id: model.id, value: model.value} }
7
+ render json: { models: models }, status: 200
8
+ end
9
+
10
+ def show
11
+ model = Model.find(params[:id])
12
+ ModelWorker.perform_async(model.id, 'show')
13
+ render json: { models: { id: model.id, value: model.value} }, status: 200
14
+ end
15
+
16
+ def destroy
17
+ Model.find(params[:id]).destroy!
18
+ render json: { success: 'true' }, status: 200
19
+ end
20
+
21
+ def create
22
+ model = Model.create(value: params[:value])
23
+ ModelWorker.perform_async(model.id, 'create')
24
+ render json: { models: { id: model.id, value: model.value} }, status: 201
25
+ end
26
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ end
@@ -0,0 +1,4 @@
1
+ class ApplicationMailer < ActionMailer::Base
2
+ default from: 'from@example.com'
3
+ layout 'mailer'
4
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -0,0 +1,4 @@
1
+ class Model < ActiveRecord::Base
2
+ include ContextualizedLogs::ContextualizedModel
3
+ contextualizable keys: { values: :value }
4
+ end
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Demo</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
9
+ <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
10
+ </head>
11
+
12
+ <body>
13
+ <%= yield %>
14
+ </body>
15
+ </html>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <style>
6
+ /* Email styles need to be inline */
7
+ </style>
8
+ </head>
9
+
10
+ <body>
11
+ <%= yield %>
12
+ </body>
13
+ </html>
@@ -0,0 +1 @@
1
+ <%= yield %>