simple_apm 1.0.14 → 1.1.0

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.
@@ -1,90 +1,140 @@
1
- <h4><%= @request.action_name %>.<%= @request.format %>(<%= @request.method %>)</h4>
2
- <p>
3
- <label>URL:</label>
4
- <span><%= @request.url %></span>
5
- </p>
6
- <p>
7
- <label>开始时间:</label>
8
- <span><%= time_label @request.started, true %></span>
9
- </p>
10
- <p>
11
- <label>响应时间:</label>
12
- <span>
13
- <%= sec_str @request.during %>
14
- (数据库:<%= sec_str @request.db_runtime %>,
15
- View: <%= sec_str @request.view_runtime %>
16
- <%= ",外部请求: #{sec_str @request.net_http_during}" if @request.net_http_during.to_f>0 %>)
17
- </span>
18
- </p>
19
- <p>
20
- <label>结束时内存:</label>
21
- <span>
22
- <%= @request.completed_memory.to_f.round(1) %>M
23
- (增幅:<%= @request.memory_during.to_f.round(1) %>M)
24
- </span>
25
- </p>
26
- <p>
27
- <label>server:</label>
28
- <span><%= @request.host %></span>
29
- </p>
30
- <p>
31
- <label>访问ip:</label>
32
- <span><%= @request.remote_addr %></span>
33
- </p>
1
+ <div class="apm-page-header">
2
+ <div>
3
+ <h1 class="apm-page-title">请求详情</h1>
4
+ <p class="apm-page-subtitle"><%= @request.action_name %>.<%= @request.format %>(<%= @request.method %>)</p>
5
+ </div>
6
+ </div>
7
+
8
+ <div class="apm-metrics">
9
+ <div class="apm-stat">
10
+ <p class="apm-stat-label">Total</p>
11
+ <div class="apm-stat-value"><%= sec_str @request.during %></div>
12
+ </div>
13
+ <div class="apm-stat">
14
+ <p class="apm-stat-label">DB</p>
15
+ <div class="apm-stat-value"><%= sec_str @request.db_runtime %></div>
16
+ </div>
17
+ <div class="apm-stat">
18
+ <p class="apm-stat-label">SQL</p>
19
+ <div class="apm-stat-value"><%= @request.queries_count.to_i %></div>
20
+ <div class="apm-stat-meta">缓存 <%= @request.cached_queries_count.to_i %></div>
21
+ </div>
22
+ <div class="apm-stat">
23
+ <p class="apm-stat-label">View</p>
24
+ <div class="apm-stat-value"><%= sec_str @request.view_runtime %></div>
25
+ </div>
26
+ <div class="apm-stat">
27
+ <p class="apm-stat-label">HTTP</p>
28
+ <div class="apm-stat-value"><%= sec_str @request.net_http_during %></div>
29
+ </div>
30
+ </div>
31
+
32
+ <section class="apm-panel">
33
+ <div class="apm-panel-header">
34
+ <div>
35
+ <h2 class="apm-panel-title">基础信息</h2>
36
+ <p class="apm-panel-subtitle">请求来源、时间和内存变化。</p>
37
+ </div>
38
+ </div>
39
+ <div class="apm-panel-body">
40
+ <dl class="apm-detail-list">
41
+ <dt>URL</dt>
42
+ <dd><%= @request.url %></dd>
43
+ <dt>开始时间</dt>
44
+ <dd><%= time_label @request.started, true %></dd>
45
+ <dt>结束时内存</dt>
46
+ <dd><%= @request.completed_memory.to_f.round(1) %>M (增幅:<%= @request.memory_during.to_f.round(1) %>M)</dd>
47
+ <dt>server</dt>
48
+ <dd><%= @request.host %></dd>
49
+ <dt>访问ip</dt>
50
+ <dd><%= @request.remote_addr %></dd>
51
+ </dl>
52
+ </div>
53
+ </section>
54
+
34
55
  <% if @request.exception.present? && @request.exception != 'null' %>
