activetracker 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CHANGELOG.md +11 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +160 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +399 -0
  10. data/Rakefile +21 -0
  11. data/THOUGHTS.md +50 -0
  12. data/activetracker.gemspec +49 -0
  13. data/app/assets/config/active_tracker_manifest.js +4 -0
  14. data/app/assets/images/active_tracker/.keep +0 -0
  15. data/app/assets/images/active_tracker/logo.svg +6 -0
  16. data/app/assets/images/active_tracker/reload.svg +10 -0
  17. data/app/assets/javascripts/active_tracker/active_tracker.js +15 -0
  18. data/app/assets/javascripts/active_tracker/tabs.js +12 -0
  19. data/app/assets/javascripts/active_tracker/tags.js +18 -0
  20. data/app/assets/javascripts/active_tracker/zepto.js +2 -0
  21. data/app/assets/stylesheets/active_tracker/active_tracker.css.scss +21 -0
  22. data/app/assets/stylesheets/active_tracker/tailwind.min.scss +1 -0
  23. data/app/controllers/active_tracker/base_controller.rb +22 -0
  24. data/app/controllers/active_tracker/dashboard_controller.rb +10 -0
  25. data/app/controllers/active_tracker/exceptions_controller.rb +41 -0
  26. data/app/controllers/active_tracker/queries_controller.rb +39 -0
  27. data/app/controllers/active_tracker/requests_controller.rb +41 -0
  28. data/app/helpers/active_tracker/application_helper.rb +4 -0
  29. data/app/helpers/active_tracker/images_helper.rb +8 -0
  30. data/app/helpers/active_tracker/output_helper.rb +35 -0
  31. data/app/helpers/active_tracker/pagination_helper.rb +16 -0
  32. data/app/jobs/active_tracker/application_job.rb +4 -0
  33. data/app/mailers/active_tracker/application_mailer.rb +6 -0
  34. data/app/models/active_tracker/application_record.rb +5 -0
  35. data/app/views/active_tracker/common/_empty.html.erb +9 -0
  36. data/app/views/active_tracker/common/_pagination.html.erb +22 -0
  37. data/app/views/active_tracker/common/_plugin_nav.html.erb +10 -0
  38. data/app/views/active_tracker/dashboard/index.html.erb +18 -0
  39. data/app/views/active_tracker/exceptions/index.html.erb +44 -0
  40. data/app/views/active_tracker/exceptions/show.html.erb +56 -0
  41. data/app/views/active_tracker/queries/index.html.erb +38 -0
  42. data/app/views/active_tracker/queries/show.html.erb +39 -0
  43. data/app/views/active_tracker/requests/_request.html.erb +30 -0
  44. data/app/views/active_tracker/requests/index.html.erb +26 -0
  45. data/app/views/active_tracker/requests/show.html.erb +81 -0
  46. data/app/views/layouts/active_tracker/active_tracker.html.erb +46 -0
  47. data/bin/console +14 -0
  48. data/bin/rails +25 -0
  49. data/bin/setup +8 -0
  50. data/doc/logo.md +11 -0
  51. data/integration/generators/installer.rb +7 -0
  52. data/integration/templates/initializer.rb +32 -0
  53. data/lib/active_tracker.rb +41 -0
  54. data/lib/active_tracker/configuration.rb +67 -0
  55. data/lib/active_tracker/engine.rb +24 -0
  56. data/lib/active_tracker/exception_capturer.rb +38 -0
  57. data/lib/active_tracker/model.rb +153 -0
  58. data/lib/active_tracker/output_capturer.rb +37 -0
  59. data/lib/active_tracker/plugin.rb +4 -0
  60. data/lib/active_tracker/plugin/base.rb +9 -0
  61. data/lib/active_tracker/plugin/exception.rb +113 -0
  62. data/lib/active_tracker/plugin/query.rb +128 -0
  63. data/lib/active_tracker/plugin/request.rb +163 -0
  64. data/lib/active_tracker/rails_logger.rb +120 -0
  65. data/lib/active_tracker/router.rb +16 -0
  66. data/lib/active_tracker/version.rb +3 -0
  67. data/lib/activetracker.rb +3 -0
  68. data/lib/tasks/active_tracker_tasks.rake +12 -0
  69. data/spec/activetracker_spec.rb +36 -0
  70. data/spec/dummy/Rakefile +6 -0
  71. data/spec/dummy/app/assets/config/manifest.js +3 -0
  72. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  73. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  74. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  75. data/spec/dummy/app/javascript/packs/application.js +15 -0
  76. data/spec/dummy/app/jobs/application_job.rb +7 -0
  77. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  78. data/spec/dummy/app/models/application_record.rb +3 -0
  79. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  80. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  81. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  82. data/spec/dummy/bin/rails +4 -0
  83. data/spec/dummy/bin/rake +4 -0
  84. data/spec/dummy/bin/setup +33 -0
  85. data/spec/dummy/config.ru +5 -0
  86. data/spec/dummy/config/application.rb +37 -0
  87. data/spec/dummy/config/boot.rb +5 -0
  88. data/spec/dummy/config/database.yml +54 -0
  89. data/spec/dummy/config/environment.rb +5 -0
  90. data/spec/dummy/config/environments/development.rb +62 -0
  91. data/spec/dummy/config/environments/production.rb +107 -0
  92. data/spec/dummy/config/environments/test.rb +48 -0
  93. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  94. data/spec/dummy/config/initializers/assets.rb +12 -0
  95. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  96. data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
  97. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  98. data/spec/dummy/config/initializers/disable_remote_forms.rb +1 -0
  99. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  100. data/spec/dummy/config/initializers/inflections.rb +16 -0
  101. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  102. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  103. data/spec/dummy/config/locales/en.yml +33 -0
  104. data/spec/dummy/config/puma.rb +38 -0
  105. data/spec/dummy/config/routes.rb +3 -0
  106. data/spec/dummy/config/spring.rb +6 -0
  107. data/spec/dummy/config/storage.yml +34 -0
  108. data/spec/dummy/public/404.html +67 -0
  109. data/spec/dummy/public/422.html +67 -0
  110. data/spec/dummy/public/500.html +66 -0
  111. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  112. data/spec/dummy/public/apple-touch-icon.png +0 -0
  113. data/spec/dummy/public/favicon.ico +0 -0
  114. data/spec/lib/active_tracker/model_spec.rb +38 -0
  115. data/spec/spec_helper.rb +18 -0
  116. metadata +348 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ca8012a092717f5f66cc467c1bc9146eb944b0e36c86ad098ea2e31f302ba76b
