superlogger 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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>.