superlogger 0.0.1

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 (122) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +82 -0
  4. data/Rakefile +34 -0
  5. data/lib/superlogger.rb +54 -0
  6. data/lib/superlogger/action_controller_log_subscriber.rb +35 -0
  7. data/lib/superlogger/action_dispatch_debug_exceptions.rb +11 -0
  8. data/lib/superlogger/action_view_log_subscriber.rb +13 -0
  9. data/lib/superlogger/active_record_log_subscriber.rb +29 -0
  10. data/lib/superlogger/logger.rb +79 -0
  11. data/lib/superlogger/middleware.rb +31 -0
  12. data/lib/superlogger/rails_rack_logger.rb +11 -0
  13. data/lib/superlogger/railtie.rb +7 -0
  14. data/lib/superlogger/version.rb +3 -0
  15. data/test/dummy/README.rdoc +28 -0
  16. data/test/dummy/Rakefile +6 -0
  17. data/test/dummy/app/assets/javascripts/application.js +13 -0
  18. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  19. data/test/dummy/app/controllers/application_controller.rb +5 -0
  20. data/test/dummy/app/controllers/home_controller.rb +5 -0
  21. data/test/dummy/app/models/something.rb +2 -0
  22. data/test/dummy/app/views/home/_partial.html.erb +0 -0
  23. data/test/dummy/app/views/home/index.html.erb +3 -0
  24. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  25. data/test/dummy/bin/bundle +3 -0
  26. data/test/dummy/bin/rails +4 -0
  27. data/test/dummy/bin/rake +4 -0
  28. data/test/dummy/bin/setup +29 -0
  29. data/test/dummy/config.ru +4 -0
  30. data/test/dummy/config/application.rb +25 -0
  31. data/test/dummy/config/boot.rb +5 -0
  32. data/test/dummy/config/database.yml +25 -0
  33. data/test/dummy/config/environment.rb +5 -0
  34. data/test/dummy/config/environments/development.rb +41 -0
  35. data/test/dummy/config/environments/production.rb +79 -0
  36. data/test/dummy/config/environments/test.rb +42 -0
  37. data/test/dummy/config/initializers/assets.rb +11 -0
  38. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  39. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  40. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  41. data/test/dummy/config/initializers/inflections.rb +16 -0
  42. data/test/dummy/config/initializers/mime_types.rb +4 -0
  43. data/test/dummy/config/initializers/session_store.rb +3 -0
  44. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  45. data/test/dummy/config/locales/en.yml +23 -0
  46. data/test/dummy/config/routes.rb +3 -0
  47. data/test/dummy/config/secrets.yml +22 -0
  48. data/test/dummy/db/development.sqlite3 +0 -0
  49. data/test/dummy/db/migrate/20160120090718_create_somethings.rb +10 -0
  50. data/test/dummy/db/schema.rb +23 -0
  51. data/test/dummy/db/test.sqlite3 +0 -0
  52. data/test/dummy/log/development.log +294 -0
  53. data/test/dummy/log/test.log +1672 -0
  54. data/test/dummy/public/404.html +67 -0
  55. data/test/dummy/public/422.html +67 -0
  56. data/test/dummy/public/500.html +66 -0
  57. data/test/dummy/public/favicon.ico +0 -0
  58. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5L/5Lly_CA8DZvPhQV2jDQx-Y6P_y3Ygra9t5jfSlGhHDA.cache +0 -0
  59. data/test/dummy/tmp/cache/assets/sprockets/v3.0/7J/7JXLU3kClrFYffhxcnNaLGjYz8LFI700NBjNiBOifaU.cache +0 -0
  60. data/test/dummy/tmp/cache/assets/sprockets/v3.0/C_/C_C8IqUQirTZx1bt5Ewm3QJvhVbwm66pxvcH0maphFY.cache +0 -0
  61. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ch/Ch2bQFHkYziI9Erdkuj8uoPJyw0W2aA5prtYAqlccww.cache +1 -0
  62. data/test/dummy/tmp/cache/assets/sprockets/v3.0/DS/DSOLSc6A5RVSmvM415eEWAWG_AgOvZcLZOXQjsXyWQA.cache +2 -0
  63. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Gy/Gyqn3Ja6WbUSqKnvWm9Xw7FIxFqJIPQ88IlgpguMo1s.cache +1 -0
  64. data/test/dummy/tmp/cache/assets/sprockets/v3.0/H3/H3tvaQM-yTy-25oSLlfjToAa74LSJHBDUpji-8C-eLg.cache +0 -0
  65. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Iv/IvDM1j8-H1H6kEjVCsyIW8N2zla-aIp9q_OE9PVZtVw.cache +1 -0
  66. data/test/dummy/tmp/cache/assets/sprockets/v3.0/K9/K9ZheMi0hi4DNLzmDMRnv9A_lOVz33kNImc16Now42o.cache +1 -0
  67. data/test/dummy/tmp/cache/assets/sprockets/v3.0/LH/LHgjtAV8kdldaJ_dX0RCznzjmWYRuLdhU29fZCJ0VmU.cache +1 -0
  68. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Nn/NnUCa7jNYx9HCmEB7E7WPWT00DwaM4IYICy1Ju1jjcs.cache +1 -0
  69. data/test/dummy/tmp/cache/assets/sprockets/v3.0/OI/OI6uxGcnsKavdWTtwDAasU3wPx8QXhzBgV0X2n1KjMQ.cache +0 -0
  70. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ol/OlBX9JIv9SAOmK2t35x1SYDx1sxCXF0yvqpna3WMyH0.cache +1 -0
  71. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Yr/YrZ0OIHu42cExs1kqngMA6ShVDKhfGmhyW-E9haNo5Y.cache +1 -0
  72. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZU/ZUokoeZcfmoTFE9YAHZRhTgceOUGJTDGH__SCqPfkqU.cache +0 -0
  73. data/test/dummy/tmp/cache/assets/sprockets/v3.0/_I/_IocgQl8XVm84HohovEBj-GxsSeBkOpqN-94yHgY-K8.cache +0 -0
  74. data/test/dummy/tmp/cache/assets/sprockets/v3.0/bJ/bJVgCoQDvMv4iocjEuC3z3WqSeK7LXgxDJ-eXaHl0l4.cache +0 -0
  75. data/test/dummy/tmp/cache/assets/sprockets/v3.0/b_/b_-O1DwVvDk3vPJ-GHDgGWR9Zth9CYblcXbBe6aiTf0.cache +0 -0
  76. data/test/dummy/tmp/cache/assets/sprockets/v3.0/br/brSVWTme0G1yzUMjrDpklxoQetdFLXdF8ZUkYXFX-sE.cache +1 -0
  77. data/test/dummy/tmp/cache/assets/sprockets/v3.0/cI/cIaWfk6Nq6ZAr0fhtHGTBtsRITI5n8IJFZbClZ2tExw.cache +0 -0
  78. data/test/dummy/tmp/cache/assets/sprockets/v3.0/g3/g3x0V2jnf5A31QMz4xGeQMouu2eChQRpoe0BEWWESeY.cache +1 -0
  79. data/test/dummy/tmp/cache/assets/sprockets/v3.0/gV/gVVPZef0xfm7t9Jyesa7ZVdnpzMpw2QtOyYUoEXO7fk.cache +0 -0
  80. data/test/dummy/tmp/cache/assets/sprockets/v3.0/gZ/gZp3uXMHuYQC4hzCr7bQfetKNdJAtbQmg3so2KpW1Dw.cache +2 -0
  81. data/test/dummy/tmp/cache/assets/sprockets/v3.0/gp/gpiWtnqpufka8lRtMznM6Ko0aWJrcH_j8cfZwdYmzNI.cache +1 -0
  82. data/test/dummy/tmp/cache/assets/sprockets/v3.0/hZ/hZi1k6tpxxCGYxRe7zY74ItcOI8gZrREOpGuA8JSpGg.cache +0 -0
  83. data/test/dummy/tmp/cache/assets/sprockets/v3.0/i7/i7v4b6OSQUj-1r9vUWRiOHjAVksSTpUfilZTpk0ACLc.cache +0 -0
  84. data/test/dummy/tmp/cache/assets/sprockets/v3.0/kz/kzdSvu57G4i6eTuarsZCAfbhbICnkRa0Xhi0b9ua6qk.cache +1 -0
  85. data/test/dummy/tmp/cache/assets/sprockets/v3.0/pE/pEhaat2KBd5SrT7szC_8R1_6hK17FTpvoRFkmCRSD3M.cache +0 -0
  86. data/test/dummy/tmp/cache/assets/sprockets/v3.0/rC/rCO5-bHVJ6Y_GsPBmOPUL23pfjvc2Gw2zt_ODmZsygw.cache +1 -0
  87. data/test/dummy/tmp/cache/assets/sprockets/v3.0/rg/rghMLGUpm1Uy3OPgfILHnVwLCycV9Rd9kSpEbxdwVV4.cache +0 -0
  88. data/test/dummy/tmp/cache/assets/sprockets/v3.0/vm/vm9zMjZUFULeJsYWRoDd3cvnEpLGK-E5XTk30_NQTEs.cache +0 -0
  89. data/test/dummy/tmp/cache/assets/sprockets/v3.0/wD/wDDl7jzOUTDgFcG1JlpN6jVHavfzB8Smsjtl3d8WDx0.cache +1 -0
  90. data/test/dummy/tmp/cache/sprockets/v3.0/-Z_pj4kfRj993e_ypawYQUIDIDKcRe569udVq_1drFs.cache +1 -0
  91. data/test/dummy/tmp/cache/sprockets/v3.0/2G0Z7Q5fvf2xX8ygtwcD9vZq-kwEzoV2MFc1URegs7s.cache +1 -0
  92. data/test/dummy/tmp/cache/sprockets/v3.0/5Lly_CA8DZvPhQV2jDQx-Y6P_y3Ygra9t5jfSlGhHDA.cache +2 -0
  93. data/test/dummy/tmp/cache/sprockets/v3.0/66bWF3byFzdKpXZsrn5Vy9CJBaDlkJKkoyqeLRRbBZY.cache +0 -0
  94. data/test/dummy/tmp/cache/sprockets/v3.0/9NtfUddiu2UU8sqL-bYq-NPAx8NGp5m5AYiAWAcKQQ4.cache +0 -0
  95. data/test/dummy/tmp/cache/sprockets/v3.0/DSOLSc6A5RVSmvM415eEWAWG_AgOvZcLZOXQjsXyWQA.cache +2 -0
  96. data/test/dummy/tmp/cache/sprockets/v3.0/GELqHyWyVR_UvkpZPDb5xjZrCgkKB5G067DYoMwTjEA.cache +0 -0
  97. data/test/dummy/tmp/cache/sprockets/v3.0/Gyqn3Ja6WbUSqKnvWm9Xw7FIxFqJIPQ88IlgpguMo1s.cache +1 -0
  98. data/test/dummy/tmp/cache/sprockets/v3.0/H5fHMceViwaxMKkefsdMmVpBN3rRYZI1obJX5Jn-4jw.cache +1 -0
  99. data/test/dummy/tmp/cache/sprockets/v3.0/IEJfj4Zwfra6y7iF-BOVR9PPIQeL9L5IiZT8MRqpCXg.cache +0 -0
  100. data/test/dummy/tmp/cache/sprockets/v3.0/IordxSS9mOh1mkt2VyfX7Iz4DhZhy73lccOYxcw5aVU.cache +1 -0
  101. data/test/dummy/tmp/cache/sprockets/v3.0/KgQHhqXCaYHJSJEG6JweQVe1a2rC-mHfkrqD9p9taTU.cache +2 -0
  102. data/test/dummy/tmp/cache/sprockets/v3.0/Ki_R5uSCGEm1Jn7TSbJOc3eBMn4Q3_IPLG0r_RRn9lA.cache +1 -0
  103. data/test/dummy/tmp/cache/sprockets/v3.0/NBBjlBjfPdkZkp4G7VCEA9LAeGycMn10CxLbDAbNeHc.cache +0 -0
  104. data/test/dummy/tmp/cache/sprockets/v3.0/OI6uxGcnsKavdWTtwDAasU3wPx8QXhzBgV0X2n1KjMQ.cache +2 -0
  105. data/test/dummy/tmp/cache/sprockets/v3.0/V9m2At1eKJAvbGAFvFTUt8hcdNI-G8xW1AShyPYS4Ys.cache +1 -0
  106. data/test/dummy/tmp/cache/sprockets/v3.0/XsDQ8X8Klh__7HZNZk8sjYzyFg5TmATqo-_UraArzN8.cache +1 -0
  107. data/test/dummy/tmp/cache/sprockets/v3.0/ZtbyFLml01tdqcRh4Ocz6XOkbPpmHM6nFRRYY4Nphpc.cache +1 -0
  108. data/test/dummy/tmp/cache/sprockets/v3.0/_ZNMI9IrCfXNcrwiRGttWiFPcLlCSpkdJSFoLhmUpyg.cache +0 -0
  109. data/test/dummy/tmp/cache/sprockets/v3.0/brSVWTme0G1yzUMjrDpklxoQetdFLXdF8ZUkYXFX-sE.cache +1 -0
  110. data/test/dummy/tmp/cache/sprockets/v3.0/gZp3uXMHuYQC4hzCr7bQfetKNdJAtbQmg3so2KpW1Dw.cache +2 -0
  111. data/test/dummy/tmp/cache/sprockets/v3.0/hZi1k6tpxxCGYxRe7zY74ItcOI8gZrREOpGuA8JSpGg.cache +2 -0
  112. data/test/dummy/tmp/cache/sprockets/v3.0/jqyQL40gGhkqnPg3IttXbq8JGHLONBjR0MlrN9HeIvU.cache +1 -0
  113. data/test/dummy/tmp/cache/sprockets/v3.0/kqQAJDpBuiNJ3XEy8VjtVcyUB9BVlP02oDMdVnlL04w.cache +0 -0
  114. data/test/dummy/tmp/cache/sprockets/v3.0/pEhaat2KBd5SrT7szC_8R1_6hK17FTpvoRFkmCRSD3M.cache +2 -0
  115. data/test/dummy/tmp/cache/sprockets/v3.0/pnW3u_1AN48ig6ngefI89y96xoSlvnJurx-e3J-leoE.cache +2 -0
  116. data/test/dummy/tmp/cache/sprockets/v3.0/q9kUTJTzJpwJJQ8CoWPFc_eCW76RZgB-R2sc4P84y6c.cache +0 -0
  117. data/test/dummy/tmp/cache/sprockets/v3.0/qFlPbNZ3UJs9EnENWVEbNWnrTEcjZkAQUzH55y3Ymi0.cache +1 -0
  118. data/test/dummy/tmp/cache/sprockets/v3.0/r86oWGkKGjcta2GtxqeESX1w_4FX1c_DWHxPWVKP28A.cache +1 -0
  119. data/test/dummy/tmp/cache/sprockets/v3.0/ssS2x0Wl67rwXHaVHsh6CO7ayn9fQ5saIwATKN6O-nI.cache +2 -0
  120. data/test/superlogger_test.rb +134 -0
  121. data/test/test_helper.rb +19 -0
  122. metadata +299 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a8233a0f1140b23ad1a79d954256e9f406e7dbf4
