simple_apm 0.1.8 → 0.1.9
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 +8 -5
- data/app/assets/javascripts/simple_apm/application.js +26 -0
- data/app/controllers/simple_apm/apm_controller.rb +29 -4
- data/app/helpers/simple_apm/application_helper.rb +6 -6
- data/app/models/simple_apm/hit.rb +15 -2
- data/app/models/simple_apm/slow_request.rb +2 -2
- data/app/views/layouts/simple_apm/application.html.erb +38 -13
- data/app/views/simple_apm/apm/actions.html.erb +6 -4
- data/app/views/simple_apm/apm/data.html.erb +27 -0
- data/app/views/simple_apm/apm/index.html.erb +0 -14
- data/app/views/simple_apm/apm/show.html.erb +5 -4
- data/config/routes.rb +2 -0
- data/config/simple_apm.yml +11 -0
- data/lib/generators/simple_apm/install_generator.rb +23 -0
- data/lib/simple_apm/redis.rb +16 -1
- data/lib/simple_apm/setting.rb +3 -3
- data/lib/simple_apm/version.rb +1 -1
- data/lib/tasks/simple_apm_tasks.rake +3 -3
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 23e7fd45a7f7fc7edc4590c681e1eabac3a34adfe7ac1a3d17e8b16a97303502
|
|
4
|
+
data.tar.gz: 3020c53720ad77a0414711531c590d7334eee6aab119bf3e1fb4d1b2c2b1c973
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1701cce03295e27d0d6cef228f86358c6653fbecfb616c6613b84c90c5eb0dd73e3e5f30fec9b34a8f6a174c3b7ce754a8c0de693f35f8f58d896a6f8bb97c25
|
|
7
|
+
data.tar.gz: 21d7870003ba6dcf01383b65f657a3ee9a36d51943c5b76f5558191d609b17791fa6e688443394509aa86c8f99308993b01cb9200c7fb12fc00e85f0541c7c81
|
data/README.md
CHANGED
|
@@ -3,18 +3,21 @@
|
|
|
3
3
|
基于Redis的简单的Web请求性能监控/慢事务追踪工具
|
|
4
4
|
|
|
5
5
|
以天为维度记录:
|
|
6
|
-
- 最慢的
|
|
7
|
-
- 记录每个action最慢的
|
|
6
|
+
- 最慢的500个(默认500)请求
|
|
7
|
+
- 记录每个action最慢的20次请求
|
|
8
8
|
- 记录每个action的平均访问时间
|
|
9
|
-
- 记录每个小时请求量
|
|
10
9
|
- 记录慢请求的详情和对应SQL详情(多余的会删掉)
|
|
11
|
-
- 以10
|
|
10
|
+
- 以10分钟为刻度记录平均/最慢访问时间、次数等性能指标,并生成图表
|
|
12
11
|
|
|
13
12
|
## Usage
|
|
14
13
|
|
|
15
14
|
```ruby
|
|
16
15
|
# routes.rb
|
|
17
|
-
mount SimpleApm::Engine =>
|
|
16
|
+
mount SimpleApm::Engine => "/apm"
|
|
17
|
+
|
|
18
|
+
# 或运行
|
|
19
|
+
rails generate simple_apm:install
|
|
20
|
+
|
|
18
21
|
```
|
|
19
22
|
|
|
20
23
|
|
|
@@ -11,3 +11,29 @@
|
|
|
11
11
|
// about supported directives.
|
|
12
12
|
//
|
|
13
13
|
//= require_tree .
|
|
14
|
+
|
|
15
|
+
// JqueryDataTable自定义排序方法
|
|
16
|
+
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
|
|
17
|
+
"sec-pre": function (a) {
|
|
18
|
+
var x = String(a).replace(/<[\s\S]*?>/g, ""); //去除html标记
|
|
19
|
+
x = x.replace(/&nbsp;/ig, ""); //去除空格
|
|
20
|
+
x = x.replace(/%/, ""); //去除百分号
|
|
21
|
+
if(x.indexOf('ms')>0){
|
|
22
|
+
x = x.replace(/ms/, "");
|
|
23
|
+
return parseFloat(x)/1000;
|
|
24
|
+
}else if(x.indexOf('min')>0){
|
|
25
|
+
x = x.replace(/min/, "");
|
|
26
|
+
return parseFloat(x)*60;
|
|
27
|
+
}else{
|
|
28
|
+
x = x.replace(/min/, "");
|
|
29
|
+
return parseFloat(x)
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"sec-asc": function (a, b) { //正序排序引用方法
|
|
33
|
+
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
|
|
34
|
+
},
|
|
35
|
+
"sec-desc": function (a, b) { //倒序排序引用方法
|
|
36
|
+
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
@@ -9,14 +9,14 @@ module SimpleApm
|
|
|
9
9
|
d = SimpleApm::RedisKey.query_date == Time.now.strftime('%Y-%m-%d') ? Time.now.strftime('%H:%M') : '23:50'
|
|
10
10
|
data = SimpleApm::Hit.chart_data(0, d)
|
|
11
11
|
@x_names = data.keys.sort
|
|
12
|
-
@time_arr = @x_names.map{|n| data[n][:hits].to_i.zero? ? 0 : (data[n][:time].to_f/data[n][:hits].to_i).round(3)
|
|
13
|
-
@hits_arr = @x_names.map{|n| data[n][:hits] rescue 0}
|
|
12
|
+
@time_arr = @x_names.map {|n| data[n][:hits].to_i.zero? ? 0 : (data[n][:time].to_f / data[n][:hits].to_i).round(3)}
|
|
13
|
+
@hits_arr = @x_names.map {|n| data[n][:hits] rescue 0}
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def index
|
|
17
17
|
respond_to do |format|
|
|
18
18
|
format.json do
|
|
19
|
-
@slow_requests = SimpleApm::SlowRequest.list(params[:count]||200).map do |r|
|
|
19
|
+
@slow_requests = SimpleApm::SlowRequest.list(params[:count] || 200).map do |r|
|
|
20
20
|
request = r.request
|
|
21
21
|
[
|
|
22
22
|
link_to(time_label(request.started), show_path(id: request.request_id)),
|
|
@@ -39,7 +39,7 @@ module SimpleApm
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def actions
|
|
42
|
-
@actions = SimpleApm::Action.all_names.map{|n| SimpleApm::Action.find(n)}
|
|
42
|
+
@actions = SimpleApm::Action.all_names.map {|n| SimpleApm::Action.find(n)}
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def action_info
|
|
@@ -51,12 +51,37 @@ module SimpleApm
|
|
|
51
51
|
redirect_to request.referer
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
def data
|
|
55
|
+
@data = SimpleApm::Redis.in_apm_days.map {|x| SimpleApm::Hit.day_info(x)}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def data_delete
|
|
59
|
+
if params[:date].is_a?(String)
|
|
60
|
+
r = SimpleApm::Redis.clear_data(params[:date])
|
|
61
|
+
flash[:notice] = r[:success] ? '删除成功!' : r[:msg]
|
|
62
|
+
elsif params[:type]=='month'
|
|
63
|
+
del_count = SimpleApm::Redis.clear_data_before_time(Time.now.at_beginning_of_day - 1.month)
|
|
64
|
+
flash[:notice] = "成功删除#{del_count}条数据"
|
|
65
|
+
elsif params[:type]=='week'
|
|
66
|
+
del_count = SimpleApm::Redis.clear_data_before_time(Time.now.at_beginning_of_day - 1.week)
|
|
67
|
+
flash[:notice] = "成功删除#{del_count}条数据"
|
|
68
|
+
else
|
|
69
|
+
flash[:notice] = '未知操作!'
|
|
70
|
+
# r = params[:date].map{|d|SimpleApm::Redis.clear_data(d)}
|
|
71
|
+
# suc, fail = r.partition{|x|x[:success]}
|
|
72
|
+
# flash[:notice] = "成功删除#{suc.length}"
|
|
73
|
+
# flash[:notice] << ",失败#{fail.length}" if fail.length>0
|
|
74
|
+
end
|
|
75
|
+
redirect_to action: :data
|
|
76
|
+
end
|
|
77
|
+
|
|
54
78
|
def set_apm_date
|
|
55
79
|
# set_query_date
|
|
56
80
|
redirect_to action: :dashboard
|
|
57
81
|
end
|
|
58
82
|
|
|
59
83
|
private
|
|
84
|
+
|
|
60
85
|
def set_query_date
|
|
61
86
|
session[:apm_date] = params[:apm_date] if params[:apm_date].present?
|
|
62
87
|
SimpleApm::RedisKey.query_date = session[:apm_date]
|
|
@@ -8,19 +8,19 @@ module SimpleApm
|
|
|
8
8
|
_sec = sec.to_f
|
|
9
9
|
|
|
10
10
|
if force == 'min'
|
|
11
|
-
return "#{(_sec / 60).to_f.round(1)}min"
|
|
11
|
+
return "#{(_sec / 60).to_f.round(1)} min"
|
|
12
12
|
elsif force == 's'
|
|
13
|
-
return "#{_sec.round(2)}s"
|
|
13
|
+
return "#{_sec.round(2)} s"
|
|
14
14
|
elsif force == 'ms'
|
|
15
|
-
return "#{(_sec * 1000).round}ms"
|
|
15
|
+
return "#{(_sec * 1000).round} ms"
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
if (_sec / 60).to_i > 0
|
|
19
|
-
"#{(_sec / 60).to_f.round(1)}min"
|
|
19
|
+
"#{(_sec / 60).to_f.round(1)} min"
|
|
20
20
|
elsif _sec.to_i > 0
|
|
21
|
-
"#{_sec.round(2)}s"
|
|
21
|
+
"#{_sec.round(2)} s"
|
|
22
22
|
else
|
|
23
|
-
"#{(_sec * 1000).round}ms"
|
|
23
|
+
"#{(_sec * 1000).round} ms"
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -4,6 +4,19 @@ module SimpleApm
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class << self
|
|
7
|
+
def day_info(date_str)
|
|
8
|
+
hits, time = 0, 0.0
|
|
9
|
+
SimpleApm::Redis.hgetall(minute_key(date_str)).each do |k, v|
|
|
10
|
+
if k=~/time/
|
|
11
|
+
time += v.to_f
|
|
12
|
+
elsif k=~/hits/
|
|
13
|
+
hits += v.to_i
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
avg_time = (hits.to_i==0 ? 0 : (time/hits).to_f.round(3))
|
|
17
|
+
{day: date_str, hits: hits, time: time, avg_time: avg_time}
|
|
18
|
+
end
|
|
19
|
+
|
|
7
20
|
def chart_data(start_time = '00:00', end_time = '23:50', per = 'minute')
|
|
8
21
|
start_hour = start_time.to_s.split(':').first.to_i
|
|
9
22
|
end_hour = [end_time.to_s.split(':').first.to_i, 23].min
|
|
@@ -42,8 +55,8 @@ module SimpleApm
|
|
|
42
55
|
i.to_s.size==1 ? "0#{i}" : i.to_s
|
|
43
56
|
end
|
|
44
57
|
|
|
45
|
-
def minute_key
|
|
46
|
-
SimpleApm::RedisKey['per-10-minute']
|
|
58
|
+
def minute_key(date_str = nil)
|
|
59
|
+
SimpleApm::RedisKey['per-10-minute', date_str]
|
|
47
60
|
end
|
|
48
61
|
|
|
49
62
|
# def hour_hit_key
|
|
@@ -40,7 +40,7 @@ module SimpleApm
|
|
|
40
40
|
# @param during [Float] 耗时
|
|
41
41
|
# @return [Boolean] 是否插入成功
|
|
42
42
|
def update_request(during, request_id)
|
|
43
|
-
# 记录最慢请求列表
|
|
43
|
+
# 记录最慢请求列表5000个
|
|
44
44
|
SimpleApm::Redis.zadd(key, during, request_id)
|
|
45
45
|
SimpleApm::Redis.zremrangebyrank(key, 0, -SimpleApm::Setting::SLOW_ACTIONS_LIMIT - 1)
|
|
46
46
|
SimpleApm::Redis.zrank(key, request_id).present?
|
|
@@ -50,7 +50,7 @@ module SimpleApm
|
|
|
50
50
|
# @return [Array<SimpleApm::SlowRequest>]
|
|
51
51
|
def list_by_action(action_name, limit = 100, offset = 0)
|
|
52
52
|
SimpleApm::Redis.zrevrange(
|
|
53
|
-
action_key(action_name), offset, limit, with_scores: true
|
|
53
|
+
action_key(action_name), offset, limit.to_i - 1, with_scores: true
|
|
54
54
|
).map{ |x| SimpleApm::SlowRequest.new(x[0], x[1], action_name)}
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -20,13 +20,23 @@
|
|
|
20
20
|
<nav class="navbar navbar-default navbar-fixed-top">
|
|
21
21
|
<div class="container">
|
|
22
22
|
<div class="navbar-header">
|
|
23
|
-
<%
|
|
24
|
-
|
|
23
|
+
<%
|
|
24
|
+
[
|
|
25
|
+
[dashboard_path, 'Dashboard'],
|
|
26
|
+
[index_path, '慢事务列表'],
|
|
27
|
+
[actions_path, 'ActionList'],
|
|
28
|
+
[data_path, '数据管理']
|
|
29
|
+
].each do |m|
|
|
30
|
+
%>
|
|
31
|
+
<a class="navbar-brand <%= 'active' if request.url =~ /#{m[0]}/ %>"
|
|
32
|
+
href="<%= m[0] %>" >
|
|
33
|
+
<%= m[1] %>
|
|
34
|
+
</a>
|
|
25
35
|
<% end %>
|
|
26
36
|
</div>
|
|
27
37
|
<div class="select-apm-date">
|
|
28
38
|
统计日期
|
|
29
|
-
<%= select_tag 'apm_date', options_for_select(SimpleApm::Redis.in_apm_days, apm_date), class: 'form-control'%>
|
|
39
|
+
<%= select_tag 'apm_date', options_for_select(SimpleApm::Redis.in_apm_days, apm_date), class: 'form-control' %>
|
|
30
40
|
</div>
|
|
31
41
|
|
|
32
42
|
</div>
|
|
@@ -42,20 +52,35 @@
|
|
|
42
52
|
</footer>
|
|
43
53
|
<div id="sql-modal" class="modal" aria-hidden="true" role="dialog" style="display: none;" tabindex="-1">
|
|
44
54
|
<div class="modal-dialog modal-lg modal-dialog-popout">
|
|
45
|
-
<
|
|
46
|
-
|
|
55
|
+
<div class="panel panel-default">
|
|
56
|
+
<div class="panel-heading">
|
|
57
|
+
<div class="panel-title">SQL</div>
|
|
58
|
+
</div>
|
|
59
|
+
<div class="panel-body">
|
|
60
|
+
<pre class="modal-content" data-lang="SQL"></pre>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
47
64
|
</div>
|
|
48
65
|
</div>
|
|
49
66
|
|
|
50
67
|
</body>
|
|
51
68
|
<script>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
69
|
+
<% if flash[:notice].present? %>
|
|
70
|
+
alert(<%= flash[:notice].to_json.html_safe %>)
|
|
71
|
+
<% end %>
|
|
72
|
+
var sql_modal_obj = $('#sql-modal')
|
|
73
|
+
$('.select-apm-date select').on('change', function () {
|
|
74
|
+
window.location.href = '<%= set_apm_date_path %>?apm_date=' + this.value
|
|
75
|
+
})
|
|
76
|
+
$('.sql').on('click', function () {
|
|
77
|
+
sql_modal_obj.find('.modal-content').html($(this).html())
|
|
78
|
+
sql_modal_obj.modal('show')
|
|
79
|
+
})
|
|
80
|
+
// 手写部分ujs
|
|
81
|
+
$("a[data-confirm]").on('click', function () {
|
|
82
|
+
return confirm($(this).data('confirm'))
|
|
83
|
+
})
|
|
84
|
+
|
|
60
85
|
</script>
|
|
61
86
|
</html>
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
<tr>
|
|
14
14
|
<td><%= link_to action.name, action_info_path(action_name: action.name) %></td>
|
|
15
15
|
<td><%= action.click_count %></td>
|
|
16
|
-
<td><%= sec_str action.avg_time
|
|
17
|
-
<td><%= link_to sec_str(action.fast_time
|
|
18
|
-
<td><%= link_to sec_str(action.slow_time
|
|
16
|
+
<td><%= sec_str action.avg_time %></td>
|
|
17
|
+
<td><%= link_to sec_str(action.fast_time), show_path(id: action.fast_id) %></td>
|
|
18
|
+
<td><%= link_to sec_str(action.slow_time), show_path(id: action.slow_id) %></td>
|
|
19
19
|
</tr>
|
|
20
20
|
<% end %>
|
|
21
21
|
</tbody>
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
<script type="text/javascript">
|
|
24
24
|
$(document).ready(function(){
|
|
25
25
|
$('#actions-table').DataTable({
|
|
26
|
-
iDisplayLength: 25
|
|
26
|
+
iDisplayLength: 25,
|
|
27
|
+
// 自定义的排序方法
|
|
28
|
+
aoColumnDefs: [ {sType: "sec", aTargets: [2,3,4]}]
|
|
27
29
|
})
|
|
28
30
|
|
|
29
31
|
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<p class="pull-right">
|
|
2
|
+
<span class="text-danger">删除数据:</span>
|
|
3
|
+
<%= link_to '保留进一周数据', data_delete_path(type: 'week'), class: 'btn btn-danger', 'data-confirm': '确定删除所有一周以前的数据?'%>
|
|
4
|
+
<%= link_to '保留进一个月数据', data_delete_path(type: 'month'), class: 'btn btn-danger', 'data-confirm': '确定删除所有一个月以前的数据?' %>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<table class="table table-bordered">
|
|
8
|
+
<thead>
|
|
9
|
+
<tr>
|
|
10
|
+
<th>日期</th>
|
|
11
|
+
<th>请求数量</th>
|
|
12
|
+
<th>平均响应时间</th>
|
|
13
|
+
<th>操作</th>
|
|
14
|
+
</tr>
|
|
15
|
+
</thead>
|
|
16
|
+
<tbody>
|
|
17
|
+
<!-- {day: date_str, hits: hits, time: time, avg_time: avg_time}-->
|
|
18
|
+
<% @data.each do |d| %>
|
|
19
|
+
<tr>
|
|
20
|
+
<td><%= d[:day]%></td>
|
|
21
|
+
<td><%= d[:hits]%></td>
|
|
22
|
+
<td><%= sec_str d[:avg_time]%></td>
|
|
23
|
+
<td><%= link_to '删除', data_delete_path(date: d[:day]), 'data-confirm': '确定删除?' %></td>
|
|
24
|
+
</tr>
|
|
25
|
+
<% end %>
|
|
26
|
+
</tbody>
|
|
27
|
+
</table>
|
|
@@ -10,20 +10,6 @@
|
|
|
10
10
|
<th>remote_addr</th>
|
|
11
11
|
</tr>
|
|
12
12
|
</thead>
|
|
13
|
-
<%# @slow_requests.each do |r| %>
|
|
14
|
-
<!-- <tr>-->
|
|
15
|
-
<%# request = r.request %>
|
|
16
|
-
<!-- <td>-->
|
|
17
|
-
<%#= link_to time_label(request.started), show_path(id: request.request_id)%>
|
|
18
|
-
<!-- </td>-->
|
|
19
|
-
<!-- <td><%#= link_to request.action_name, action_info_path(action_name: request.action_name)%></td>-->
|
|
20
|
-
<!-- <td><%#= sec_str request.during %></td>-->
|
|
21
|
-
<!-- <td><%#= sec_str request.db_runtime %></td>-->
|
|
22
|
-
<!-- <td><%#= sec_str request.view_runtime%></td>-->
|
|
23
|
-
<!-- <td><%#= request.host %></td>-->
|
|
24
|
-
<!-- <td><%#= request.remote_addr %></td>-->
|
|
25
|
-
<!-- </tr>-->
|
|
26
|
-
<%# end %>
|
|
27
13
|
</table>
|
|
28
14
|
|
|
29
15
|
<script type="text/javascript">
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
<h4><%= @request.action_name %>.<%= @request.format
|
|
2
|
-
<!-- @host="xyy", @remote_addr="127.0.0.1", @method="GET", @format="html", @exception="null"-->
|
|
1
|
+
<h4><%= @request.action_name %>.<%= @request.format %>(<%= @request.method %>)</h4>
|
|
3
2
|
<p>
|
|
4
3
|
<label>开始时间:</label>
|
|
5
4
|
<span><%= time_label @request.started, true %></span>
|
|
@@ -31,7 +30,7 @@
|
|
|
31
30
|
<td>time</td>
|
|
32
31
|
<td>name</td>
|
|
33
32
|
<td>sql</td>
|
|
34
|
-
<td
|
|
33
|
+
<td>时间(ms)</td>
|
|
35
34
|
<td>位置</td>
|
|
36
35
|
</tr>
|
|
37
36
|
</thead>
|
|
@@ -54,7 +53,9 @@
|
|
|
54
53
|
<script type="text/javascript">
|
|
55
54
|
$(document).ready(function(){
|
|
56
55
|
$('#sql-table').DataTable({
|
|
57
|
-
bPaginate: false
|
|
56
|
+
bPaginate: false,
|
|
57
|
+
// 自定义的排序方法
|
|
58
|
+
aoColumnDefs: [{sType: "sec", aTargets: [3]}]
|
|
58
59
|
})
|
|
59
60
|
|
|
60
61
|
})
|
data/config/routes.rb
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# 默认为 redis://localhost:6379/0
|
|
2
|
+
# 确保是完整的redis地址,可以设置远程地址
|
|
3
|
+
redis_url:
|
|
4
|
+
# 默认为空, 建议使用hiredis(并确保有这个gem)
|
|
5
|
+
redis_driver:
|
|
6
|
+
# 记录每天的最慢的请求数存储量,默认500
|
|
7
|
+
slow_actions_limit:
|
|
8
|
+
# 记录每天的每个Action最慢的N个请求,默认20
|
|
9
|
+
action_slow_request_limit:
|
|
10
|
+
# 项目名,默认为 'app',区分项目名可以多个项目数据存于一台redis server上
|
|
11
|
+
app_name:
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
module SimpleApm
|
|
3
|
+
module Generators
|
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
|
5
|
+
desc "Create Notifications's base files"
|
|
6
|
+
source_root File.expand_path('../../../../', __FILE__)
|
|
7
|
+
|
|
8
|
+
def add_default_config
|
|
9
|
+
path = "#{Rails.root}/config/simple_apm.yml"
|
|
10
|
+
if File.exist?(path)
|
|
11
|
+
puts 'Skipping config/simple_apm.yml creation, as file already exists!'
|
|
12
|
+
else
|
|
13
|
+
puts 'Adding simple_apm default config file (config/simple_apm.yml)...'
|
|
14
|
+
template 'config/simple_apm.yml', path
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def add_routes
|
|
19
|
+
route 'mount SimpleApm::Engine => "/apm"'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/simple_apm/redis.rb
CHANGED
|
@@ -37,7 +37,22 @@ module SimpleApm
|
|
|
37
37
|
|
|
38
38
|
# 所有统计的日期,通过hits来判断
|
|
39
39
|
def in_apm_days
|
|
40
|
-
SimpleApm::Redis.keys('*:action-names').map{|x|x.split(':').first}.sort
|
|
40
|
+
SimpleApm::Redis.keys('*:action-names').map{|x|x.split(':').first}.sort.reverse
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# 清理指定日期之前的数据
|
|
44
|
+
def clear_data_before_time(date)
|
|
45
|
+
i = 0
|
|
46
|
+
SimpleApm::Redis.in_apm_days.each do |d|
|
|
47
|
+
SimpleApm::Redis.clear_data(d) and i+=1 if Time.parse(d) <= date
|
|
48
|
+
end
|
|
49
|
+
i
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def clear_data(date_str)
|
|
53
|
+
return {success: false, msg: '当日没有数据'} unless in_apm_days.include?(date_str)
|
|
54
|
+
keys = SimpleApm::Redis.keys("#{date_str}:*")
|
|
55
|
+
{success: true, msg: SimpleApm::Redis.del(keys)}
|
|
41
56
|
end
|
|
42
57
|
|
|
43
58
|
def method_missing(method, *args)
|
data/lib/simple_apm/setting.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
module SimpleApm
|
|
2
2
|
class Setting
|
|
3
|
-
ApmSettings = YAML.load(IO.read(
|
|
3
|
+
ApmSettings = YAML.load(IO.read("config/simple_apm.yml")) rescue {}
|
|
4
4
|
REDIS_URL = ApmSettings['redis_url'].presence || 'redis://localhost:6379/0'
|
|
5
5
|
# nil , hiredis ...
|
|
6
6
|
REDIS_DRIVER = ApmSettings['redis_driver']
|
|
7
7
|
# 最慢的请求数存储量
|
|
8
|
-
SLOW_ACTIONS_LIMIT = ApmSettings['slow_actions_limit'].presence ||
|
|
8
|
+
SLOW_ACTIONS_LIMIT = ApmSettings['slow_actions_limit'].presence || 500
|
|
9
9
|
# 每个action存最慢的请求量
|
|
10
|
-
ACTION_SLOW_REQUEST_LIMIT = ApmSettings['action_slow_request_limit'].presence ||
|
|
10
|
+
ACTION_SLOW_REQUEST_LIMIT = ApmSettings['action_slow_request_limit'].presence || 20
|
|
11
11
|
# 区分项目显示
|
|
12
12
|
APP_NAME = ApmSettings['app_name'].presence || 'app'
|
|
13
13
|
end
|
data/lib/simple_apm/version.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
# desc "Explaining what the task does"
|
|
2
|
-
|
|
3
|
-
#
|
|
4
|
-
|
|
2
|
+
task :simple_apm do
|
|
3
|
+
# Task goes here
|
|
4
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: simple_apm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- yuanyin.xia
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-06-
|
|
11
|
+
date: 2018-06-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -80,9 +80,12 @@ files:
|
|
|
80
80
|
- app/views/simple_apm/apm/action_info.html.erb
|
|
81
81
|
- app/views/simple_apm/apm/actions.html.erb
|
|
82
82
|
- app/views/simple_apm/apm/dashboard.html.erb
|
|
83
|
+
- app/views/simple_apm/apm/data.html.erb
|
|
83
84
|
- app/views/simple_apm/apm/index.html.erb
|
|
84
85
|
- app/views/simple_apm/apm/show.html.erb
|
|
85
86
|
- config/routes.rb
|
|
87
|
+
- config/simple_apm.yml
|
|
88
|
+
- lib/generators/simple_apm/install_generator.rb
|
|
86
89
|
- lib/simple_apm.rb
|
|
87
90
|
- lib/simple_apm/engine.rb
|
|
88
91
|
- lib/simple_apm/redis.rb
|