builder_apm 0.2.4 → 0.2.5
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/app/controllers/builder_apm/request_data_controller.rb +0 -1
- data/app/views/builder_apm/error_requests/index.html.erb +1 -0
- data/app/views/builder_apm/js/_data_fetcher.html.erb +49 -29
- data/app/views/builder_apm/js/_error_requests.html.erb +1 -0
- data/app/views/builder_apm/js/_n_plus_one.html.erb +1 -0
- data/app/views/builder_apm/js/_recent_requests.html.erb +1 -0
- data/app/views/builder_apm/js/_request_analysis.html.erb +1 -0
- data/app/views/builder_apm/js/_slow_requests.html.erb +1 -0
- data/app/views/builder_apm/n_plus_one/index.html.erb +1 -0
- data/app/views/builder_apm/recent_requests/index.html.erb +1 -0
- data/app/views/builder_apm/request_analysis/index.html.erb +1 -0
- data/app/views/builder_apm/slow_requests/index.html.erb +1 -0
- data/lib/builder_apm/controllers/instrumenter.rb +3 -5
- data/lib/builder_apm/middleware/timing.rb +6 -2
- data/lib/builder_apm/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cbbeca0fe7a6139175c8b354026859775e2f5db9666bc3ac74d2d19a411e46b
|
4
|
+
data.tar.gz: a571a27eb27d78926e237109863c07277e7cf90e8fe4b902f8545ac36a01c788
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '049b33f6202dbd35201bcd9cf39fe26abc199fac70864ea0707956f03d2a532135793cdd8980cbcebf8faff2c8ed62fdaf41a97d5f31f898780214314a7e4edb'
|
7
|
+
data.tar.gz: a04010fe3649dd05172dc2a4bfc4036f1bb1b886a1e2c91d4b0bd6f6563d4a1fec8174a07f0f4e75b1eb7ea688eb10c0ff4c87ec181899e9a657fbe530d40c82
|
@@ -5,6 +5,7 @@
|
|
5
5
|
<tr>
|
6
6
|
<th class="sortable" data-field="start_time">Time</th>
|
7
7
|
<th class="sortable" data-field="controller">Controller#Action</th>
|
8
|
+
<th class="sortable" data-field="method">Method</th>
|
8
9
|
<th class="sortable" data-field="status">Status</th>
|
9
10
|
<th class="sortable" data-field="exception_class">Error Class</th>
|
10
11
|
<th class="sortable" data-field="exception_message">Error Message</th>
|
@@ -5,32 +5,56 @@
|
|
5
5
|
var allData = null;
|
6
6
|
var isAsc = false;
|
7
7
|
var current_sort_field = 'real_start_time';
|
8
|
+
var start_time = Date.now();
|
8
9
|
|
9
10
|
function fetchDataAndUpdateStorage(onSuccess) {
|
10
|
-
|
11
|
-
var
|
12
|
-
var
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
start_time = Date.now();
|
12
|
+
var initialCursor = localStorage.getItem('builder_apm_cursor') || "-inf";
|
13
|
+
var storedData = localStorage.getItem('builder_apm_requests');
|
14
|
+
if (storedData) {
|
15
|
+
var dataCompressed = decompress(storedData, function(result, error) {
|
16
|
+
allData = JSON.parse(result) || [];
|
17
|
+
fetchAndProcessData(initialCursor, onSuccess);
|
18
|
+
});
|
19
|
+
} else {
|
20
|
+
allData = [];
|
21
|
+
// Start fetching data
|
22
|
+
fetchAndProcessData(initialCursor, onSuccess);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
function fetchAndProcessData(cursor, onSuccess) {
|
26
|
+
// Get the last request time
|
27
|
+
var limit = 100;
|
28
|
+
|
29
|
+
// Make an AJAX request to fetch latest data
|
30
|
+
$.get('/builder_apm/request_data?cursor=' + cursor + '&limit=' + limit, function(newData) {
|
31
|
+
|
32
|
+
newData = newData.map(request => calcDurations(request));
|
33
|
+
|
20
34
|
processData(allData, null, newData, onSuccess);
|
21
|
-
|
22
|
-
//
|
23
|
-
var
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
35
|
+
|
36
|
+
// Find the latest request in the newly fetched data
|
37
|
+
var latestRequest = newData.reduce((latest, current) => current.real_end_time > latest.real_end_time ? current : latest, newData[0]);
|
38
|
+
|
39
|
+
// If latest request's end_time is less than start_time, and there's more data (received data is equal to limit), fetch next batch
|
40
|
+
if (latestRequest && latestRequest.real_end_time < start_time && newData.length === limit) {
|
41
|
+
fetchAndProcessData(localStorage.getItem('builder_apm_cursor'), onSuccess);
|
28
42
|
} else {
|
29
|
-
|
43
|
+
try {
|
44
|
+
// Store the updated data back to local storage
|
45
|
+
compress(JSON.stringify(allData), function(result, error) {
|
46
|
+
if(result != null) {
|
47
|
+
localStorage.setItem('builder_apm_requests', result);
|
48
|
+
}
|
49
|
+
});
|
50
|
+
} catch(e) {
|
51
|
+
console.error("Error storing data to local storage. Might be out of storage space.", e);
|
52
|
+
alert('not enough local storage')
|
53
|
+
}
|
54
|
+
onSuccess(allData);
|
30
55
|
}
|
31
|
-
}
|
32
|
-
}
|
33
|
-
}
|
56
|
+
});
|
57
|
+
}
|
34
58
|
|
35
59
|
function loadLocalData(onSuccess) {
|
36
60
|
if(allData) {
|
@@ -42,6 +66,7 @@ function loadLocalData(onSuccess) {
|
|
42
66
|
processData(JSON.parse(result), error, [], onSuccess);
|
43
67
|
});
|
44
68
|
} else {
|
69
|
+
allData = [];
|
45
70
|
fetchDataAndUpdateStorage(onSuccess);
|
46
71
|
}
|
47
72
|
}
|
@@ -52,12 +77,6 @@ function processData(storedData, error, newData, onSuccess) {
|
|
52
77
|
// Append the new data to the stored data
|
53
78
|
allData = storedData.concat(newData);
|
54
79
|
try {
|
55
|
-
// Store the updated data back to local storage
|
56
|
-
compress(JSON.stringify(allData), function(result, error) {
|
57
|
-
if(result != null) {
|
58
|
-
localStorage.setItem('builder_apm_requests', result);
|
59
|
-
}
|
60
|
-
});
|
61
80
|
|
62
81
|
// Update the cursor
|
63
82
|
if (newData.length > 0) {
|
@@ -183,7 +202,7 @@ function getNPlusOneRequests(requestArray) {
|
|
183
202
|
function aggregateRequests(requestArray) {
|
184
203
|
let aggregates = {};
|
185
204
|
requestArray.forEach(request => {
|
186
|
-
let key = `${request.controller}#${request.method}|${request.path}`;
|
205
|
+
let key = `${request.controller}#${request.action}|${request.method}|${request.path}`;
|
187
206
|
if (!aggregates[key]) {
|
188
207
|
aggregates[key] = {
|
189
208
|
count: 0,
|
@@ -206,9 +225,10 @@ function aggregateRequests(requestArray) {
|
|
206
225
|
|
207
226
|
let results = [];
|
208
227
|
for (let key in aggregates) {
|
209
|
-
let [controller, path] = key.split('|');
|
228
|
+
let [controller, method, path] = key.split('|');
|
210
229
|
results.push({
|
211
230
|
controller,
|
231
|
+
method,
|
212
232
|
path,
|
213
233
|
count: aggregates[key].count,
|
214
234
|
averageDuration: aggregates[key].totalDuration / aggregates[key].count,
|
@@ -33,6 +33,7 @@ $(document).ready(function() {
|
|
33
33
|
|
34
34
|
$('<td>').text(new Date(item['start_time']).toLocaleString()).appendTo(row);
|
35
35
|
$('<td>').text(item['controller'] + '#' + item['action']).appendTo(row);
|
36
|
+
$('<td>').text(item['method']).appendTo(row);
|
36
37
|
$('<td>').text(item['status']).appendTo(row);
|
37
38
|
$('<td>').append(item['exception_class']).appendTo(row);
|
38
39
|
$('<td>').append(item['exception_message']).appendTo(row);
|
@@ -32,6 +32,7 @@ $(document).ready(function() {
|
|
32
32
|
|
33
33
|
$('<td>').text(new Date(item['start_time']).toLocaleString()).appendTo(row);
|
34
34
|
$('<td>').text(item['controller'] + '#' + item['action']).appendTo(row);
|
35
|
+
$('<td>').text(item['method']).appendTo(row);
|
35
36
|
$('<td>').text(item['status']).appendTo(row);
|
36
37
|
$('<td>').append(renderDuration(item['duration'])).appendTo(row);
|
37
38
|
$('<td>').append(renderDuration(item['db_runtime'])).appendTo(row);
|
@@ -36,6 +36,7 @@ $(document).ready(function() {
|
|
36
36
|
|
37
37
|
$('<td>').text(new Date(item['start_time']).toLocaleString()).appendTo(row);
|
38
38
|
$('<td>').text(item['controller'] + '#' + item['action']).appendTo(row);
|
39
|
+
$('<td>').text(item['method']).appendTo(row);
|
39
40
|
$('<td>').text(item['status']).appendTo(row);
|
40
41
|
$('<td>').append(renderDuration(item['real_duration_time'])).appendTo(row);
|
41
42
|
$('<td>').append(renderDuration(item['calc_db_runtime'])).appendTo(row);
|
@@ -31,6 +31,7 @@ $(document).ready(function() {
|
|
31
31
|
var row = $('<tr>');
|
32
32
|
|
33
33
|
$('<td>').text(item['controller']).appendTo(row);
|
34
|
+
$('<td>').text(item['method']).appendTo(row);
|
34
35
|
$('<td>').text(item['path']).appendTo(row);
|
35
36
|
$('<td>').text(item['count']).appendTo(row);
|
36
37
|
$('<td>').append(renderDuration(item['averageDuration'])).appendTo(row);
|
@@ -32,6 +32,7 @@ $(document).ready(function() {
|
|
32
32
|
|
33
33
|
$('<td>').text(new Date(item['start_time']).toLocaleString()).appendTo(row);
|
34
34
|
$('<td>').text(item['controller'] + '#' + item['action']).appendTo(row);
|
35
|
+
$('<td>').text(item['method']).appendTo(row);
|
35
36
|
$('<td>').text(item['status']).appendTo(row);
|
36
37
|
$('<td>').append(renderDuration(item['duration'])).appendTo(row);
|
37
38
|
$('<td>').append(renderDuration(item['db_runtime'])).appendTo(row);
|
@@ -5,6 +5,7 @@
|
|
5
5
|
<tr>
|
6
6
|
<th class="sortable" data-field="start_time">Time</th>
|
7
7
|
<th class="sortable" data-field="controller">Controller#Action</th>
|
8
|
+
<th class="sortable" data-field="method">Method</th>
|
8
9
|
<th class="sortable" data-field="status">Status</th>
|
9
10
|
<th class="sortable" data-field="real_duration_time">Duration (ms)</th>
|
10
11
|
<th class="sortable" data-field="calc_db_runtime">DB Runtime (ms)</th>
|
@@ -5,6 +5,7 @@
|
|
5
5
|
<tr>
|
6
6
|
<th class="sortable" data-field="start_time">Time</th>
|
7
7
|
<th class="sortable" data-field="controller">Controller#Action</th>
|
8
|
+
<th class="sortable" data-field="method">Method</th>
|
8
9
|
<th class="sortable" data-field="status">Status</th>
|
9
10
|
<th class="sortable" data-field="real_duration_time">Duration (ms)</th>
|
10
11
|
<th class="sortable" data-field="calc_db_runtime">DB Runtime (ms)</th>
|
@@ -4,6 +4,7 @@
|
|
4
4
|
<thead>
|
5
5
|
<tr>
|
6
6
|
<th class="sortable" data-field="controller">Controller#Action</th>
|
7
|
+
<th class="sortable" data-field="method">Method</th>
|
7
8
|
<th class="sortable" data-field="path">Url</th>
|
8
9
|
<th class="sortable" data-field="count">Requests</th>
|
9
10
|
<th class="sortable" data-field="averageDuration">Avg Duration (ms)</th>
|
@@ -5,6 +5,7 @@
|
|
5
5
|
<tr>
|
6
6
|
<th class="sortable" data-field="start_time">Time</th>
|
7
7
|
<th class="sortable" data-field="controller">Controller#Action</th>
|
8
|
+
<th class="sortable" data-field="method">Method</th>
|
8
9
|
<th class="sortable" data-field="status">Status</th>
|
9
10
|
<th class="sortable" data-field="real_duration_time">Duration (ms)</th>
|
10
11
|
<th class="sortable" data-field="calc_db_runtime">DB Runtime (ms)</th>
|
@@ -55,14 +55,12 @@ module BuilderApm
|
|
55
55
|
view_runtime: event.payload[:view_runtime],
|
56
56
|
stack: Thread.current[:stack]
|
57
57
|
}
|
58
|
-
|
59
|
-
if event.payload[:exception_object]
|
58
|
+
if event.payload[:exception_object]
|
60
59
|
exception = event.payload[:exception_object]
|
61
|
-
status = ActionDispatch::ExceptionWrapper.new(Rails.
|
62
|
-
data[:status] = status
|
60
|
+
data[:status] = ActionDispatch::ExceptionWrapper.new(Rails.application.routes, exception).status_code
|
63
61
|
data[:exception_class] = exception.class
|
64
62
|
data[:exception_message] = exception.message
|
65
|
-
data[:exception_backtrace] = exception.backtrace
|
63
|
+
data[:exception_backtrace] = exception.backtrace
|
66
64
|
end
|
67
65
|
|
68
66
|
data
|
@@ -33,8 +33,12 @@ module BuilderApm
|
|
33
33
|
data[:real_duration_time] = end_time - start_time
|
34
34
|
Thread.current['request_data'] = nil
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
begin
|
37
|
+
@redis_client.zadd("builder_apm:timestamps", end_time, request_id)
|
38
|
+
@redis_client.set("builder_apm:Request:#{data[:request_id]}", data.to_json)
|
39
|
+
rescue => e
|
40
|
+
Rails.logger.error "Redis Missing"
|
41
|
+
end
|
38
42
|
end
|
39
43
|
end
|
40
44
|
end
|
data/lib/builder_apm/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: builder_apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Ketelle
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-07-
|
11
|
+
date: 2023-07-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|