simple_apm 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +43 -31
- data/app/assets/javascripts/simple_apm/application.js +94 -0
- data/app/assets/stylesheets/simple_apm/application.css +130 -6
- data/app/controllers/simple_apm/apm_controller.rb +33 -17
- data/app/controllers/simple_apm/application_controller.rb +15 -1
- data/app/helpers/simple_apm/application_helper.rb +24 -0
- data/app/models/simple_apm/action.rb +5 -5
- data/app/models/simple_apm/diagnostic_report.rb +203 -0
- data/app/models/simple_apm/sql.rb +1 -1
- data/app/views/layouts/simple_apm/application.html.erb +65 -61
- data/app/views/simple_apm/apm/_diagnostic_export.html.erb +17 -0
- data/app/views/simple_apm/apm/_timings.html.erb +18 -0
- data/app/views/simple_apm/apm/action_info.html.erb +50 -29
- data/app/views/simple_apm/apm/actions.html.erb +44 -25
- data/app/views/simple_apm/apm/dashboard.html.erb +54 -35
- data/app/views/simple_apm/apm/data.html.erb +69 -25
- data/app/views/simple_apm/apm/index.html.erb +49 -21
- data/app/views/simple_apm/apm/missing.html.erb +8 -0
- data/app/views/simple_apm/apm/show.html.erb +69 -44
- data/config/locales/simple_apm.en.yml +200 -0
- data/config/locales/simple_apm.zh-CN.yml +200 -0
- data/config/routes.rb +2 -1
- data/lib/simple_apm/version.rb +1 -1
- data/lib/simple_apm/worker.rb +4 -1
- metadata +7 -1
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
<div class="apm-page-header">
|
|
2
2
|
<div>
|
|
3
|
-
<h1 class="apm-page-title"
|
|
4
|
-
<p class="apm-page-subtitle"
|
|
3
|
+
<h1 class="apm-page-title"><%= t("simple_apm.actions.title") %></h1>
|
|
4
|
+
<p class="apm-page-subtitle"><%= t("simple_apm.actions.subtitle") %></p>
|
|
5
|
+
</div>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<% total_hits = @actions.sum { |action| action.click_count.to_i } %>
|
|
9
|
+
<div class="apm-metrics apm-metrics-compact">
|
|
10
|
+
<div class="apm-stat">
|
|
11
|
+
<p class="apm-stat-label"><%= t("simple_apm.actions.action_count") %></p>
|
|
12
|
+
<div class="apm-stat-value"><%= number_with_delimiter(@actions.length) %></div>
|
|
13
|
+
<div class="apm-stat-meta"><%= apm_date %></div>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="apm-stat">
|
|
16
|
+
<p class="apm-stat-label"><%= t("simple_apm.actions.total_hits") %></p>
|
|
17
|
+
<div class="apm-stat-value"><%= number_with_delimiter(total_hits) %></div>
|
|
18
|
+
<div class="apm-stat-meta"><%= t("simple_apm.dashboard.current_day_total") %></div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="apm-stat">
|
|
21
|
+
<p class="apm-stat-label"><%= t("simple_apm.actions.weighted_avg_response") %></p>
|
|
22
|
+
<div class="apm-stat-value"><%= total_hits.positive? ? sec_str(@actions.sum { |action| action.time.to_f } / total_hits) : '—' %></div>
|
|
23
|
+
<div class="apm-stat-meta"><%= t("simple_apm.actions.summary_hint") %></div>
|
|
5
24
|
</div>
|
|
6
25
|
</div>
|
|
7
26
|
|
|
8
27
|
<section class="apm-panel">
|
|
9
28
|
<div class="apm-panel-header">
|
|
10
29
|
<div>
|
|
11
|
-
<h2 class="apm-panel-title"
|
|
12
|
-
<p class="apm-panel-subtitle"
|
|
30
|
+
<h2 class="apm-panel-title"><%= t("simple_apm.actions.list_title") %></h2>
|
|
31
|
+
<p class="apm-panel-subtitle"><%= t("simple_apm.actions.list_subtitle") %></p>
|
|
13
32
|
</div>
|
|
14
33
|
</div>
|
|
15
34
|
<div class="apm-panel-body">
|
|
@@ -17,27 +36,28 @@
|
|
|
17
36
|
<table id="actions-table" class="table">
|
|
18
37
|
<thead>
|
|
19
38
|
<tr>
|
|
20
|
-
<th
|
|
21
|
-
<th
|
|
22
|
-
<th
|
|
23
|
-
<th
|
|
24
|
-
<th
|
|
25
|
-
<th
|
|
26
|
-
<th
|
|
27
|
-
<th
|
|
39
|
+
<th scope="col"><%= t("simple_apm.actions.name") %></th>
|
|
40
|
+
<th scope="col"><%= t("simple_apm.actions.click_count") %></th>
|
|
41
|
+
<th scope="col"><%= t("simple_apm.actions.avg_response_time") %></th>
|
|
42
|
+
<th scope="col"><%= t("simple_apm.actions.avg_db_time") %></th>
|
|
43
|
+
<th scope="col"><%= t("simple_apm.actions.avg_sql_count") %></th>
|
|
44
|
+
<th scope="col"><%= t("simple_apm.actions.avg_http_time") %></th>
|
|
45
|
+
<th scope="col"><%= t("simple_apm.actions.fastest_response_time") %></th>
|
|
46
|
+
<th scope="col"><%= t("simple_apm.actions.slowest_response_time") %></th>
|
|
28
47
|
</tr>
|
|
29
48
|
</thead>
|
|
30
49
|
<tbody>
|
|
31
50
|
<% @actions.each do |action| %>
|
|
51
|
+
<% has_hits = action.click_count.to_i.positive? %>
|
|
32
52
|
<tr>
|
|
33
|
-
<td><%= link_to action.name, action_info_path(action_name: action.name) %></td>
|
|
34
|
-
<td><%= action.click_count %></td>
|
|
35
|
-
<td><%= sec_str
|
|
36
|
-
<td><%= sec_str
|
|
37
|
-
<td><%= action.avg_queries_count.round(1) %></td>
|
|
38
|
-
<td><%= sec_str
|
|
39
|
-
<td><%= link_to
|
|
40
|
-
<td><%= link_to
|
|
53
|
+
<td class="apm-mono"><%= link_to action.name, action_info_path(action_name: action.name, apm_date: apm_date) %></td>
|
|
54
|
+
<td data-order="<%= action.click_count.to_i %>"><%= number_with_delimiter(action.click_count.to_i) %></td>
|
|
55
|
+
<td data-order="<%= has_hits ? action.avg_time : 0 %>"><%= has_hits ? sec_str(action.avg_time) : '—' %></td>
|
|
56
|
+
<td data-order="<%= has_hits ? action.avg_db_time : 0 %>"><%= has_hits ? sec_str(action.avg_db_time) : '—' %></td>
|
|
57
|
+
<td data-order="<%= has_hits ? action.avg_queries_count : 0 %>"><%= has_hits ? action.avg_queries_count.round(1) : '—' %></td>
|
|
58
|
+
<td data-order="<%= has_hits ? action.avg_http_time : 0 %>"><%= has_hits ? sec_str(action.avg_http_time) : '—' %></td>
|
|
59
|
+
<td data-order="<%= action.fast_time.to_f %>"><%= action.fast_id.present? ? link_to(sec_str(action.fast_time), show_path(id: action.fast_id, apm_date: apm_date)) : '—' %></td>
|
|
60
|
+
<td data-order="<%= action.slow_time.to_f %>"><%= action.slow_id.present? ? link_to(sec_str(action.slow_time), show_path(id: action.slow_id, apm_date: apm_date)) : '—' %></td>
|
|
41
61
|
</tr>
|
|
42
62
|
<% end %>
|
|
43
63
|
</tbody>
|
|
@@ -47,11 +67,10 @@
|
|
|
47
67
|
</section>
|
|
48
68
|
<script type="text/javascript">
|
|
49
69
|
$(document).ready(function(){
|
|
50
|
-
$('#actions-table').DataTable({
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
})
|
|
70
|
+
$('#actions-table').DataTable(window.SimpleApmUI.tableOptions({
|
|
71
|
+
order: [[2, 'desc']],
|
|
72
|
+
columnDefs: [{type: 'num', targets: [1, 2, 3, 4, 5, 6, 7]}]
|
|
73
|
+
}))
|
|
55
74
|
|
|
56
75
|
})
|
|
57
76
|
</script>
|
|
@@ -1,76 +1,91 @@
|
|
|
1
1
|
<div class="apm-page-header">
|
|
2
2
|
<div>
|
|
3
|
-
<h1 class="apm-page-title"
|
|
4
|
-
<p class="apm-page-subtitle"
|
|
3
|
+
<h1 class="apm-page-title"><%= t("simple_apm.dashboard.title") %></h1>
|
|
4
|
+
<p class="apm-page-subtitle"><%= t("simple_apm.dashboard.subtitle") %></p>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="apm-toolbar-actions">
|
|
7
|
+
<%= link_to t("simple_apm.layout.nav_actions"), actions_path(apm_date: apm_date), class: 'btn apm-button-secondary' %>
|
|
8
|
+
<%= link_to t("simple_apm.layout.nav_slow_requests"), index_path(apm_date: apm_date), class: 'btn btn-primary' %>
|
|
5
9
|
</div>
|
|
6
10
|
</div>
|
|
7
11
|
|
|
8
12
|
<div class="apm-metrics">
|
|
9
13
|
<div class="apm-stat">
|
|
10
|
-
<p class="apm-stat-label"
|
|
11
|
-
<div class="apm-stat-value"><%= @
|
|
12
|
-
<div class="apm-stat-meta"
|
|
14
|
+
<p class="apm-stat-label"><%= t("simple_apm.dashboard.daily_avg_response") %></p>
|
|
15
|
+
<div class="apm-stat-value"><%= @daily_stats[:hits].positive? ? sec_str(@daily_stats[:avg_time]) : '—' %></div>
|
|
16
|
+
<div class="apm-stat-meta"><%= t("simple_apm.dashboard.weighted_daily_average") %></div>
|
|
13
17
|
</div>
|
|
14
18
|
<div class="apm-stat">
|
|
15
|
-
<p class="apm-stat-label"
|
|
16
|
-
<div class="apm-stat-value"><%= @
|
|
17
|
-
<div class="apm-stat-meta"
|
|
19
|
+
<p class="apm-stat-label"><%= t("simple_apm.dashboard.hits") %></p>
|
|
20
|
+
<div class="apm-stat-value"><%= number_with_delimiter(@daily_stats[:hits]) %></div>
|
|
21
|
+
<div class="apm-stat-meta"><%= t("simple_apm.dashboard.current_day_total") %></div>
|
|
18
22
|
</div>
|
|
19
23
|
<div class="apm-stat">
|
|
20
|
-
<p class="apm-stat-label"
|
|
21
|
-
<div class="apm-stat-value"><%= sec_str(@time_arr.map(&:to_f).max.to_f) %></div>
|
|
22
|
-
<div class="apm-stat-meta"
|
|
24
|
+
<p class="apm-stat-label"><%= t("simple_apm.dashboard.peak_avg_response") %></p>
|
|
25
|
+
<div class="apm-stat-value"><%= @daily_stats[:hits].positive? ? sec_str(@time_arr.map(&:to_f).max.to_f) : '—' %></div>
|
|
26
|
+
<div class="apm-stat-meta"><%= t("simple_apm.dashboard.interval_peak") %></div>
|
|
23
27
|
</div>
|
|
24
28
|
<div class="apm-stat">
|
|
25
|
-
<p class="apm-stat-label"
|
|
29
|
+
<p class="apm-stat-label"><%= t("simple_apm.dashboard.current_collection") %></p>
|
|
26
30
|
<div class="apm-stat-value">
|
|
27
31
|
<% if SimpleApm::Redis.running? %>
|
|
28
|
-
<span class="apm-status apm-status-ok"
|
|
32
|
+
<span class="apm-status apm-status-ok"><%= t("simple_apm.common.running") %></span>
|
|
29
33
|
<% else %>
|
|
30
|
-
<span class="apm-status apm-status-danger"
|
|
34
|
+
<span class="apm-status apm-status-danger"><%= t("simple_apm.common.paused") %></span>
|
|
31
35
|
<% end %>
|
|
32
36
|
</div>
|
|
33
|
-
<div class="apm-stat-meta"
|
|
37
|
+
<div class="apm-stat-meta"><%= t("simple_apm.dashboard.redis_status") %></div>
|
|
34
38
|
</div>
|
|
35
39
|
<div class="apm-stat">
|
|
36
|
-
<p class="apm-stat-label"
|
|
37
|
-
<div class="apm-stat-value"><%=
|
|
38
|
-
<div class="apm-stat-meta"
|
|
40
|
+
<p class="apm-stat-label"><%= t("simple_apm.dashboard.query_date") %></p>
|
|
41
|
+
<div class="apm-stat-value"><%= apm_date %></div>
|
|
42
|
+
<div class="apm-stat-meta"><%= t("simple_apm.dashboard.switch_in_top_right") %></div>
|
|
39
43
|
</div>
|
|
40
44
|
</div>
|
|
41
45
|
|
|
46
|
+
<% if @daily_stats[:hits].zero? %>
|
|
47
|
+
<section class="apm-panel">
|
|
48
|
+
<div class="apm-empty-state">
|
|
49
|
+
<h2 class="apm-panel-title"><%= t("simple_apm.dashboard.no_data") %></h2>
|
|
50
|
+
<p><%= t("simple_apm.dashboard.no_data_hint") %></p>
|
|
51
|
+
<%= link_to t("simple_apm.layout.nav_data"), data_path, class: 'btn apm-button-secondary' %>
|
|
52
|
+
</div>
|
|
53
|
+
</section>
|
|
54
|
+
<% else %>
|
|
42
55
|
<div class="apm-grid">
|
|
43
56
|
<section class="apm-panel apm-col-6">
|
|
44
57
|
<div class="apm-panel-header">
|
|
45
58
|
<div>
|
|
46
|
-
<h2 class="apm-panel-title"
|
|
47
|
-
<p class="apm-panel-subtitle"
|
|
59
|
+
<h2 class="apm-panel-title"><%= t("simple_apm.dashboard.response_time") %></h2>
|
|
60
|
+
<p class="apm-panel-subtitle"><%= t("simple_apm.dashboard.response_time_subtitle") %></p>
|
|
48
61
|
</div>
|
|
49
62
|
</div>
|
|
50
63
|
<div class="apm-panel-body">
|
|
51
|
-
<div id="time_chart" class="apm-chart"></div>
|
|
64
|
+
<div id="time_chart" class="apm-chart" role="img" aria-label="<%= t("simple_apm.dashboard.response_time") %> · <%= apm_date %>"></div>
|
|
52
65
|
</div>
|
|
53
66
|
</section>
|
|
54
67
|
|
|
55
68
|
<section class="apm-panel apm-col-6">
|
|
56
69
|
<div class="apm-panel-header">
|
|
57
70
|
<div>
|
|
58
|
-
<h2 class="apm-panel-title"
|
|
59
|
-
<p class="apm-panel-subtitle"
|
|
71
|
+
<h2 class="apm-panel-title"><%= t("simple_apm.dashboard.hit_count") %></h2>
|
|
72
|
+
<p class="apm-panel-subtitle"><%= t("simple_apm.dashboard.hit_count_subtitle") %></p>
|
|
60
73
|
</div>
|
|
61
74
|
</div>
|
|
62
75
|
<div class="apm-panel-body">
|
|
63
|
-
<div id="hits_chart" class="apm-chart"></div>
|
|
76
|
+
<div id="hits_chart" class="apm-chart" role="img" aria-label="<%= t("simple_apm.dashboard.hit_count") %> · <%= apm_date %>"></div>
|
|
64
77
|
</div>
|
|
65
78
|
</section>
|
|
66
79
|
</div>
|
|
67
80
|
|
|
68
81
|
<script>
|
|
69
|
-
|
|
82
|
+
(function () {
|
|
83
|
+
var time_chart = echarts.init(document.getElementById('time_chart')),
|
|
70
84
|
hits_chart = echarts.init(document.getElementById('hits_chart'));
|
|
71
85
|
time_chart.setOption({
|
|
86
|
+
animation: false,
|
|
72
87
|
color: ['#0f766e'],
|
|
73
|
-
grid: {left:
|
|
88
|
+
grid: {left: 16, right: 18, top: 32, bottom: 16, containLabel: true},
|
|
74
89
|
tooltip: {trigger: 'axis'},
|
|
75
90
|
xAxis: {
|
|
76
91
|
data: <%= @x_names.to_json.html_safe %>,
|
|
@@ -79,22 +94,25 @@
|
|
|
79
94
|
},
|
|
80
95
|
yAxis: {
|
|
81
96
|
type: 'value',
|
|
97
|
+
name: 's',
|
|
82
98
|
axisLine: {show: false},
|
|
83
99
|
splitLine: {lineStyle: {color: '#eef2f7'}},
|
|
84
100
|
axisLabel: {color: '#667085'}
|
|
85
101
|
},
|
|
86
102
|
series: [{
|
|
103
|
+
name: '<%= j t("simple_apm.dashboard.response_time") %> (s)',
|
|
87
104
|
type: 'line',
|
|
88
|
-
|
|
89
|
-
symbolSize:
|
|
105
|
+
showSymbol: true,
|
|
106
|
+
symbolSize: 4,
|
|
90
107
|
areaStyle: {color: 'rgba(15, 118, 110, 0.10)'},
|
|
91
|
-
data: <%= @time_arr.to_json.html_safe %>
|
|
108
|
+
data: <%= @time_arr.each_with_index.map { |time, i| @hits_arr[i].to_i.positive? ? time : nil }.to_json.html_safe %>
|
|
92
109
|
}]
|
|
93
110
|
})
|
|
94
111
|
|
|
95
112
|
hits_chart.setOption({
|
|
113
|
+
animation: false,
|
|
96
114
|
color: ['#2563eb'],
|
|
97
|
-
grid: {left:
|
|
115
|
+
grid: {left: 16, right: 18, top: 32, bottom: 16, containLabel: true},
|
|
98
116
|
tooltip: {trigger: 'axis'},
|
|
99
117
|
xAxis: {
|
|
100
118
|
data: <%= @x_names.to_json.html_safe %>,
|
|
@@ -103,21 +121,22 @@
|
|
|
103
121
|
},
|
|
104
122
|
yAxis: {
|
|
105
123
|
type: 'value',
|
|
124
|
+
minInterval: 1,
|
|
106
125
|
axisLine: {show: false},
|
|
107
126
|
splitLine: {lineStyle: {color: '#eef2f7'}},
|
|
108
127
|
axisLabel: {color: '#667085'}
|
|
109
128
|
},
|
|
110
129
|
series: [{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
symbolSize: 6,
|
|
114
|
-
areaStyle: {color: 'rgba(37, 99, 235, 0.10)'},
|
|
130
|
+
name: '<%= j t("simple_apm.dashboard.hit_count") %>',
|
|
131
|
+
type: 'bar',
|
|
115
132
|
data: <%= @hits_arr.to_json.html_safe %>
|
|
116
133
|
}]
|
|
117
134
|
})
|
|
118
135
|
|
|
119
|
-
$(window).on('resize', function () {
|
|
136
|
+
$(window).on('resize.simpleApmCharts', function () {
|
|
120
137
|
time_chart.resize()
|
|
121
138
|
hits_chart.resize()
|
|
122
139
|
})
|
|
140
|
+
})();
|
|
123
141
|
</script>
|
|
142
|
+
<% end %>
|
|
@@ -1,35 +1,54 @@
|
|
|
1
1
|
<div class="apm-page-header">
|
|
2
2
|
<div>
|
|
3
|
-
<h1 class="apm-page-title"
|
|
4
|
-
<p class="apm-page-subtitle"
|
|
3
|
+
<h1 class="apm-page-title"><%= t("simple_apm.data.title") %></h1>
|
|
4
|
+
<p class="apm-page-subtitle"><%= t("simple_apm.data.subtitle") %></p>
|
|
5
|
+
</div>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<% total_hits = @data.sum { |day| day[:hits].to_i } %>
|
|
9
|
+
<div class="apm-metrics apm-metrics-compact">
|
|
10
|
+
<div class="apm-stat">
|
|
11
|
+
<p class="apm-stat-label"><%= t("simple_apm.data.retained_days") %></p>
|
|
12
|
+
<div class="apm-stat-value"><%= number_with_delimiter(@data.length) %></div>
|
|
13
|
+
<div class="apm-stat-meta"><%= t("simple_apm.data.history_title") %></div>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="apm-stat">
|
|
16
|
+
<p class="apm-stat-label"><%= t("simple_apm.data.retained_requests") %></p>
|
|
17
|
+
<div class="apm-stat-value"><%= number_with_delimiter(total_hits) %></div>
|
|
18
|
+
<div class="apm-stat-meta"><%= t("simple_apm.data.summary_hint") %></div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="apm-stat">
|
|
21
|
+
<p class="apm-stat-label"><%= t("simple_apm.data.weighted_avg_response") %></p>
|
|
22
|
+
<div class="apm-stat-value"><%= total_hits.positive? ? sec_str(@data.sum { |day| day[:time].to_f } / total_hits) : '—' %></div>
|
|
23
|
+
<div class="apm-stat-meta"><%= t("simple_apm.dashboard.weighted_daily_average") %></div>
|
|
5
24
|
</div>
|
|
6
25
|
</div>
|
|
7
26
|
|
|
8
27
|
<section class="apm-panel">
|
|
9
28
|
<div class="apm-panel-header">
|
|
10
29
|
<div>
|
|
11
|
-
<h2 class="apm-panel-title"
|
|
12
|
-
<p class="apm-panel-subtitle"
|
|
30
|
+
<h2 class="apm-panel-title"><%= t("simple_apm.data.collection_status") %></h2>
|
|
31
|
+
<p class="apm-panel-subtitle"><%= t("simple_apm.data.collection_subtitle") %></p>
|
|
13
32
|
</div>
|
|
14
33
|
<div class="apm-toolbar-actions">
|
|
15
34
|
<% if SimpleApm::Redis.running? %>
|
|
16
|
-
<span class="apm-status apm-status-ok"
|
|
17
|
-
<%=
|
|
35
|
+
<span class="apm-status apm-status-ok"><%= t("simple_apm.common.running") %></span>
|
|
36
|
+
<%= button_to t("simple_apm.data.pause_collection"), data_delete_path(type: 'stop_data'), method: :post, class: 'btn btn-warning', form: {data: {confirm: t("simple_apm.data.confirm_pause")}} %>
|
|
18
37
|
<% else %>
|
|
19
|
-
<span class="apm-status apm-status-danger"
|
|
20
|
-
<%=
|
|
38
|
+
<span class="apm-status apm-status-danger"><%= t("simple_apm.common.paused") %></span>
|
|
39
|
+
<%= button_to t("simple_apm.data.resume_collection"), data_delete_path(type: 'rerun_data'), method: :post, class: 'btn btn-primary' %>
|
|
21
40
|
<% end %>
|
|
22
41
|
</div>
|
|
23
42
|
</div>
|
|
24
43
|
<div class="apm-panel-body">
|
|
25
44
|
<div class="apm-toolbar">
|
|
26
45
|
<div>
|
|
27
|
-
<strong
|
|
28
|
-
<p class="apm-page-subtitle"
|
|
46
|
+
<strong><%= t("simple_apm.data.delete_data") %></strong>
|
|
47
|
+
<p class="apm-page-subtitle"><%= t("simple_apm.data.delete_subtitle") %></p>
|
|
29
48
|
</div>
|
|
30
49
|
<div class="apm-toolbar-actions">
|
|
31
|
-
<%=
|
|
32
|
-
<%=
|
|
50
|
+
<%= button_to t("simple_apm.data.keep_one_week"), data_delete_path(type: 'week'), method: :post, class: 'btn btn-danger', form: {data: {confirm: t("simple_apm.data.confirm_delete_week")}} %>
|
|
51
|
+
<%= button_to t("simple_apm.data.keep_one_month"), data_delete_path(type: 'month'), method: :post, class: 'btn btn-danger', form: {data: {confirm: t("simple_apm.data.confirm_delete_month")}} %>
|
|
33
52
|
</div>
|
|
34
53
|
</div>
|
|
35
54
|
</div>
|
|
@@ -38,33 +57,58 @@
|
|
|
38
57
|
<section class="apm-panel">
|
|
39
58
|
<div class="apm-panel-header">
|
|
40
59
|
<div>
|
|
41
|
-
<h2 class="apm-panel-title"
|
|
42
|
-
<p class="apm-panel-subtitle"
|
|
60
|
+
<h2 class="apm-panel-title"><%= t("simple_apm.data.history_title") %></h2>
|
|
61
|
+
<p class="apm-panel-subtitle"><%= t("simple_apm.data.history_subtitle") %></p>
|
|
43
62
|
</div>
|
|
44
63
|
</div>
|
|
45
64
|
<div class="apm-panel-body">
|
|
65
|
+
<% if @data.empty? %>
|
|
66
|
+
<div class="apm-empty-state">
|
|
67
|
+
<h3 class="apm-panel-title"><%= t("simple_apm.data.no_data") %></h3>
|
|
68
|
+
<p><%= t("simple_apm.data.no_data_hint") %></p>
|
|
69
|
+
</div>
|
|
70
|
+
<% else %>
|
|
46
71
|
<div class="apm-table-wrap">
|
|
47
|
-
<table
|
|
72
|
+
<table id="history-table" class="table">
|
|
48
73
|
<thead>
|
|
49
74
|
<tr>
|
|
50
|
-
<th
|
|
51
|
-
<th
|
|
52
|
-
<th
|
|
53
|
-
<th
|
|
75
|
+
<th scope="col"><%= t("simple_apm.data.date") %></th>
|
|
76
|
+
<th scope="col"><%= t("simple_apm.data.request_count") %></th>
|
|
77
|
+
<th scope="col"><%= t("simple_apm.data.avg_response_time") %></th>
|
|
78
|
+
<th scope="col"><%= t("simple_apm.data.operation") %></th>
|
|
54
79
|
</tr>
|
|
55
80
|
</thead>
|
|
56
81
|
<tbody>
|
|
57
|
-
|
|
58
|
-
<% @data.each do |d| %>
|
|
82
|
+
<% @data.sort_by { |day| day[:day] }.reverse.each do |d| %>
|
|
59
83
|
<tr>
|
|
60
|
-
<td><%= d[:day] %></td>
|
|
61
|
-
<td><%= d[:hits] %></td>
|
|
62
|
-
<td><%= sec_str
|
|
63
|
-
<td
|
|
84
|
+
<td class="apm-mono"><%= link_to d[:day], dashboard_path(apm_date: d[:day]) %></td>
|
|
85
|
+
<td data-order="<%= d[:hits].to_i %>"><%= number_with_delimiter(d[:hits].to_i) %></td>
|
|
86
|
+
<td data-order="<%= d[:avg_time].to_f %>"><%= d[:hits].to_i.positive? ? sec_str(d[:avg_time]) : '—' %></td>
|
|
87
|
+
<td>
|
|
88
|
+
<div class="apm-toolbar-actions">
|
|
89
|
+
<%= link_to t("simple_apm.data.view_actions"), actions_path(apm_date: d[:day]), class: 'btn apm-button-secondary' %>
|
|
90
|
+
<%= link_to t("simple_apm.data.view_slow_requests"), index_path(apm_date: d[:day]), class: 'btn apm-button-secondary' %>
|
|
91
|
+
<%= button_to t("simple_apm.data.delete"), data_delete_path(date: d[:day]), method: :post, class: 'btn btn-danger', form: {data: {confirm: t("simple_apm.data.confirm_delete")}} %>
|
|
92
|
+
</div>
|
|
93
|
+
</td>
|
|
64
94
|
</tr>
|
|
65
95
|
<% end %>
|
|
66
96
|
</tbody>
|
|
67
97
|
</table>
|
|
68
98
|
</div>
|
|
99
|
+
<% end %>
|
|
69
100
|
</div>
|
|
70
101
|
</section>
|
|
102
|
+
<% unless @data.empty? %>
|
|
103
|
+
<script>
|
|
104
|
+
$(document).ready(function () {
|
|
105
|
+
$('#history-table').DataTable(window.SimpleApmUI.tableOptions({
|
|
106
|
+
order: [[0, 'desc']],
|
|
107
|
+
columnDefs: [
|
|
108
|
+
{type: 'num', targets: [1, 2]},
|
|
109
|
+
{orderable: false, searchable: false, targets: [3]}
|
|
110
|
+
]
|
|
111
|
+
}));
|
|
112
|
+
});
|
|
113
|
+
</script>
|
|
114
|
+
<% end %>
|
|
@@ -1,32 +1,40 @@
|
|
|
1
1
|
<div class="apm-page-header">
|
|
2
2
|
<div>
|
|
3
|
-
<h1 class="apm-page-title"
|
|
4
|
-
<p class="apm-page-subtitle"
|
|
3
|
+
<h1 class="apm-page-title"><%= t("simple_apm.index.title") %></h1>
|
|
4
|
+
<p class="apm-page-subtitle"><%= t("simple_apm.index.subtitle") %></p>
|
|
5
5
|
</div>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
8
|
<section class="apm-panel">
|
|
9
9
|
<div class="apm-panel-header">
|
|
10
10
|
<div>
|
|
11
|
-
<h2 class="apm-panel-title"
|
|
12
|
-
<p class="apm-panel-subtitle"
|
|
11
|
+
<h2 class="apm-panel-title"><%= t("simple_apm.index.samples_title") %></h2>
|
|
12
|
+
<p class="apm-panel-subtitle"><%= t("simple_apm.index.samples_subtitle") %></p>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="apm-toolbar-actions">
|
|
15
|
+
<%= label_tag 'sample-limit', t("simple_apm.index.sample_limit") %>
|
|
16
|
+
<% maximum_samples = [SimpleApm::Setting::SLOW_ACTIONS_LIMIT.to_i, 1].max %>
|
|
17
|
+
<% sample_limits = ([50, 200, 500].map { |limit| [limit, maximum_samples].min } + [@sample_limit]).uniq.sort %>
|
|
18
|
+
<%= select_tag 'sample-limit', options_for_select(sample_limits, @sample_limit), class: 'form-control' %>
|
|
19
|
+
<button id="refresh-requests" type="button" class="btn apm-button-secondary"><%= t("simple_apm.index.refresh") %></button>
|
|
13
20
|
</div>
|
|
14
21
|
</div>
|
|
15
22
|
<div class="apm-panel-body">
|
|
23
|
+
<p id="slow-requests-feedback" class="apm-table-feedback" role="status" aria-live="polite"></p>
|
|
16
24
|
<div class="apm-table-wrap">
|
|
17
|
-
<table id="slow-requests" class="table">
|
|
25
|
+
<table id="slow-requests" class="table" aria-describedby="slow-requests-feedback">
|
|
18
26
|
<thead>
|
|
19
27
|
<tr>
|
|
20
|
-
<th
|
|
21
|
-
<th
|
|
22
|
-
<th
|
|
23
|
-
<th
|
|
24
|
-
<th
|
|
25
|
-
<th
|
|
26
|
-
<th
|
|
27
|
-
<th
|
|
28
|
-
<th
|
|
29
|
-
<th
|
|
28
|
+
<th scope="col"><%= t("simple_apm.index.request_time") %></th>
|
|
29
|
+
<th scope="col"><%= t("simple_apm.index.action_name") %></th>
|
|
30
|
+
<th scope="col"><%= t("simple_apm.index.total_time") %></th>
|
|
31
|
+
<th scope="col"><%= t("simple_apm.common.db") %></th>
|
|
32
|
+
<th scope="col"><%= t("simple_apm.common.sql") %></th>
|
|
33
|
+
<th scope="col"><%= t("simple_apm.common.view") %></th>
|
|
34
|
+
<th scope="col"><%= t("simple_apm.common.http") %></th>
|
|
35
|
+
<th scope="col"><%= t("simple_apm.index.memory_mb") %></th>
|
|
36
|
+
<th scope="col"><%= t("simple_apm.common.server") %></th>
|
|
37
|
+
<th scope="col"><%= t("simple_apm.index.ip") %></th>
|
|
30
38
|
</tr>
|
|
31
39
|
</thead>
|
|
32
40
|
</table>
|
|
@@ -36,11 +44,31 @@
|
|
|
36
44
|
|
|
37
45
|
<script type="text/javascript">
|
|
38
46
|
$(document).ready(function () {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
var requestsUrl = <%= raw json_escape(index_path(format: :json, apm_date: apm_date).to_json) %>,
|
|
48
|
+
refreshButton = $('#refresh-requests'),
|
|
49
|
+
sampleLimit = $('#sample-limit');
|
|
50
|
+
var requestsTable = $('#slow-requests').on('processing.dt', function (event, settings, processing) {
|
|
51
|
+
refreshButton.prop('disabled', processing).text(processing ? '<%= j t("simple_apm.index.refresh_loading") %>' : '<%= j t("simple_apm.index.refresh") %>');
|
|
52
|
+
sampleLimit.prop('disabled', processing);
|
|
53
|
+
$(this).attr('aria-busy', processing ? 'true' : 'false');
|
|
54
|
+
}).DataTable(window.SimpleApmUI.tableOptions({
|
|
55
|
+
ajax: requestsUrl + '&count=' + encodeURIComponent(sampleLimit.val()),
|
|
56
|
+
order: [[2, 'desc']],
|
|
57
|
+
columnDefs: [
|
|
58
|
+
{type: 'sec', targets: [2, 3, 5, 6]},
|
|
59
|
+
{type: 'num', targets: [4, 7]},
|
|
60
|
+
{className: 'apm-mono', targets: [1, 8, 9]}
|
|
61
|
+
]
|
|
62
|
+
}));
|
|
63
|
+
refreshButton.on('click', function () {
|
|
64
|
+
requestsTable.ajax.reload(null, false);
|
|
65
|
+
});
|
|
66
|
+
sampleLimit.on('change', function () {
|
|
67
|
+
var pageUrl = new URL(window.location.href);
|
|
68
|
+
pageUrl.searchParams.set('count', this.value);
|
|
69
|
+
window.history.replaceState(null, '', pageUrl.toString());
|
|
70
|
+
$('.apm-date-form input[name="count"]').val(this.value);
|
|
71
|
+
requestsTable.ajax.url(requestsUrl + '&count=' + encodeURIComponent(this.value)).load();
|
|
72
|
+
});
|
|
45
73
|
})
|
|
46
74
|
</script>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<section class="apm-panel apm-empty-state">
|
|
2
|
+
<h1 class="apm-page-title"><%= t("simple_apm.common.missing_title") %></h1>
|
|
3
|
+
<p class="apm-page-subtitle"><%= t("simple_apm.common.missing_hint") %></p>
|
|
4
|
+
<div class="apm-toolbar-actions">
|
|
5
|
+
<%= link_to t("simple_apm.layout.nav_slow_requests"), index_path, class: 'btn apm-button-secondary' %>
|
|
6
|
+
<%= link_to t("simple_apm.layout.nav_actions"), actions_path, class: 'btn btn-primary' %>
|
|
7
|
+
</div>
|
|
8
|
+
</section>
|