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,4 @@
1
+ module ActiveTracker
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module ActiveTracker
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveTracker
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ <div class="bg-gray-200 shadow mt-4 rounded-lg py-20 text-center">
2
+ <div class="text-blue-800">
3
+ <svg width="128" height="128" class="inline fill-current" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M128 64c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64C0 28.654 28.654 0 64 0c35.346 0 64 28.654 64 64zm-37.276.816c-.775 5.69-3.425 10.786-7.285 14.668-4.65 4.659-11.076 7.539-18.163 7.539-2.058 0-4.073-.24-5.99-.706l-12.85 21.205c-2.001 3.303-6.299 4.362-9.596 2.357a7.009 7.009 0 01-2.353-9.614l12.611-20.81a25.68 25.68 0 01-7.496-18.169c0-1.2.084-2.385.24-3.543a77.805 77.805 0 009.116 3.247v.296a16.33 16.33 0 004.777 11.563 16.234 16.234 0 0011.54 4.786c4.51 0 8.596-1.836 11.54-4.786 2.002-2.005 3.481-4.518 4.228-7.327 3.128-.043 6.214-.24 9.188-.636l.479-.07h.014zM57.872 17.79c-1.722-1.02-3.269-1.935-5.236-1.935h-.014c-3.368 0-5.44 2.824-6.116 6.127-.26 1.3-.469 2.635-.68 3.99-.338 2.166-.684 4.385-1.264 6.598-7.257.805-12.936 2.725-15.36 5.648-2.578 3.12-1.042 6.889 3.847 10.517 5.186 3.854 14.105 7.51 25.519 9.897 11.85 2.47 23.574 3.007 32.55 1.807 8.835-1.172 14.584-3.981 15.232-7.963.606-3.755-3.48-7.778-10.23-11.21a61.699 61.699 0 00-4.396-1.99c-1.793-5.051-2.735-9.689-3.524-13.57a150.176 150.176 0 00-.788-3.724c-.747-3.275-2.748-6.127-6.115-6.127-2.357 0-4.224.99-6.236 2.056-2.355 1.248-4.91 2.603-8.687 2.603-3.899 0-6.339-1.444-8.502-2.724zM74.632 49.4c6.214.353 12.216.14 18.388-1.003v-.014c1.913-.35 1.654-1.087 1.389-1.843l-.008-.02c-.386-1.058-.888-2.138-1.382-3.197-.191-.411-.381-.82-.562-1.222-15.796 3.219-36.933-1.468-49.234-5.605a54.513 54.513 0 01-1.93 3.459l-.002.003c-.479.761-1.01 1.607 1.157 2.496 4.89 2.005 8.764 3.388 14.64 4.616 5.989 1.243 11.935 2.02 17.544 2.33z"/></svg>
4
+ </div>
5
+ <div class="mt-10 text-blue-800">
6
+ <p>We didn't find any <%= plural_type %>.</p>
7
+ <p class="mt-2">Please check back again later.</p>
8
+ </div>
9
+ </div>
@@ -0,0 +1,22 @@
1
+ <div class="w-full mt-4 flex justify-between">
2
+ <% if duration %>
3
+ <div class="text-sm mb-2 text-gray-700">Returned <b class="font-bold"><%= pluralize pagination[:total], "result" %></b> in <b class="font-bold"><%= duration.to_i %>ms</b></div>
4
+ <% end %>
5
+ <div>
6
+ <a href='<%= insert_page_to_url(url, 1) %>' class="px-2 py-1 border-gray-300 bg-white text-sm border text-gray-700 rounded">First</a>
7
+ <% if pagination[:page] > 1 %>
8
+ <a href='<%= insert_page_to_url(url, pagination[:page] - 1) %>' class="px-2 py-1 border-gray-300 bg-white text-sm border text-gray-700 rounded">Prev</a>
9
+ <% end %>
10
+ <% pagination[:window].each do |page| %>
11
+ <% if page == pagination[:page] %>
12
+ <span class="px-2 py-1 border-gray-300 bg-gray-700 text-sm border text-gray-300 rounded"><%= page %></span>
13
+ <% else %>
14
+ <a href='<%= insert_page_to_url(url, page) %>' class="px-2 py-1 border-gray-300 bg-white text-sm border text-gray-700 rounded"><%= page %></a>
15
+ <% end %>
16
+ <% end %>
17
+ <% if pagination[:page] < pagination[:total_pages] %>
18
+ <a href='<%= insert_page_to_url(url, pagination[:page] + 1) %>' class="px-2 py-1 border-gray-300 bg-white text-sm border text-gray-700 rounded">Next</a>
19
+ <% end %>
20
+ <a href='<%= insert_page_to_url(url, pagination[:total_pages]) %>' class="px-2 py-1 border-gray-300 bg-white text-sm border text-gray-700 rounded">Last</a>
21
+ </div>
22
+ </div>
@@ -0,0 +1,10 @@
1
+ <% current = request.path[plugin.nav_url] %>
2
+ <a href="<%= plugin.nav_url %>" class="flex items-center mb-3 <%= current ? "text-blue-700" : "text-gray-600" %> hover:text-blue-700">
3
+ <div class="">
4
+ <%= plugin.nav_svg %>
5
+ </div>
6
+ <div class='ml-2'>
7
+ <%= plugin.nav_title %>
8
+ </div>
9
+ </a>
10
+
@@ -0,0 +1,18 @@
1
+ <% @statistics.each do |row| %>
2
+ <h2 class="text-xl text-blue-900 flex items-center "><%= row.first[:plugin].nav_svg %> <span class="ml-2"><%= row.first[:plugin].nav_title %></span></h2>
3
+ <div class="flex -mx-2 mt-2 flex-wrap mb-10">
4
+ <% row.each do |statistic| %>
5
+ <% if statistic[:error] %>
6
+ <div class="w-1/4 rounded-lg shadow-lg bg-red-500 text-red-100 py-2 px-4 m-2">
7
+ <div class="text-5xl"><%= statistic[:value] %></div>
8
+ <div class="text-sm text-red-300"><%= statistic[:label] %></div>
9
+ </div>
10
+ <% else %>
11
+ <div class="w-1/4 rounded-lg shadow-lg bg-green-500 text-green-100 py-2 px-4 m-2">
12
+ <div class="text-5xl"><%= statistic[:value] %></div>
13
+ <div class="text-sm text-green-300"><%= statistic[:label] %></div>
14
+ </div>
15
+ <% end %>
16
+ <% end -%>
17
+ </div>
18
+ <% end -%>
@@ -0,0 +1,44 @@
1
+ <div class="flex w-full justify-between items-center">
2
+ <h1 class="text-xl text-blue-900 flex-1">Exceptions</h1>
3
+ <form action="<%= ActiveTracker::Configuration.root_path + "/exceptions" %>" method="get" class="js-filter-form">
4
+ <input type='text' name="q" class="bg-gray-100 border-2 border-gray-400 px-2 py-1 rounded-lg js-filter-input" placeholder="Search for request" value="<%= params[:q] %>">
5
+ </form>
6
+ </div>
7
+
8
+ <% if @exceptions && @exceptions.any? %>
9
+ <div class="bg-white shadow mt-4 rounded-b-lg" style="">
10
+ <div class="bg-gray-200 text-gray-600 uppercase tracking-tight leading-none py-2 px-4 flex flex-grow">
11
+ <div class="flex-1">Class / Message</div>
12
+ <div class="w-24 text-center">Count</div>
13
+ <div class="w-32 text-right">Last raised</div>
14
+ </div>
15
+
16
+ <% @exceptions.each do |exception| %>
17
+ <% actual_exception = ActiveTracker::Model.find(exception.key) %>
18
+ <% border_size = @exceptions.last == exception ? "none" : "2" %>
19
+ <a href='<%= ActiveTracker::Configuration.root_path + "/exceptions/#{exception.id}" %>' class="flex flex-grow border-b-<%= border_size %> border-gray-200 text-gray-600 px-4 text-sm py-6 items-center">
20
+ <div class="flex-1 break-all">
21
+ <div class="font-mono text-sm text-gray-800"><%= actual_exception.tags[:class_name] %></div>
22
+ <div class=""><%= actual_exception.message %></div>
23
+ <% if actual_exception.backtrace.present? %>
24
+ <div class="bg-gray-200 text-gray-900 py-1 px-2 text-xs rounded no-wrap mt-1 inline-block"><%= actual_exception.backtrace.first %></div>
25
+ <% end %>
26
+ </div>
27
+ <% if actual_exception.count < 10 %>
28
+ <div class="w-24 text-center"><span class="bg-green-100 text-green-600 rounded-full px-3 py-2 font-bold"><%= actual_exception.count %></span></div>
29
+ <% elsif actual_exception.count < 40 %>
30
+ <div class="w-24 text-center"><span class="bg-yellow-100 text-yellow-700 rounded-full px-3 py-2 font-bold"><%= actual_exception.count %></span></div>
31
+ <% elsif actual_exception.count < 100 %>
32
+ <div class="w-24 text-center"><span class="bg-orange-200 text-orange-700 rounded-full px-3 py-2 font-bold"><%= actual_exception.count %></span></div>
33
+ <% else %>
34
+ <div class="w-24 text-center"><span class="bg-red-300 text-red-800 rounded-full px-3 py-2 font-bold"><%= actual_exception.count %></span></div>
35
+ <% end %>
36
+ <div class="w-32 text-right"><%= time_ago_in_words actual_exception.log_at %> ago</div>
37
+ </a>
38
+ <% end -%>
39
+ </div>
40
+
41
+ <%= render "active_tracker/common/pagination", pagination: @pagination, url: request.fullpath, duration: @duration %>
42
+ <% else %>
43
+ <%= render "active_tracker/common/empty", plural_type: "exceptions" %>
44
+ <% end %>
@@ -0,0 +1,56 @@
1
+ <div class="flex w-full justify-between items-center">
2
+ <h1 class="text-xl text-blue-900 flex-1">Exception</h1>
3
+ </div>
4
+
5
+ <div class="flex flex-grow mt-10 items-center">
6
+ <div class="rounded-lg bg-white text-sm text-gray-600 flex-1">
7
+ <div class="flex flex-grow items-center">
8
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">Class</div>
9
+ <div class="pl-4 font-mono"><%= @exception.tags[:class_name] %></div>
10
+ </div>
11
+ <div class="flex flex-grow items-center text-gray-600">
12
+ <div class="bg-gray-200 uppercase w-32 p-4">Message</div>
13
+ <div class="ml-4 block mt-1 inline-block"><%= @exception.message %></div>
14
+ </div>
15
+ <div class="flex flex-grow items-center">
16
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">Count</div>
17
+ <div class="pl-4">
18
+ <% if @exception.count < 10 %>
19
+ <div class="w-24"><span class="bg-green-100 text-green-600 rounded-full px-3 py-2 font-bold"><%= @exception.count %></span></div>
20
+ <% elsif @exception.count < 40 %>
21
+ <div class="w-24"><span class="bg-yellow-100 text-yellow-600 rounded-full px-3 py-2 font-bold"><%= @exception.count %></span></div>
22
+ <% elsif @exception.count < 100 %>
23
+ <div class="w-24"><span class="bg-orange-200 text-orange-700 rounded-full px-3 py-2 font-bold"><%= @exception.count %></span></div>
24
+ <% else %>
25
+ <div class="w-24"><span class="bg-red-300 text-red-800 rounded-full px-3 py-2 font-bold"><%= @exception.count %></span></div>
26
+ <% end %>
27
+ </div>
28
+ </div>
29
+ <div class="flex flex-grow items-center">
30
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">Last raised</div>
31
+ <div class="pl-4"><%= time_ago_in_words @exception.log_at %> ago</div>
32
+ </div>
33
+ </div>
34
+ </div>
35
+
36
+ <div class="mt-10 flex-grow-0">
37
+ <div>
38
+ <a href="#" class="text-lg mr-3 text-blue-600 js-activetracker-tab" data-tab="backtrace">Backtrace</a>
39
+ </div>
40
+
41
+ <div class="bg-black text-white font-mono whitespace-pre-wrap text-sm rounded-lg mt-2 p-4 overflow-x-auto js-activetracker-tab-content" data-content="backtrace"><%= @exception.backtrace.join("<div class='mb-2'></div>").html_safe %></div>
42
+ </div>
43
+
44
+
45
+ <div class="bg-white shadow mt-10 rounded-b-lg" style="">
46
+ <div class="bg-gray-200 text-gray-600 uppercase tracking-tight leading-none py-2 px-4 flex flex-grow">
47
+ <div class="w-24">Method</div>
48
+ <div class="flex-1">Path</div>
49
+ <div class="w-24">Response</div>
50
+ <div class="w-32 text-right">Time</div>
51
+ </div>
52
+
53
+ <% @requests.each do |request| %>
54
+ <%= render "active_tracker/requests/request", request: request %>
55
+ <% end -%>
56
+ </div>
@@ -0,0 +1,38 @@
1
+ <div class="flex w-full justify-between items-center">
2
+ <h1 class="text-xl text-blue-900 flex-1">Queries</h1>
3
+ <form action="<%= ActiveTracker::Configuration.root_path + "/queries" %>" method="get" class="js-filter-form">
4
+ <input type='text' name="q" class="bg-gray-100 border-2 border-gray-400 px-2 py-1 rounded-lg js-filter-input" placeholder="Search for request" value="<%= params[:q] %>">
5
+ </form>
6
+ </div>
7
+
8
+ <% if @queries && @queries.any? %>
9
+ <div class="bg-white shadow mt-4 rounded-b-lg" style="">
10
+ <div class="bg-gray-200 text-gray-600 uppercase tracking-tight leading-none py-2 px-4 flex flex-grow">
11
+ <div class="flex-1">SQL</div>
12
+ <div class="w-24 text-right">Count</div>
13
+ <div class="w-32 text-right">Last response</div>
14
+ </div>
15
+
16
+ <% @queries.each do |query| %>
17
+ <% actual_query = ActiveTracker::Model.find(query.key) %>
18
+ <% border_size = @queries.last == query ? "none" : "2" %>
19
+ <a href='<%= ActiveTracker::Configuration.root_path + "/queries/#{query.id}" %>' class="flex flex-grow border-b-<%= border_size %> border-gray-200 text-gray-600 px-4 text-sm py-6 items-center">
20
+ <div class="flex-1 break-all font-mono"><%= actual_query.tags[:sql] %>
21
+ <% if actual_query.tags[:name].present? %>
22
+ <br /><div class="block bg-gray-200 text-gray-900 py-1 px-2 text-xs rounded no-wrap mt-1 inline-block"><%= actual_query.tags[:name] %></div>
23
+ <% end %>
24
+ </div>
25
+ <div class="w-24 text-right"><%= actual_query.count %></div>
26
+ <% if actual_query.last_duration > ActiveTracker::Plugin::Query.min_slow_duration_ms %>
27
+ <div class="w-32 text-center text-red-600"><%= "%.1f" % actual_query.last_duration %>ms</div>
28
+ <% else %>
29
+ <div class="w-32 text-center"><%= "%.1f" % actual_query.last_duration %>ms</div>
30
+ <% end %>
31
+ </a>
32
+ <% end -%>
33
+ </div>
34
+
35
+ <%= render "active_tracker/common/pagination", pagination: @pagination, url: request.fullpath, duration: @duration %>
36
+ <% else %>
37
+ <%= render "active_tracker/common/empty", plural_type: "queries" %>
38
+ <% end %>
@@ -0,0 +1,39 @@
1
+ <div class="flex w-full justify-between items-center">
2
+ <h1 class="text-xl text-blue-900 flex-1">Query</h1>
3
+ </div>
4
+
5
+ <div class="flex flex-grow mt-10 items-center">
6
+ <div class="rounded-lg bg-white text-sm text-gray-600 flex-1">
7
+ <div class="flex flex-grow items-center">
8
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">SQL</div>
9
+ <div class="pl-4 font-mono"><%= @query.tags[:sql] %></div>
10
+ </div>
11
+ <div class="flex flex-grow items-center">
12
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">Name</div>
13
+ <% if @query.tags[:name].present? %>
14
+ <div class="ml-4 block bg-gray-200 text-gray-900 py-1 px-2 text-xs rounded no-wrap mt-1 inline-block"><%= @query.tags[:name] %></div>
15
+ <% end %>
16
+ </div>
17
+ <div class="flex flex-grow items-center">
18
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">Count</div>
19
+ <div class="pl-4"><%= @query.count %></div>
20
+ </div>
21
+ <div class="flex flex-grow items-center">
22
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">Duration</div>
23
+ <div class="pl-4"><%= "%.1f" % @query.last_duration %>ms</div>
24
+ </div>
25
+ </div>
26
+ </div>
27
+
28
+ <div class="bg-white shadow mt-4 rounded-b-lg" style="">
29
+ <div class="bg-gray-200 text-gray-600 uppercase tracking-tight leading-none py-2 px-4 flex flex-grow">
30
+ <div class="w-24">Method</div>
31
+ <div class="flex-1">Path</div>
32
+ <div class="w-24">Response</div>
33
+ <div class="w-32 text-right">Time</div>
34
+ </div>
35
+
36
+ <% @requests.each do |request| %>
37
+ <%= render "active_tracker/requests/request", request: request %>
38
+ <% end -%>
39
+ </div>
@@ -0,0 +1,30 @@
1
+ <% border_size = @requests.last == request ? "none" : "2" %>
2
+ <a href='<%= ActiveTracker::Configuration.root_path + "/requests/#{request.id}" %>' class="flex flex-grow border-b-<%= border_size %> border-gray-200 text-gray-600 px-4 text-sm py-6 items-center">
3
+ <div class="w-24"><span class="bg-gray-200 text-gray-600 rounded-full px-3 py-2 font-bold"><%= request.tags[:method] %></span></div>
4
+ <div class="flex-1 break-all"><%= request.tags[:url] %>
5
+ <% showable_tags = request.tags.keys.reject {|k| ["url", "method", "duration", "user_avatar_url", "params", /\Aat_.*/].any? {|r| k.to_s.match(r) } } %>
6
+ <% if showable_tags.any? %>
7
+ <div class="js-tags">
8
+ <% showable_tags.each do |k| %>
9
+ <span class="bg-gray-200 text-gray-900 py-1 px-2 text-xs rounded no-wrap mt-1 inline-block"><%= "#{k}:#{request.tags[k]}" %></span>
10
+ <% end %>
11
+ </div>
12
+ <% end %>
13
+ <!--
14
+ TODO: make these links that further filters the results
15
+ -->
16
+ </div>
17
+ <% if request.tags[:status].start_with?("2") %>
18
+ <div class="w-24"><span class="bg-green-100 text-green-600 rounded-full px-3 py-2 font-bold"><%= request.tags[:status] %></span></div>
19
+ <% elsif request.tags[:status].start_with?("3") %>
20
+ <div class="w-24"><span class="bg-yellow-100 text-yellow-600 rounded-full px-3 py-2 font-bold"><%= request.tags[:status] %></span></div>
21
+ <% elsif request.tags[:status].start_with?("4") %>
22
+ <div class="w-24"><span class="bg-orange-200 text-orange-700 rounded-full px-3 py-2 font-bold"><%= request.tags[:status] %></span></div>
23
+ <% elsif request.tags[:status].start_with?("5") %>
24
+ <div class="w-24"><span class="bg-red-300 text-red-800 rounded-full px-3 py-2 font-bold"><%= request.tags[:status] %></span></div>
25
+ <% end %>
26
+ <div class="w-32 text-center">
27
+ <b class="block"><%= request.tags[:duration] %></b>
28
+ <%= time_ago_in_words request.log_at %> ago
29
+ </div>
30
+ </a>
@@ -0,0 +1,26 @@
1
+ <div class="flex w-full justify-between items-center">
2
+ <h1 class="text-xl text-blue-900 flex-1">Requests</h1>
3
+ <form action="<%= ActiveTracker::Configuration.root_path + "/requests" %>" method="get" class="js-filter-form">
4
+ <input type='text' name="q" class="bg-gray-100 border-2 border-gray-400 px-2 py-1 rounded-lg js-filter-input" placeholder="Search for request" value="<%= params[:q] %>">
5
+ </form>
6
+ </div>
7
+
8
+ <% if @requests && @requests.any? %>
9
+ <div class="bg-white shadow mt-4 rounded-b-lg" style="">
10
+ <div class="bg-gray-200 text-gray-600 uppercase tracking-tight leading-none py-2 px-4 flex flex-grow">
11
+ <div class="w-24">Method</div>
12
+ <div class="flex-1">Path</div>
13
+ <div class="w-24">Response</div>
14
+ <div class="w-32 text-right">Time</div>
15
+ </div>
16
+
17
+ <% @requests.each do |request| %>
18
+ <%= render "active_tracker/requests/request", request: request %>
19
+ <% end -%>
20
+
21
+ </div>
22
+
23
+ <%= render "active_tracker/common/pagination", pagination: @pagination, url: request.fullpath, duration: @duration %>
24
+ <% else %>
25
+ <%= render "active_tracker/common/empty", plural_type: "requests" %>
26
+ <% end %>
@@ -0,0 +1,81 @@
1
+ <div class="flex w-full justify-between items-center">
2
+ <h1 class="text-xl text-blue-900 flex-1">Request</h1>
3
+ </div>
4
+
5
+ <div class="flex flex-grow mt-10 items-center">
6
+ <div class="rounded-lg bg-white text-sm text-gray-600 flex-1">
7
+ <div class="flex flex-grow items-center">
8
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">Method</div>
9
+ <div class="pl-4"><span class="bg-gray-200 text-gray-600 rounded-full px-2 py-1 text-sm font-bold"><%= @request.tags[:method] %></span></div>
10
+ </div>
11
+ <div class="flex flex-grow items-center">
12
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">Path</div>
13
+ <div class="pl-4"><%= @request.tags[:url] %></div>
14
+ </div>
15
+ <div class="flex flex-grow items-center">
16
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">Status</div>
17
+ <% if @request.tags[:status].start_with?("2") %>
18
+ <div class="pl-4"><span class="bg-green-100 text-green-600 rounded-full px-2 py-1 text-sm font-bold"><%= @request.tags[:status] %></span></div>
19
+ <% elsif @request.tags[:status].start_with?("3") %>
20
+ <div class="pl-4"><span class="bg-yellow-100 text-yellow-600 rounded-full px-2 py-1 text-sm font-bold"><%= @request.tags[:status] %></span></div>
21
+ <% elsif @request.tags[:status].start_with?("4") %>
22
+ <div class="pl-4"><span class="bg-orange-100 text-orange-600 rounded-full px-2 py-1 text-sm font-bold"><%= @request.tags[:status] %></span></div>
23
+ <% elsif @request.tags[:status].start_with?("5") %>
24
+ <div class="pl-4"><span class="bg-red-100 text-red-600 rounded-full px-2 py-1 text-sm font-bold"><%= @request.tags[:status] %></span></div>
25
+ <% end %>
26
+ </div>
27
+ <div class="flex flex-grow items-center">
28
+ <div class="bg-gray-200 text-gray-600 uppercase w-32 p-4">When</div>
29
+ <div class="pl-4"><%= time_ago_in_words @request.log_at %> ago</div>
30
+ </div>
31
+ </div>
32
+
33
+ <% if @request.tags[:user_avatar_url] || @request.tags[:user_name] || @request.tags[:user_email] %>
34
+ <div class="ml-8 text-center">
35
+ <% if @request.tags[:user_avatar_url] %>
36
+ <%= image_tag @request.tags[:user_avatar_url], class:"w-20 h-20 object-cover rounded-full inline-block border-2 border-gray-500" %>
37
+ <% end %>
38
+ <% if @request.tags[:user_name] %>
39
+ <h2 class="text-lg text-blue-900"><%= @request.tags[:user_name] %></h2>
40
+ <% end %>
41
+ <% if @request.tags[:user_email] %>
42
+ <a href="mailto:<%= @request.tags[:user_email] %>" class="text-sm text-blue-600 hover:text-blue-600 hover:underline"><%= @request.tags[:user_email] %></a>
43
+ <% end %>
44
+ </div>
45
+ <% end %>
46
+ </div>
47
+
48
+ <div class="mt-10 flex-grow-0">
49
+ <div>
50
+ <a href="#" class="text-lg mr-3 text-blue-600 js-activetracker-tab" data-tab="logs">Logs</a>
51
+ <a href="#" class="text-lg mr-3 text-gray-500 js-activetracker-tab" data-tab="response">Response</a>
52
+ <% if ActiveTracker::Plugin::Query.registered? && @queries.any? %>
53
+ <a href="#" class="text-lg mr-3 text-gray-500 js-activetracker-tab" data-tab="queries">Queries</a>
54
+ <% end %>
55
+ </div>
56
+
57
+ <div class="bg-black text-white font-mono whitespace-pre-wrap text-sm rounded-lg mt-2 p-4 overflow-x-auto js-activetracker-tab-content" data-content="logs"><%= escape_ansi @request.log.strip %></div>
58
+ <div class="bg-black text-white font-mono whitespace-pre-wrap text-sm rounded-lg mt-2 p-4 overflow-x-auto js-activetracker-tab-content hidden" data-content="response"><%= @request.output.strip %></div>
59
+ <div class="bg-white rounded-b-lg mt-2 overflow-x-auto js-activetracker-tab-content hidden" data-content="queries">
60
+ <div class="bg-gray-200 text-gray-600 uppercase tracking-tight leading-none py-2 px-4 flex flex-grow">
61
+ <div class="flex-1">SQL</div>
62
+ <div class="w-24 text-right">Count</div>
63
+ <div class="w-32 text-right">Last response</div>
64
+ </div>
65
+
66
+ <% @queries.each do |query| %>
67
+ <% actual_query = ActiveTracker::Model.find(query.key) %>
68
+ <% border_size = @queries.last == query ? "none" : "2" %>
69
+ <a href='<%= ActiveTracker::Configuration.root_path + "/queries/#{query.id}" %>' class="flex flex-grow border-b-<%= border_size %> border-gray-200 text-gray-600 px-4 text-sm py-6 items-center">
70
+ <div class="flex-1 break-all font-mono"><%= actual_query.tags[:sql] %>
71
+ <% if actual_query.tags[:name].present? %>
72
+ <br /><div class="block bg-gray-200 text-gray-900 py-1 px-2 text-xs rounded no-wrap mt-1 inline-block"><%= actual_query.tags[:name] %></div>
73
+ <% end %>
74
+ </div>
75
+ <div class="w-24 text-right"><%= actual_query.count %></div>
76
+ <div class="w-32 text-center"><%= "%.1f" % actual_query.last_duration %>ms</div>
77
+ </a>
78
+ <% end -%>
79
+ </div>
80
+
81
+ </div>
@@ -0,0 +1,46 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>ActiveTracker</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag rescue nil %>
7
+
8
+ <%= stylesheet_link_tag 'active_tracker/active_tracker', media: 'all' %>
9
+ <%= javascript_include_tag 'active_tracker/active_tracker' %>
10
+ </head>
11
+
12
+ <body class="bg-gray-300 p-3 pb-10">
13
+ <div class="container mx-auto">
14
+ <header class="border-b-2 border-gray-400 flex justify-between w-full pb-3 items-center">
15
+ <div class="">
16
+ <%= link_to image_tag("active_tracker/logo.svg"), ActiveTracker::Configuration.root_path %>
17
+ </div>
18
+ <div class="text-right">
19
+ <% if ActiveTracker.connection_offline? %>
20
+ <div class="text-red-700 inline-block flex flex-0 align-middle">
21
+ <div class="w-6 h-6 mr-2">
22
+ <svg aria-hidden="true" class="fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/></svg>
23
+ </div>
24
+ <span>Redis Offline</span>
25
+ </div>
26
+ <% end %>
27
+ </div>
28
+ </header>
29
+
30
+ <div class="mt-5 flex">
31
+ <nav class='w-48 mt-1 mr-8'>
32
+ <% ActiveTracker::Configuration.plugins.each do |plugin| %>
33
+ <%= render "active_tracker/common/plugin_nav", plugin: plugin %>
34
+ <% end -%>
35
+ </nav>
36
+ <article class="flex-1 min-w-0">
37
+ <%= yield %>
38
+ </article>
39
+ </div>
40
+ </div>
41
+
42
+ <div class="container mx-auto text-sm text-gray-600 text-center mt-6 pt-3 border-t-2 border-gray-400">
43
+ ActionTracker is an <%= link_to "open-source project", "https://github.com/civo/activetracker", class:"text-blue-600" %> from <%= link_to "Civo", "https://www.civo.com", class:"text-blue-600" %>.<br />Released under the MIT licence, but copyright &copy; 2019 Civo Ltd and the ActionTracker contributors.
44
+ </div>
45
+ </body>
46
+ </html>