35
- <p>
36
- <label>报错信息: </label>
37
- <pre><%= @request.exception %></pre>
38
- </p>
56
+ <section class="apm-panel">
57
+ <div class="apm-panel-header">
58
+ <div>
59
+ <h2 class="apm-panel-title">报错信息</h2>
60
+ </div>
61
+ </div>
62
+ <div class="apm-panel-body">
63
+ <pre><%= @request.exception %></pre>
64
+ </div>
65
+ </section>
39
66
  <% end %>
67
+
40
68
  <% if @request.net_http_requests.present? %>
41
- <p>外部请求</p>
42
- <table class="table table-bordered">
43
- <tr>
44
- <th>开始时间</th>
45
- <th>耗时</th>
46
- <th>URL</th>
47
- <th>其他信息</th>
48
- </tr>
49
- <% @request.net_http_requests.each do |r| %>
50
- <tr>
51
- <td><%= time_label r.started %></td>
52
- <td><%= sec_str r.during %></td>
53
- <td><%= r.url %></td>
54
- <td><%= "#{r.filename}: #{r.line}" if r.filename.present? %></td>
55
- </tr>
56
- <% end %>
57
- </table>
69
+ <section class="apm-panel">
70
+ <div class="apm-panel-header">
71
+ <div>
72
+ <h2 class="apm-panel-title">外部请求</h2>
73
+ <p class="apm-panel-subtitle">请求过程中触发的 Net::HTTP 调用。</p>
74
+ </div>
75
+ </div>
76
+ <div class="apm-panel-body">
77
+ <div class="apm-table-wrap">
78
+ <table class="table table-bordered">
79
+ <tr>
80
+ <th>开始时间</th>
81
+ <th>耗时</th>
82
+ <th>URL</th>
83
+ <th>其他信息</th>
84
+ </tr>
85
+ <% @request.net_http_requests.each do |r| %>
86
+ <tr>
87
+ <td><%= time_label r.started %></td>
88
+ <td><%= sec_str r.during %></td>
89
+ <td><%= r.url %></td>
90
+ <td><%= "#{r.filename}: #{r.line}" if r.filename.present? %></td>
91
+ </tr>
92
+ <% end %>
93
+ </table>
94
+ </div>
95
+ </div>
96
+ </section>
58
97
  <% end %>
59
98
 
60
99
  <% if @request.sqls.present? %>
61
- <p>SQL列表</p>
62
- <table id="sql-table" class="table">
63
- <thead>
64
- <tr>
65
- <td>time</td>
66
- <td>name</td>
67
- <td>sql</td>
68
- <td>时间(ms)</td>
69
- <td>位置</td>
70
- </tr>
71
- </thead>
72
- <tbody>
73
- <% @request.sqls.each do |sql| %>
74
- <tr>
75
- <td><%= time_label sql.started %></td>
76
- <td>
77
- <%= sql.name %>
78
- </td>
79
- <td>
80
- <div class="sql"><%= sql.full_sql -%></div>
81
- </td>
82
- <td><%= sec_str sql.during %></td>
83
- <td><%= sql.filename %>:<%= sql.line %></td>
84
- </tr>
85
- <% end %>
86
- </tbody>
87
- </table>
100
+ <section class="apm-panel">
101
+ <div class="apm-panel-header">
102
+ <div>
103
+ <h2 class="apm-panel-title">SQL 列表</h2>
104
+ <p class="apm-panel-subtitle">点击 SQL 文本查看完整语句。</p>
105
+ </div>
106
+ </div>
107
+ <div class="apm-panel-body">
108
+ <div class="apm-table-wrap">
109
+ <table id="sql-table" class="table">
110
+ <thead>
111
+ <tr>
112
+ <td>time</td>
113
+ <td>name</td>
114
+ <td>sql</td>
115
+ <td>时间(ms)</td>
116
+ <td>位置</td>
117
+ </tr>
118
+ </thead>
119
+ <tbody>
120
+ <% @request.sqls.each do |sql| %>
121
+ <tr>
122
+ <td><%= time_label sql.started %></td>
123
+ <td>
124
+ <%= sql.name %>
125
+ </td>
126
+ <td>
127
+ <div class="sql"><%= sql.full_sql -%></div>
128
+ </td>
129
+ <td><%= sec_str sql.during %></td>
130
+ <td><%= sql.filename %>:<%= sql.line %></td>
131
+ </tr>
132
+ <% end %>
133
+ </tbody>
134
+ </table>
135
+ </div>
136
+ </div>
137
+ </section>
88
138
  <script type="text/javascript">