4
+ data.tar.gz: d1e8f33220aa0e1accfbd79e7bf54d9db3302d9f8b8a0d9d9c9f82b00b43d39f
5
+ SHA512:
6
+ metadata.gz: dfd9ac4744bf119d05f28ee6089cfab0ee06b49b783ac803b05af94fc2c7498ed4199d24d18a41bf9dfa91ec78225420fcdf5172c4b81fa87741486ff91fc2f5
7
+ data.tar.gz: fce52cb07294f7317edfc891a898543bf07515770b20bbdeb876184d2f1ac94f2a42fe6ff7810fc1d47d89c8c9c6b7e8d2ff17d2fc231aa6c97cc9abb3988ab3
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /pkg/
6
+ /spec/reports/
7
+ /tmp/
8
+
9
+ # rspec failure tracking
10
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.0
7
+ before_install: gem install bundler -v 1.17.3
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.0.1] - 2019-09-27
10
+ ### Added
11
+ - New gem started
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in activetracker.gemspec
6
+ gemspec
@@ -0,0 +1,160 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ activetracker (0.4.0)
5
+ redis (~> 4.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionmailer (4.2.11.1)
11
+ actionpack (= 4.2.11.1)
12
+ actionview (= 4.2.11.1)
13
+ activejob (= 4.2.11.1)
14
+ mail (~> 2.5, >= 2.5.4)
15
+ rails-dom-testing (~> 1.0, >= 1.0.5)
16
+ actionpack (4.2.11.1)
17
+ actionview (= 4.2.11.1)
18
+ activesupport (= 4.2.11.1)
19
+ rack (~> 1.6)
20
+ rack-test (~> 0.6.2)
21
+ rails-dom-testing (~> 1.0, >= 1.0.5)
22
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
23
+ actionview (4.2.11.1)
24
+ activesupport (= 4.2.11.1)
25
+ builder (~> 3.1)
26
+ erubis (~> 2.7.0)
27
+ rails-dom-testing (~> 1.0, >= 1.0.5)
28
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
29
+ activejob (4.2.11.1)
30
+ activesupport (= 4.2.11.1)
31
+ globalid (>= 0.3.0)
32
+ activemodel (4.2.11.1)
33
+ activesupport (= 4.2.11.1)
34
+ builder (~> 3.1)
35
+ activerecord (4.2.11.1)
36
+ activemodel (= 4.2.11.1)
37
+ activesupport (= 4.2.11.1)
38
+ arel (~> 6.0)
39
+ activesupport (4.2.11.1)
40
+ i18n (~> 0.7)
41
+ minitest (~> 5.1)
42
+ thread_safe (~> 0.3, >= 0.3.4)
43
+ tzinfo (~> 1.1)
44
+ addressable (2.7.0)
45
+ public_suffix (>= 2.0.2, < 5.0)
46
+ arel (6.0.4)
47
+ builder (3.2.3)
48
+ capybara (3.29.0)
49
+ addressable
50
+ mini_mime (>= 0.1.3)
51
+ nokogiri (~> 1.8)
52
+ rack (>= 1.6.0)
53
+ rack-test (>= 0.6.3)
54
+ regexp_parser (~> 1.5)
55
+ xpath (~> 3.2)
56
+ concurrent-ruby (1.1.5)
57
+ crass (1.0.4)
58
+ diff-lcs (1.3)
59
+ erubis (2.7.0)
60
+ factory_girl (4.9.0)
61
+ activesupport (>= 3.0.0)
62
+ factory_girl_rails (4.9.0)
63
+ factory_girl (~> 4.9.0)
64
+ railties (>= 3.0.0)
65
+ fakeredis (0.7.0)
66
+ redis (>= 3.2, < 5.0)
67
+ globalid (0.4.2)
68
+ activesupport (>= 4.2.0)
69
+ i18n (0.9.5)
70
+ concurrent-ruby (~> 1.0)
71
+ loofah (2.3.0)
72
+ crass (~> 1.0.2)
73
+ nokogiri (>= 1.5.9)
74
+ mail (2.7.1)
75
+ mini_mime (>= 0.1.1)
76
+ mini_mime (1.0.2)
77
+ mini_portile2 (2.4.0)
78
+ minitest (5.12.2)
79
+ nokogiri (1.10.4)
80
+ mini_portile2 (~> 2.4.0)
81
+ public_suffix (4.0.1)
82
+ rack (1.6.11)
83
+ rack-test (0.6.3)
84
+ rack (>= 1.0)
85
+ rails (4.2.11.1)
86
+ actionmailer (= 4.2.11.1)
87
+ actionpack (= 4.2.11.1)
88
+ actionview (= 4.2.11.1)
89
+ activejob (= 4.2.11.1)
90
+ activemodel (= 4.2.11.1)
91
+ activerecord (= 4.2.11.1)
92
+ activesupport (= 4.2.11.1)
93
+ bundler (>= 1.3.0, < 2.0)
94
+ railties (= 4.2.11.1)
95
+ sprockets-rails
96
+ rails-deprecated_sanitizer (1.0.3)
97
+ activesupport (>= 4.2.0.alpha)
98
+ rails-dom-testing (1.0.9)
99
+ activesupport (>= 4.2.0, < 5.0)
100
+ nokogiri (~> 1.6)
101
+ rails-deprecated_sanitizer (>= 1.0.1)
102
+ rails-html-sanitizer (1.2.0)
103
+ loofah (~> 2.2, >= 2.2.2)
104
+ railties (4.2.11.1)
105
+ actionpack (= 4.2.11.1)
106
+ activesupport (= 4.2.11.1)
107
+ rake (>= 0.8.7)
108
+ thor (>= 0.18.1, < 2.0)
109
+ rake (10.5.0)
110
+ redis (4.1.2)
111
+ regexp_parser (1.6.0)
112
+ rspec-core (3.8.2)
113
+ rspec-support (~> 3.8.0)
114
+ rspec-expectations (3.8.4)
115
+ diff-lcs (>= 1.2.0, < 2.0)
116
+ rspec-support (~> 3.8.0)
117
+ rspec-mocks (3.8.1)
118
+ diff-lcs (>= 1.2.0, < 2.0)
119
+ rspec-support (~> 3.8.0)
120
+ rspec-rails (3.8.2)
121
+ actionpack (>= 3.0)
122
+ activesupport (>= 3.0)
123
+ railties (>= 3.0)
124
+ rspec-core (~> 3.8.0)
125
+ rspec-expectations (~> 3.8.0)
126
+ rspec-mocks (~> 3.8.0)
127
+ rspec-support (~> 3.8.0)
128
+ rspec-support (3.8.2)
129
+ sprockets (4.0.0)
130
+ concurrent-ruby (~> 1.0)
131
+ rack (> 1, < 3)
132
+ sprockets-rails (3.2.1)
133
+ actionpack (>= 4.0)
134
+ activesupport (>= 4.0)
135
+ sprockets (>= 3.0.0)
136
+ thor (0.20.3)
137
+ thread_safe (0.3.6)
138
+ timecop (0.9.1)
139
+ tzinfo (1.2.5)
140
+ thread_safe (~> 0.1)
141
+ xpath (3.2.0)
142
+ nokogiri (~> 1.8)
143
+
144
+ PLATFORMS
145
+ ruby
146
+
147
+ DEPENDENCIES
148
+ activesupport
149
+ activetracker!
150
+ bundler (~> 1.17)
151
+ capybara
152
+ factory_girl_rails
153
+ fakeredis
154
+ rails
155
+ rake (~> 10.0)
156
+ rspec-rails
157
+ timecop
158
+
159
+ BUNDLED WITH
160
+ 1.17.3
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Civo Ltd <hello@civo.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,399 @@
1
+ # ActiveTracker
2
+
3
+ > ActiveTracker is a Ruby gem implementing an engine that you add to your Rails application to track user requests through your logs, see errors raised, query usage along with other things configured via a plugin architecture.
4
+
5
+ ![Overview of ActiveTracker](https://user-images.githubusercontent.com/22904/67408234-9edf6300-f5b0-11e9-8eb5-eda79642e15f.png)
6
+
7
+ ## Contents
8
+
9
+ * [Installation](#installation)
10
+ * [Quickstart](##tldr---quickstart)
11
+ * [Prerequisites](#prerequisites)
12
+ * [Configuration](#configuration)
13
+ * [Request plugin](#request-plugin)
14
+ * [Filters](#filters)
15
+ * [Tagging your own requests](#tagging-your-own-requests)
16
+ * [Redaction](#redaction)
17
+ * [Query plugin](#query-plugin)
18
+ * [Filters](#filters-1)
19
+ * [Slow queries](#slow-queries)
20
+ * [Exception plugin](#exception-plugin)
21
+ * [Filters](#filters-2)
22
+ * [Upcoming plans](#upcoming-plans)
23
+ * [Writing plugins](#writing-plugins)
24
+ * [The plugin itself](#1-the-plugin-itself)
25
+ * [Controller and views](#2-controllers-and-views)
26
+ * [How can I help?](#how-can-i-help)
27
+ * [Contributing](#contributing)
28
+ * [Licence](#licence)
29
+
30
+
31
+ ## Installation
32
+
33
+ Add this line to your application's Gemfile:
34
+
35
+ ```ruby
36
+ gem 'activetracker'
37
+ ```
38
+
39
+ And then execute:
40
+
41
+ $ bundle
42
+
43
+ Then run:
44
+
45
+ $ bundle exec rails activetracker:install
46
+
47
+ After this you can run your Rails application and visit http://your-host/activetracker to see ActiveTracker's capturing of your requests, etc.
48
+
49
+ ### TL;DR - Quickstart
50
+
51
+ ```sh
52
+ echo "gem 'activetracker'" >> Gemfile
53
+ bundle
54
+ bundle exec rails activetracker:install
55
+ rails s
56
+ # Then open http://localhost:3000/activetracker and hit other pages
57
+ # on your site
58
+ ```
59
+
60
+ ## Prequisites
61
+
62
+ This gem is currently only tested against Rails 5.2. If you're using it with another version of Rails and it works, please let us know. If you find a bug with it using another version of Rails, please raise it as an [issue](https://github.com/civo/activetracker/issues).
63
+
64
+ ActiveTracker stores its data in Redis, so you must have a Redis service available for it.
65
+
66
+ ## Configuration
67
+
68
+ After you run the `rails activetracker:install` command, you will have a file called `activetracker.rb` in `config/initializers`. This file controls which ActiveTracker plugins are enabled and configuring ActiveTracker as a whole as well as each individual plugin.
69
+
70
+ #### Selecting plugins
71
+
72
+ Configuring the list of plugins is as easy as listing them:
73
+
74
+ ```
75
+ ActiveTracker::Configuration.plugins = [
76
+ ActiveTracker::Plugin::Request,
77
+ ActiveTracker::Plugin::Exception,
78
+ ]
79
+ ```
80
+
81
+ This will enable any Rails integration necessary and add them to ActiveTracker's sidebar.
82
+
83
+ #### Redis
84
+
85
+ ActiveTracker stores its data in Redis. We recommend a separate Redis installation for this, with a memory limit set and configured to automatically delete least recently used items - put some lines like this in your Redis configuration file:
86
+
87
+ ```
88
+ maxmemory 250mb
89
+ maxmemory-policy allkeys-lru
90
+ ```
91
+
92
+ You should point ActiveTracker to your Redis server within the `activetracker.rb` initializer with:
93
+
94
+ ```
95
+ ActiveTracker::Configuration.redis_url = "redis://localhost:6379/15"
96
+ ```
97
+
98
+ #### Pagination
99
+
100
+ If you don't like the default number of items per page in ActiveTracker, you can change it with:
101
+
102
+ ```
103
+ ActiveTracker::Configuration.per_page = 50
104
+ ```
105
+
106
+ #### Different mountpoint
107
+
108
+ You can choose to have ActiveTracker available anywhere if you don't like the default of `/activetracker`:
109
+
110
+ ```
111
+ ActiveTracker::Configuration.mountpoint = "debugger"
112
+ ```
113
+
114
+ #### Authentication
115
+
116
+ If you want to setup authentication for your installation:
117
+
118
+ ```
119
+ ActiveTracker::Configuration.authentication = "username:password"
120
+
121
+ # or using a proc:
122
+
123
+ ActiveTracker::Configuration.authentication do
124
+ false unless params[:password] == "password"
125
+ end
126
+ ```
127
+
128
+ The first example uses HTTP Basic authentication and the latter will reject unauthenticated requests with 404 (so as not to give away its existence). These are executed in the context of a controller, but it doesn't descend from ApplicationController, so you can't use any authentication methods defined there (if you wish to `extend` or `include` them on `ActiveTracker::BaseController` you can though).
129
+
130
+ ## Request plugin
131
+
132
+ > The request plugin captures the log and output from every request your Rails application receives.
133
+
134
+ <img width="400" alt="Screenshot 2019-10-23 at 16 19 14" src="https://user-images.githubusercontent.com/22904/67408530-0d242580-f5b1-11e9-9d64-51bf52125978.png"> <img width="400" alt="Screenshot 2019-10-23 at 16 19 20" src="https://user-images.githubusercontent.com/22904/67408531-0d242580-f5b1-11e9-8cb6-62c81a84936f.png">
135
+
136
+
137
+ There is a limit of 64KB for the log, but the full output is captured for every request.
138
+
139
+ #### Filters
140
+
141
+ You can filter requests from being captured by adding to the `activetracker` initializer lines like:
142
+
143
+ ```ruby
144
+ ActiveTracker::Plugin::Request.filters << /foobar/
145
+ # or
146
+ ActiveTracker::Plugin::Request.filters += "/foobar"
147
+ # or replace them entirely with
148
+ ActiveTracker::Plugin::Request.filters = ["/foobar"]
149
+ ```
150
+
151
+ By default ActiveTracker itself is filtered out. If a string is supplied it must match the start of the path of the request, not just any portion. Regular expression filters are applied against the whole path.
152
+
153
+ #### Tagging your own requests
154
+
155
+ During a request cycle you can add custom tags to requests by putting lines like this in your controller, model, helper, service, etc:
156
+
157
+ ```
158
+ ActiveTracker::Plugin::Request.tag_current(key: value, key2: value2)
159
+ ```
160
+
161
+ These tags are then shown alongside every request, and if you click the tag you can filter the requests down to only those matching that tag(s).
162
+
163
+ The tag names `user_avatar_url`, `user_name` and `user_email` have special meaning, if you set these tags, they will be displayed alongside the request in a nice format when you view it (see "Test McPerson" in the right hand screenshot above).
164
+
165
+ #### Redaction
166
+
167
+ The easiest way of ensuring values such as passwords in the log and output aren't leaked to ActiveTracker is to tell ActiveTracker to explicitly redact that value. For example, in your controller:
168
+
169
+ ```
170
+ def login
171
+ ActiveTracker::Plugin::Request.redact(Current.user.password_hash)
172
+ ActiveTracker::Plugin::Request.redact(params[:password])
173
+ end
174
+ ```
175
+
176
+ These are cleared upon each request.
177
+
178
+ ## Query plugin
179
+
180
+ > The query plugin saves a count for each SQL query executed and how long it took, to enable you to find queries executed too often or queries you consider to be too slow for your application.
181
+
182
+ <img width="400" alt="Screenshot 2019-10-24 at 08 55 40" src="https://user-images.githubusercontent.com/22904/67464913-1a3a2680-f63c-11e9-9ba8-e1d28fcfa54f.png"> <img width="400" alt="Screenshot 2019-10-24 at 08 55 45" src="https://user-images.githubusercontent.com/22904/67464921-1c03ea00-f63c-11e9-95dc-568d5d8754ce.png">
183
+
184
+ #### Filters
185
+
186
+ You can filter queries from being captured by adding to the `activetracker` initializer lines to search both the SQL and the ActiveRecord `name` of the query (e.g. `Order Load`) like this:
187
+
188
+ ```ruby
189
+ ActiveTracker::Plugin::Query.filters << /secret_records/
190
+ # or
191
+ ActiveTracker::Plugin::Query.filters += "secret_records"
192
+ # or replace them entirely with
193
+ ActiveTracker::Plugin::Query.filters = ["secret_records"]
194
+ ```
195
+
196
+ By default ActiveTracker filters out queries containing either `SCHEMA` or an empty value. These values are searched anywhere in the SQL or `name`.
197
+
198
+ #### Slow queries
199
+
200
+ You can configure a threshold of how slow a query has to be before it's highlighted with a red time value using:
201
+
202
+ ```ruby
203
+ ActiveTracker::Plugin::Query.min_slow_duration_ms = 25
204
+ ```
205
+
206
+ By default this is set to 100ms, but this is probably too loose for most applications.
207
+
208
+ ## Exception plugin
209
+
210
+ > The exception plugin tracks unhandled exceptions, incrementing a counter for them and keeping a backtrace to where the error occured.
211
+
212
+ <img width="400" alt="Screenshot 2019-10-24 at 09 03 53" src="https://user-images.githubusercontent.com/22904/67465517-3ee2ce00-f63d-11e9-8395-104ec31f046e.png"> <img width="400" alt="Screenshot 2019-10-24 at 09 03 59" src="https://user-images.githubusercontent.com/22904/67465525-42765500-f63d-11e9-82b1-e2b904c20025.png">
213
+
214
+ #### Filters
215
+
216
+ You can filter certain exceptions from being captured by adding to the `activetracker` initializer lines to specify a class name like this:
217
+
218
+ ```ruby
219
+ ActiveTracker::Plugin::Query.filters << ActiveRecord::RecordNotFound
220
+ # or
221
+ ActiveTracker::Plugin::Query.filters += "ActiveRecord::RecordNotFound"
222
+ # or replace them entirely with
223
+ ActiveTracker::Plugin::Query.filters = [/.*RecordNotFound/]
224
+ ```
225
+
226
+ There are no exception filters by default. Strings and classes have to be exact matches, but regular expressions match against the name normally.
227
+
228
+ ## Upcoming plans
229
+
230
+ The next set of plugins we're planning on writing are:
231
+
232
+ #### Resque
233
+
234
+ Statistics for current queue lengths and current amounts of failed jobs. Clicking the sidebar will list jobs on each queue and failed jobs - just like the Resque Web UI but all in the same place as your other ActiveTracker monitoring panes.
235
+
236
+ #### Mail
237
+
238
+ Recording when emails are sent from your system, along with their body for easy previewing of what was sent and when.
239
+
240
+ #### Cache
241
+
242
+ Using Rails notifications track cache hits and misses for each key.
243
+
244
+ #### Events
245
+
246
+ We'd like a simple system of triggering events from within your application that simply are recorded to ActiveTracker. So maybe a key, a description and a backtrace would be enough?
247
+
248
+ ## Writing plugins
249
+
250
+ If you would like to write a plugin, there is a minimum set of code you need to write. In our example we're going to write a "Fake" plugin.
251
+
252
+ ### 1. The plugin itself
253
+
254
+ A plain Ruby object on the path (in ActiveTracker these live in `lib/active_tracker/plugin`) namespaced under `ActiveTracker::Plugin`. The minimum methods this should implement are:
255
+
256
+ ```ruby
257
+ module ActiveTracker
258
+ module Plugin
259
+ class Fake < Base
260
+ def self.register
261
+ # Subscribe to Notifications
262
+ # Insert Rails middleware
263
+ # Hook in to Rails/gem internals
264
+
265
+ @@registered = true
266
+ end
267
+
268
+ def self.registered?
269
+ @@registered rescue false
270
+ end
271
+
272
+ def self.resources_name
273
+ # return a symbol for use in config/routes.rb like:
274
+ # resources resources_name
275
+ end
276
+
277
+ def self.nav_svg
278
+ # return the HTML safe source of an SVG image with a class
279
+ # specified of 'fill-current' and 16x16 dimensions. Don't
280
+ # specify the colour on the paths, they should be monochrome
281
+ end
282
+
283
+ def self.nav_title
284
+ # return a string containing the title to use in the sidebar
285
+ end
286
+
287
+ def self.statistics
288
+ # Return an array of hashes containing keys of:
289
+ # {plugin: self, label: "Something", value: 1}
290
+ # if the statistic is bad, add a key of `error: true`
291
+ #
292
+ # if you don't report statistics, don't implement this method
293
+ end
294
+ end
295
+ end
296
+ end
297
+ ```
298
+
299
+ The hooks/notifications/middleware/etc should insert records in to the `ActiveTracker::Model` using a couple of simple methods. If you are recording EVERY occurence of this event:
300
+
301
+ ```ruby
302
+ # Type of object, JSON of the data for this object, tags are a hash of
303
+ # keys and values that can be useful for filtering. Data type is if you
304
+ # are saving multiple objects for each Fake.
305
+ ActiveTracker::Model.save("Fake", {output: output},
306
+ tags: {my_value: something.value},
307
+ data_type: "full",
308
+ expiry: 7.days,
309
+ log_at: Time.now
310
+ )
311
+ ```
312
+
313
+ Or if you only want to track the latest one, but count all of them, you could do it like this:
314
+
315
+ ```ruby
316
+ ActiveTracker::Model.find_or_create("Fake", tags:tags, data_type: "full") do |obj|
317
+ if obj.persisted
318
+ ActiveTracker::Model.delete(obj.key)
319
+ end
320
+ obj.data ||= {}
321
+ obj.data["count"] = (obj.data["count"] || 0) + 1
322
+
323
+ obj.data["output"] = output
324
+ end
325
+ ```
326
+
327
+ ### 2. Controller and views
328
+
329
+ You should implement an `ActiveTracker::FakesController` that implements the normal RESTful endpoints. A barebones example of how to write this would be something like:
330
+
331
+ ```ruby
332
+ module ActiveTracker
333
+ class FakesController < ActiveTracker::BaseController
334
+ def index
335
+ # Track how long this request takes
336
+ ts = Time.current.to_f
337
+ # Get all matching records from the model
338
+ @fakes = ActiveTracker::Model.all("Fake")
339
+ # If you're providing filtering, use a method to reduce the recordset
340
+ filter_fakes if params[:q].present?
341
+ # Finish tracking this request's duration
342
+ @duration = (Time.current.to_f - ts) * 1000
343
+ # Paginate the objects
344
+ @fakes, @pagination = ActiveTracker::Model.paginate(@fakes, params[:page], ActiveTracker::Configuration.per_page)
345
+ end
346
+
347
+ def show
348
+ # Find the fake from the model
349
+ @request = ActiveTracker::Model.find(params[:id])
350
+ end
351
+
352
+ private
353
+
354
+ def filter_requests
355
+ # Go through each record in @fakes determining whether to select/reject
356
+ # it or not, based on params[:q] and reset @fakes to the new set
357
+ # if needed
358
+ end
359
+ end
360
+ end
361
+ ```
362
+
363
+ For styling, have a look at the Tailwind classes used in the views for other plugins and try to maintain consistent styling - unless you're willing to upgrade all other plugins 😉
364
+
365
+ Once you've written your plugin, you can add it to `integration/templates/initializer.rb` either uncommented if it will be a new default plugin, or at least to the comment block at the top for available plugins.
366
+
367
+ ## How can I help?
368
+
369
+ The most obvious way to help is by jumping in and raising issues, creating your own plugins (we'll list them here when people start doing that, or maybe integrate them in to this repository if people want to just donate them and they have wide appeal).
370
+
371
+ However, if you are looking for a way to help out but don't have any ideas, we've listed a few below that we'd appreciate some help with (we'll hopefully get to all of them over time, but have our own list above that we're planning on first):
372
+
373
+ #### Webpacker
374
+
375
+ Currently ActiveTracker uses the asset pipeline. We'd love it if it would work with Webpacker or the asset pipeline (and maybe it already does), whichever the containing project is using.
376
+
377
+ #### Ajax loading of results
378
+
379
+ We would love to have it Ajaxified so if you stay on the page (and maybe click a button to enable the feature) it automatically puts a banner bar at the top of results saying "New requests/queries/whatever available" and if you click it, the new entries will be Ajax loaded in.
380
+
381
+ #### Automated testing
382
+
383
+ Having no experience of automated testing a Rails engine, if anyone fancies putting in some testing for us - we'd *LOVE* that!
384
+
385
+ #### Responsive
386
+
387
+ We chose [Tailwind CSS](https://tailwindcss.com) because it's lovely to work with and you can quickly/easily put together fairly nice interfaces. It's also built to be responsive, but as this is a small, spare time project for us we haven't had chance to do this yet.
388
+
389
+ #### Dark mode
390
+
391
+ Some of our team love dark displays, but the main author of this gem doesn't. So while we'd love to have it, it's not high enough on the priority list to justify at the moment.
392
+
393
+ ## Contributing
394
+
395
+ Bug reports and pull requests are welcome on GitHub at https://github.com/civo/activetracker.
396
+
397
+ ## Licence
398
+
399
+ The gem is available as open source under the terms of the [MIT Licence](https://opensource.org/licenses/MIT). The [ActiveTracker logo](doc/logo.md) was an icon downloaded from LogoFound.com and combined with the name in Helvetica Neue.