activetracker 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +160 -0
- data/LICENSE.txt +21 -0
- data/README.md +399 -0
- data/Rakefile +21 -0
- data/THOUGHTS.md +50 -0
- data/activetracker.gemspec +49 -0
- data/app/assets/config/active_tracker_manifest.js +4 -0
- data/app/assets/images/active_tracker/.keep +0 -0
- data/app/assets/images/active_tracker/logo.svg +6 -0
- data/app/assets/images/active_tracker/reload.svg +10 -0
- data/app/assets/javascripts/active_tracker/active_tracker.js +15 -0
- data/app/assets/javascripts/active_tracker/tabs.js +12 -0
- data/app/assets/javascripts/active_tracker/tags.js +18 -0
- data/app/assets/javascripts/active_tracker/zepto.js +2 -0
- data/app/assets/stylesheets/active_tracker/active_tracker.css.scss +21 -0
- data/app/assets/stylesheets/active_tracker/tailwind.min.scss +1 -0
- data/app/controllers/active_tracker/base_controller.rb +22 -0
- data/app/controllers/active_tracker/dashboard_controller.rb +10 -0
- data/app/controllers/active_tracker/exceptions_controller.rb +41 -0
- data/app/controllers/active_tracker/queries_controller.rb +39 -0
- data/app/controllers/active_tracker/requests_controller.rb +41 -0
- data/app/helpers/active_tracker/application_helper.rb +4 -0
- data/app/helpers/active_tracker/images_helper.rb +8 -0
- data/app/helpers/active_tracker/output_helper.rb +35 -0
- data/app/helpers/active_tracker/pagination_helper.rb +16 -0
- data/app/jobs/active_tracker/application_job.rb +4 -0
- data/app/mailers/active_tracker/application_mailer.rb +6 -0
- data/app/models/active_tracker/application_record.rb +5 -0
- data/app/views/active_tracker/common/_empty.html.erb +9 -0
- data/app/views/active_tracker/common/_pagination.html.erb +22 -0
- data/app/views/active_tracker/common/_plugin_nav.html.erb +10 -0
- data/app/views/active_tracker/dashboard/index.html.erb +18 -0
- data/app/views/active_tracker/exceptions/index.html.erb +44 -0
- data/app/views/active_tracker/exceptions/show.html.erb +56 -0
- data/app/views/active_tracker/queries/index.html.erb +38 -0
- data/app/views/active_tracker/queries/show.html.erb +39 -0
- data/app/views/active_tracker/requests/_request.html.erb +30 -0
- data/app/views/active_tracker/requests/index.html.erb +26 -0
- data/app/views/active_tracker/requests/show.html.erb +81 -0
- data/app/views/layouts/active_tracker/active_tracker.html.erb +46 -0
- data/bin/console +14 -0
- data/bin/rails +25 -0
- data/bin/setup +8 -0
- data/doc/logo.md +11 -0
- data/integration/generators/installer.rb +7 -0
- data/integration/templates/initializer.rb +32 -0
- data/lib/active_tracker.rb +41 -0
- data/lib/active_tracker/configuration.rb +67 -0
- data/lib/active_tracker/engine.rb +24 -0
- data/lib/active_tracker/exception_capturer.rb +38 -0
- data/lib/active_tracker/model.rb +153 -0
- data/lib/active_tracker/output_capturer.rb +37 -0
- data/lib/active_tracker/plugin.rb +4 -0
- data/lib/active_tracker/plugin/base.rb +9 -0
- data/lib/active_tracker/plugin/exception.rb +113 -0
- data/lib/active_tracker/plugin/query.rb +128 -0
- data/lib/active_tracker/plugin/request.rb +163 -0
- data/lib/active_tracker/rails_logger.rb +120 -0
- data/lib/active_tracker/router.rb +16 -0
- data/lib/active_tracker/version.rb +3 -0
- data/lib/activetracker.rb +3 -0
- data/lib/tasks/active_tracker_tasks.rake +12 -0
- data/spec/activetracker_spec.rb +36 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/javascript/packs/application.js +15 -0
- data/spec/dummy/app/jobs/application_job.rb +7 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +33 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +37 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +54 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +62 -0
- data/spec/dummy/config/environments/production.rb +107 -0
- data/spec/dummy/config/environments/test.rb +48 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +12 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/disable_remote_forms.rb +1 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +38 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/lib/active_tracker/model_spec.rb +38 -0
- data/spec/spec_helper.rb +18 -0
- metadata +348 -0
@@ -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 © 2019 Civo Ltd and the ActionTracker contributors.
|
44
|
+
</div>
|
45
|
+
</body>
|
46
|
+
</html>
|