89
139
  $(document).ready(function () {
90
140
  $('#sql-table').DataTable({
@@ -95,4 +145,4 @@
95
145
 
96
146
  })
97
147
  </script>
98
- <% end %>
148
+ <% end %>
@@ -62,12 +62,12 @@ module SimpleApm
62
62
  end
63
63
 
64
64
  def rerun!
65
- hset('status', 'running', true)
65
+ hset('status', 'running', 'true')
66
66
  end
67
67
 
68
68
  # 停止收集数据
69
69
  def stop!
70
- hset('status', 'running', false)
70
+ hset('status', 'running', 'false')
71
71
  end
72
72
 
73
73
  def method_missing(method, *args)
@@ -1,6 +1,16 @@
1
+ require 'erb'
2
+
1
3
  module SimpleApm
2
4
  class Setting
3
- ApmSettings = YAML.load(IO.read("config/simple_apm.yml")) rescue {}
5
+ def self.load_settings(path = "config/simple_apm.yml")
6
+ yaml = ERB.new(File.read(path)).result
7
+ settings = YAML.safe_load(yaml, aliases: true) || {}
8
+ settings.is_a?(Hash) ? settings : {}
9
+ rescue
10
+ {}
11
+ end
12
+
13
+ ApmSettings = load_settings
4
14
  REDIS_URL = ApmSettings['redis_url'].presence || 'redis://localhost:6379/0'
5
15
  # nil , hiredis ...
6
16
  REDIS_DRIVER = ApmSettings['redis_driver']
@@ -1,3 +1,3 @@
1
1
  module SimpleApm
2
- VERSION = '1.0.14'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -44,6 +44,8 @@ module SimpleApm
44
44
  started: started.to_s,
45
45
  db_runtime: payload[:db_runtime].to_f / 1000,
46
46
  view_runtime: payload[:view_runtime].to_f / 1000,
47
+ queries_count: payload[:queries_count].to_i,
48
+ cached_queries_count: payload[:cached_queries_count].to_i,
47
49
  controller: payload[:controller],
48
50
  action: payload[:action],
49
51
  host: Socket.gethostname,
@@ -127,4 +129,4 @@ module SimpleApm
127
129
  end
128
130
  end
129
131
  end
130
- end
132
+ end
data/lib/simple_apm.rb CHANGED
@@ -3,12 +3,21 @@ require 'simple_apm/redis'
3
3
  require 'simple_apm/engine'
4
4
  require 'simple_apm/worker'
5
5
  require 'simple_apm/net_http'
6
- require 'callsite'
7
6
  require 'get_process_mem'
8
7
  module SimpleApm
9
8
 
10
9
  SimpleApm::NetHttp.install
11
10
 
11
+ def self.merge_callsite_payload!(payload, locations = caller_locations)
12
+ if dev_caller = locations.detect { |location| location.path.include?(Rails.root.to_s) }
13
+ payload.merge!(
14
+ :line => dev_caller.lineno,
15
+ :filename => dev_caller.path.gsub(Rails.root.to_s, ''),
16
+ :method => dev_caller.base_label
17
+ )
18
+ end
19
+ end
20
+
12
21
  ActiveSupport::Notifications.subscribe('process_action.action_controller') do |name, started, finished, unique_id, payload|
13
22
  remote_addr = (payload[:headers]['HTTP_X_REAL_IP'] rescue nil)
14
23
  if remote_addr.blank? || remote_addr=='127.0.0.1'
@@ -36,10 +45,7 @@ module SimpleApm
36
45
  real_start_time = payload[:real_start_time] || started
37
46
  during = finished - real_start_time
38
47
  th[:net_http_during] += during if th[:net_http_during]
39
- if dev_caller = caller.detect { |c| c.include?(Rails.root.to_s) }
40
- c = ::Callsite.parse(dev_caller)
41
- payload.merge!(:line => c.line, :filename => c.filename.to_s.gsub(Rails.root.to_s, ''), :method => c.method)
42
- end
48
+ SimpleApm.merge_callsite_payload!(payload)
43
49
  ProcessingThread.add_event(
44
50
  name: name,
45
51
  request_id: request_id,
@@ -52,10 +58,7 @@ module SimpleApm
52
58
  ActiveSupport::Notifications.subscribe 'sql.active_record' do |name, started, finished, unique_id, payload|
53
59
  request_id = Thread.current['action_dispatch.request_id'].presence || Thread.main['action_dispatch.request_id']
54
60
  if request_id
55
- if dev_caller = caller.detect {|c| c.include? Rails.root.to_s}
56
- c = ::Callsite.parse(dev_caller)
57
- payload.merge!(:line => c.line, :filename => c.filename.to_s.gsub(Rails.root.to_s, ''), :method => c.method)
58
- end
61
+ SimpleApm.merge_callsite_payload!(payload)
59
62
  ProcessingThread.add_event(
60
63
  name: name,
61
64
  request_id: request_id,
metadata CHANGED
@@ -1,29 +1,42 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.14
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yuanyin.xia
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2019-05-29 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '8.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '8.1'
26
+ - !ruby/object:Gem::Dependency
27
+ name: sprockets-rails
15
28
  requirement: !ruby/object:Gem::Requirement
16
29
  requirements:
17
30
  - - ">="
18
31
  - !ruby/object:Gem::Version
19
- version: '4.2'
32
+ version: '3.5'
20
33
  type: :runtime
21
34
  prerelease: false
22
35
  version_requirements: !ruby/object:Gem::Requirement
23
36
  requirements:
24
37
  - - ">="
25
38
  - !ruby/object:Gem::Version
26
- version: '4.2'
39
+ version: '3.5'
27
40
  - !ruby/object:Gem::Dependency
28
41
  name: redis-namespace
29
42
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +69,30 @@ dependencies:
56
69
  name: get_process_mem
57
70
  requirement: !ruby/object:Gem::Requirement
58
71
  requirements:
59
- - - "~>"
72
+ - - ">="
60
73
  - !ruby/object:Gem::Version
61
- version: '0'
74
+ version: '1.0'
62
75
  type: :runtime
63
76
  prerelease: false
64
77
  version_requirements: !ruby/object:Gem::Requirement
65
78
  requirements:
66
- - - "~>"
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '1.0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: sqlite3
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '2.1'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
67
94
  - !ruby/object:Gem::Version
68
- version: '0'
95
+ version: '2.1'
69
96
  description: 'xyy: Simple Apm View for rails using redis.'
70
97
  email:
71
98
  - xiayuanyin@qq.com
@@ -115,7 +142,6 @@ homepage: https://github.com/xiayuanyin/simple_apm
115
142
  licenses:
116
143
  - MIT
117
144
  metadata: {}
118
- post_install_message:
119
145
  rdoc_options: []
120
146
  require_paths:
121
147
  - lib
@@ -130,9 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
156
  - !ruby/object:Gem::Version
131
157
  version: '0'
132
158
  requirements: []
133
- rubyforge_project:
134
- rubygems_version: 2.6.14
135
- signing_key:
159
+ rubygems_version: 3.6.9
136
160
  specification_version: 4
137
161
  summary: 'xyy: Simple Rails Apm'
138
162
  test_files: []