4
+ data.tar.gz: 7fc49063ae14c89e033a224dc619e878401d8f33
5
+ SHA512:
6
+ metadata.gz: 5bf2ca0272093a2b54928be31590756f57ddb0fb959c0fc4fc37cdd074cdaf51adbc903bfd5d549705708b53269e312afeb20ac04af50dec472ff41e7c4082c8
7
+ data.tar.gz: 1b181052bfb35cc721824dde111d9d87b4aadc0b8605d944b7c1657e0afff478a1b2052c6033b8df04f64f262de53b84744c709c177bed20985f9799ae8cafef
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 Soh Yu Ming
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,82 @@
1
+ Superlogger - Machine-readable logging for Rails [![Build Status](https://travis-ci.org/moexmen/superlogger.svg?branch=master)](https://travis-ci.org/moexmen/superlogger)
2
+ =======
3
+
4
+ Rails' default request logging is easy to read for humans but difficult for log aggregators such as Kibana, Graylog and Splunk. Superlogger transforms the logs into key-value pairs for easy parsing and adds useful details like Timestamp and Session ID for tracing purposes.
5
+
6
+ Default rails logging:
7
+ ```sh
8
+ Started GET "/home/index" for ::1 at 2016-04-11 16:23:27 +0800
9
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
10
+ Processing by HomeController#index as HTML
11
+ Something Load (0.2ms) SELECT "somethings".* FROM "somethings" WHERE "somethings"."paper" = ? AND "somethings"."stone" = ? ORDER BY "somethings"."id" ASC LIMIT 1 [["paper", "123"], ["stone", "456"]]
12
+ Rendered home/_partial.html.erb (0.2ms)
13
+ Rendered home/index.html.erb within layouts/application (5.2ms)
14
+ Completed 200 OK in 283ms (Views: 271.6ms | ActiveRecord: 0.6ms)
15
+
16
+ Started GET "/assets/application.self-e80e8f2318043e8af94dddc2adad5a4f09739a8ebb323b3ab31cd71d45fd9113.css?body=1" for ::1 at 2016-04-11 16:23:27 +0800
17
+
18
+ Started GET "/assets/application.self-8f06a73c35179188914ab50e057157639fce1401c1cdca640ac9cec33746fc5b.js?body=1" for ::1 at 2016-04-11 16:23:27 +0800
19
+ ```
20
+
21
+ Machine-readable logging with Superlogger:
22
+ ```sh
23
+ 2016-04-11 16:18:22.279 | b48534ea049a | I | middleware:28 | method=GET | path=/home/index | ip=::1
24
+ 2016-04-11 16:18:22.293 | b48534ea049a | D | action_controller_log_subscriber:9 | controller=HomeController | action=index | params={}
25
+ 2016-04-11 16:18:22.305 | b48534ea049a | D | active_record_log_subscriber:24 | sql=SELECT "somethings".* FROM "somethings" WHERE "somethings"."paper" = ? AND "somethings"."stone" = ? ORDER BY "somethings"."id" ASC LIMIT 1 | params=["'123'", "'456'"] | duration=0.48
26
+ 2016-04-11 16:18:22.316 | b48534ea049a | D | action_view_log_subscriber:6 | view=_partial.html.erb | duration=0.3
27
+ 2016-04-11 16:18:22.316 | b48534ea049a | D | action_view_log_subscriber:6 | view=index.html.erb | duration=5.6
28
+ 2016-04-11 16:18:22.541 | b48534ea049a | I | action_controller_log_subscriber:29 | status=200 | total_duration=247.16 | view_duration=235.25 | db_duration=0.78
29
+ ```
30
+
31
+ ## Features ##
32
+ - Timestamp (milliseconds)
33
+ - Session ID for logs across requests
34
+ - Key-value pairs for log data
35
+ - Muting of assets logging
36
+ - File and line numbers
37
+ - Recording of IP address
38
+
39
+ ## Installation ##
40
+
41
+ Add superlogger to your application's Gemfile
42
+
43
+ ```ruby
44
+ gem "superlogger"
45
+ ```
46
+
47
+ And then execute:
48
+
49
+ ```sh
50
+ $ bundle
51
+ ```
52
+
53
+ ## Usage ##
54
+
55
+ ```ruby
56
+ require 'superlogger'
57
+
58
+ class SomeClass
59
+ include Superlogger
60
+
61
+ def some_method
62
+ Logger.debug name:'john', age: '21'
63
+ Logger.info name:'john', age: '21'
64
+ Logger.warn name:'john', age: '21'
65
+ Logger.error name:'john', age: '21'
66
+ Logger.fatal name:'john', age: '21'
67
+ end
68
+ end
69
+ ```
70
+
71
+ ## Output Format ##
72
+ ```sh
73
+ 2015-03-26 23:37:38.086 | 970298669a40 | I | log_subscriber:24 | status:200 | total:858.35 | view:597.46 | db:34.96
74
+ < timestamp > | < session id > | < severity > | < file >:< line num > | < data you pass in ... >
75
+ ```
76
+
77
+ ### Severity Levels ###
78
+ - **D** - Debug
79
+ - **I** - Info
80
+ - **W** - Warn
81
+ - **E** - Error
82
+ - **F** - Fatal
data/Rakefile ADDED
@@ -0,0 +1,34 @@
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 = 'Superlogger'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,54 @@
1
+ require 'superlogger/version'
2
+ require 'superlogger/logger'
3
+
4
+ module Superlogger
5
+ module_function
6
+
7
+ def setup(app)
8
+ overwrite_rails_rack_logger
9
+ overwrite_action_dispatch_debug_exceptions
10
+ insert_superlogger_middleware(app)
11
+ detach_all_existing_log_subscribers
12
+ attach_superlogger_log_subscribers
13
+ end
14
+
15
+ def overwrite_rails_rack_logger
16
+ require 'superlogger/rails_rack_logger'
17
+ end
18
+
19
+ def overwrite_action_dispatch_debug_exceptions
20
+ require 'superlogger/action_dispatch_debug_exceptions'
21
+ end
22
+
23
+ def insert_superlogger_middleware(app)
24
+ require 'superlogger/middleware'
25
+
26
+ # important to insert after session middleware so we can get the session id
27
+ app.middleware.use Superlogger::Middleware
28
+ end
29
+
30
+ def detach_all_existing_log_subscribers
31
+ # force log subscribers to attach first so we can remove them all
32
+ require 'action_controller/log_subscriber'
33
+ require 'active_record/log_subscriber'
34
+ require 'action_view/log_subscriber'
35
+ require 'action_mailer/log_subscriber'
36
+
37
+ # remove log subscribers
38
+ ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
39
+ subscriber.patterns.each do |pattern|
40
+ ActiveSupport::Notifications.unsubscribe pattern
41
+ end
42
+ end
43
+
44
+ ActiveSupport::LogSubscriber.log_subscribers.clear
45
+ end
46
+
47
+ def attach_superlogger_log_subscribers
48
+ require 'superlogger/action_controller_log_subscriber'
49
+ require 'superlogger/action_view_log_subscriber'
50
+ require 'superlogger/active_record_log_subscriber'
51
+ end
52
+ end
53
+
54
+ require 'superlogger/railtie' if defined?(Rails)
@@ -0,0 +1,35 @@
1
+ module Superlogger
2
+ class ActionControllerLogSubscriber < ActiveSupport::LogSubscriber
3
+ INTERNAL_PARAMS = %w(controller action format _method only_path)
4
+
5
+ # start of controller action
6
+ def start_processing(event)
7
+ payload = event.payload
8
+
9
+ Logger.debug controller: payload[:controller], action: payload[:action], params: payload[:params].except(*INTERNAL_PARAMS)
10
+ end
11
+
12
+ # end of controller action
13
+ def process_action(event)
14
+ payload = event.payload
15
+
16
+ if payload[:exception]
17
+ status = ActionDispatch::ExceptionWrapper.status_code_for_exception(payload[:exception][0])
18
+
19
+ Logger.fatal status: status, exception: payload[:exception]
20
+ else
21
+ # Assume status 401 if action finishes without status code and no exception
22
+ # https://github.com/pcg79/devise/commit/1e2dab3c0ce49efe2b5940c15f47388c69d6731b
23
+ payload[:status] ||= 401
24
+
25
+ total_duration = event.duration.to_f.round(2)
26
+ view_duration = payload[:view_runtime].to_f.round(2) if payload.key?(:view_runtime)
27
+ db_duration = payload[:db_runtime].to_f.round(2) if payload.key?(:db_runtime)
28
+
29
+ Logger.info status: payload[:status], total_duration: total_duration, view_duration: view_duration, db_duration: db_duration
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ Superlogger::ActionControllerLogSubscriber.attach_to :action_controller
@@ -0,0 +1,11 @@
1
+ class ActionDispatch::DebugExceptions
2
+ alias_method :old_log_error, :log_error
3
+ def log_error(request, wrapper)
4
+ if wrapper.exception.is_a? ActionController::RoutingError
5
+ # Change routing errors to warn instead
6
+ Superlogger::Logger.warn routing_error: request['PATH_INFO'].inspect
7
+ else
8
+ old_log_error request, wrapper
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Superlogger
2
+ class ActionViewLogSubscriber < ActiveSupport::LogSubscriber
3
+ def render_template(event)
4
+ payload = event.payload
5
+
6
+ Logger.debug view: payload[:identifier].split('/').last, duration: event.duration.round(1)
7
+ end
8
+ alias :render_partial :render_template
9
+ alias :render_collection :render_template
10
+ end
11
+ end
12
+
13
+ Superlogger::ActionViewLogSubscriber.attach_to :action_view
@@ -0,0 +1,29 @@
1
+ module Superlogger
2
+ class ActiveRecordLogSubscriber < ActiveSupport::LogSubscriber
3
+ IGNORE_PAYLOAD_NAMES = ["SCHEMA", "EXPLAIN", "ActiveRecord::SchemaMigration Load"]
4
+
5
+ def self.runtime=(value)
6
+ ActiveRecord::RuntimeRegistry.sql_runtime = value
7
+ end
8
+
9
+ def self.runtime
10
+ ActiveRecord::RuntimeRegistry.sql_runtime ||= 0
11
+ end
12
+
13
+ def sql(event)
14
+ self.class.runtime += event.duration
15
+
16
+ return if Rails.env.production?
17
+
18
+ payload = event.payload
19
+ return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
20
+
21
+ sql = payload[:sql]
22
+ params = payload[:binds].map { |_, value| "'#{value}'"}
23
+
24
+ Logger.debug sql: sql, params: params, duration: event.duration.round(2)
25
+ end
26
+ end
27
+ end
28
+
29
+ Superlogger::ActiveRecordLogSubscriber.attach_to :active_record
@@ -0,0 +1,79 @@
1
+ require 'request_store'
2
+
3
+ module Superlogger
4
+ module Logger
5
+ def self.session_id=(session_id)
6
+ RequestStore.store[:superlogger_session_id] = session_id
7
+ end
8
+
9
+ def self.session_id
10
+ RequestStore.store[:superlogger_session_id] || "NS-#{Thread.current.object_id}"
11
+ end
12
+
13
+ def self.debug(*args)
14
+ Rails.logger.debug { format_msg(args) }
15
+ end
16
+
17
+ def self.info(*args)
18
+ Rails.logger.info { format_msg(args) }
19
+ end
20
+
21
+ def self.warn(*args)
22
+ Rails.logger.warn { format_msg(args) }
23
+ end
24
+
25
+ def self.error(*args)
26
+ Rails.logger.error { format_msg(args) }
27
+ end
28
+
29
+ def self.fatal(*args)
30
+ Rails.logger.fatal { format_msg(args) }
31
+ end
32
+
33
+ private
34
+
35
+ def self.format_msg(args)
36
+ "#{get_caller_location} | #{format_args(args)}"
37
+ end
38
+
39
+ def self.get_caller_location
40
+ # Find the last method call on Superlogger::Logger
41
+ count = 0
42
+ location_index = caller_locations(0).find_index do |location|
43
+ count += 1 if location && location.path.include?('superlogger/logger.rb')
44
+ count == 4
45
+ end
46
+
47
+ # Add 1 to get the caller of the logger
48
+ location = caller_locations(location_index + 1).first
49
+
50
+ # extract filename without file extension from location.path
51
+ # eg. superlogger/lib/superlogger/logger.rb
52
+ file = location.path.split('/').last.split('.').first
53
+
54
+ "#{file}:#{location.lineno}"
55
+ end
56
+
57
+ def self.format_args(args)
58
+ # format args in key=value pair, separated by pipes
59
+ args.map do |arg|
60
+ arg = {nil: arg} unless arg.is_a?(Hash)
61
+
62
+ arg.map do |key, value|
63
+ "#{key}=#{value}"
64
+ end
65
+ end.flatten.join(' | ')
66
+ end
67
+ end
68
+ end
69
+
70
+ # for overriding default Rails Logger format
71
+ class Logger
72
+ def format_message(severity, time, _progname, msg)
73
+ timestamp = time.strftime('%Y-%m-%d %H:%M:%S.%L')
74
+ session_id = Superlogger::Logger.session_id[0..11]
75
+ severity = severity.to_s.upcase[0]
76
+
77
+ "#{timestamp} | #{session_id} | #{severity} | #{msg}\n"
78
+ end
79
+ end
@@ -0,0 +1,31 @@
1
+ module Superlogger
2
+ class Middleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ request = ActionDispatch::Request.new(env)
9
+
10
+ # only process the actual request, less the assets
11
+ if request.path.start_with?('/assets/') == false
12
+ process_request(request)
13
+ end
14
+
15
+ @app.call(env)
16
+ end
17
+
18
+ def process_request(request)
19
+ if request.env['rack.session']
20
+ # Session is lazy loaded. Force session to load if it is not already loaded.
21
+ request.env['rack.session'].send(:load!) unless request.env['rack.session'].id
22
+
23
+ # Store session id before any actual logging is done
24
+ Superlogger::Logger.session_id = request.env['rack.session'].id
25
+ end
26
+
27
+ # Start of request logging
28
+ Logger.info method: request.method, path: request.fullpath, ip: request.ip
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ class Rails::Rack::Logger
2
+ # Overwrite the default call_app method to mute the following line:
3
+ # Started GET “/session/new” for 127.0.0.1 at 2012-09-26 14:51:42 -0700
4
+ def call_app(_request, env)
5
+ @app.call(env)
6
+ ensure
7
+ ActiveSupport::LogSubscriber.flush_all!
8
+ end
9
+ end
10
+
11
+
@@ -0,0 +1,7 @@
1
+ module Superlogger
2
+ class Railtie < Rails::Railtie
3
+ initializer :superlogger do |app|
4
+ Superlogger.setup(app)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Superlogger
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.