contextualized_logs 0.0.1.pre.alpha

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 (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 %>