builder_apm 0.3.2 → 0.4.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.
- checksums.yaml +4 -4
- data/app/controllers/builder_apm/request_data_controller.rb +6 -17
- data/app/views/builder_apm/error_requests/index.html.erb +1 -1
- data/app/views/builder_apm/js/_dashboard.html.erb +7 -6
- data/app/views/builder_apm/js/_data_fetcher.html.erb +3 -23
- data/app/views/builder_apm/js/_error_requests.html.erb +5 -8
- data/app/views/builder_apm/js/_n_plus_one.html.erb +6 -9
- data/app/views/builder_apm/js/_recent_requests.html.erb +7 -11
- data/app/views/builder_apm/js/_request_analysis.html.erb +1 -0
- data/app/views/builder_apm/js/_slow_requests.html.erb +7 -8
- data/app/views/builder_apm/n_plus_one/index.html.erb +3 -3
- data/app/views/builder_apm/recent_requests/index.html.erb +3 -3
- data/app/views/builder_apm/slow_requests/index.html.erb +3 -3
- data/lib/builder_apm/middleware/timing.rb +72 -19
- data/lib/builder_apm/models/instrumenter.rb +1 -1
- data/lib/builder_apm/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bbbfb5298b7a84fda6ffbc495937ac3cd7f0615a892971f7013de6d43a1c8aa
|
4
|
+
data.tar.gz: d598f00dc01dd754deefe947d974a74f678ea046a7ad251d91aa509307d91385
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05f73adf32d4b1243b507757525163a5a7f6896e07374be8618b868196d716fad628b98780e9aa7fe30d6ddf2b3ded694c87c798eefc5a844555c303f7bde6f6
|
7
|
+
data.tar.gz: '0149a38a394eb52f942554154f45a248796a6e30045888c8479e368f524428a70f87d3660e3f3899a5a027857701e8a727d7730ad898c30f55a5b5e17776a97b'
|
@@ -1,41 +1,30 @@
|
|
1
1
|
module BuilderApm
|
2
2
|
class RequestDataController < ApplicationController
|
3
3
|
def index
|
4
|
-
cursor = params[:cursor].presence&.to_f || Time.now.to_f
|
4
|
+
cursor = params[:cursor].presence&.to_f || Time.now.to_f * 1000
|
5
5
|
limit = params[:limit].presence&.to_i || 50
|
6
6
|
type = params[:type].presence || 'timestamps'
|
7
7
|
|
8
8
|
purge_old_keys
|
9
9
|
@requests = retrieve_data_from_redis_since(cursor, limit, type)
|
10
|
-
|
10
|
+
Rails.logger.info "#{@requests.size} results gathered"
|
11
11
|
render json: @requests
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def purge_old_keys
|
17
|
-
time_limit = (Time.now -
|
17
|
+
time_limit = (Time.now - 2.hour).to_f * 1000
|
18
18
|
redis_client.zremrangebyscore('builder_apm:timestamps', '-inf', time_limit)
|
19
19
|
redis_client.zremrangebyscore('builder_apm:errors', '-inf', time_limit)
|
20
20
|
redis_client.zremrangebyscore('builder_apm:n_plus_one', '-inf', time_limit)
|
21
21
|
redis_client.zremrangebyscore('builder_apm:slow', '-inf', time_limit)
|
22
|
+
redis_client.zremrangebyscore('builder_apm:dashboard', '-inf', time_limit)
|
22
23
|
end
|
23
24
|
|
24
25
|
def retrieve_data_from_redis_since(cursor, limit, type)
|
25
|
-
|
26
|
-
|
27
|
-
keys = redis_client.zrevrangebyscore("builder_apm:#{type}", cursor, "-inf", limit: [0, limit])
|
28
|
-
# else
|
29
|
-
# keys = redis_client.lrange("builder_apm:#{type}", 0, -1)
|
30
|
-
# end
|
31
|
-
|
32
|
-
keys = keys.map { |key| "builder_apm:Request:#{key}" }
|
33
|
-
data = keys.empty? ? [] : redis_client.mget(*keys)
|
34
|
-
begin
|
35
|
-
data.map { |d| JSON.parse(d) }
|
36
|
-
rescue => e
|
37
|
-
raise e
|
38
|
-
end
|
26
|
+
data = redis_client.zrevrangebyscore("builder_apm:#{type}", cursor, "-inf", limit: [0, limit])
|
27
|
+
data.map{ |d| JSON.parse(d) }
|
39
28
|
end
|
40
29
|
end
|
41
30
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
<thead>
|
5
5
|
<tr>
|
6
6
|
<th class="sortable" data-field="start_time">Time</th>
|
7
|
-
<th class="sortable" data-field="
|
7
|
+
<th class="sortable" data-field="controller_action">Controller#Action</th>
|
8
8
|
<th class="sortable" data-field="method">Method</th>
|
9
9
|
<th class="sortable" data-field="status">Status</th>
|
10
10
|
<th class="sortable" data-field="exception_class">Error Class</th>
|
@@ -5,6 +5,7 @@ google.charts.load('current', {packages: ['corechart', 'line']});
|
|
5
5
|
google.charts.setOnLoadCallback(drawCharts);
|
6
6
|
|
7
7
|
function drawCharts() {
|
8
|
+
limit = 3000
|
8
9
|
prepareChartData(aggregationInterval);
|
9
10
|
autoFetchDataAndUpdateStorage(function(updatedData){
|
10
11
|
// Render the table with the updated data
|
@@ -39,14 +40,14 @@ function prepareChartData(aggregationInterval) {
|
|
39
40
|
|
40
41
|
// Add current request data to interval totals
|
41
42
|
aggregatedData[timeKey]['count'] += 1;
|
42
|
-
aggregatedData[timeKey]['totalDuration'] += (item['
|
43
|
-
aggregatedData[timeKey]['totalDbRuntime'] += item['
|
43
|
+
aggregatedData[timeKey]['totalDuration'] += (item['duration']);
|
44
|
+
aggregatedData[timeKey]['totalDbRuntime'] += item['db_runtime'];
|
44
45
|
aggregatedData[timeKey]['totalViewRuntime'] += item['view_runtime'];
|
45
|
-
aggregatedData[timeKey]['totalOther'] += item['
|
46
|
+
aggregatedData[timeKey]['totalOther'] += item['duration'] - item['db_runtime'] - item['view_runtime'];
|
46
47
|
// aggregatedData[timeKey]['durations'].push(item['duration']);
|
47
|
-
// aggregatedData[timeKey]['totalDbRuntime'] += item['
|
48
|
-
// aggregatedData[timeKey]['totalViewRuntime'] += item['
|
49
|
-
// aggregatedData[timeKey]['totalOther'] += item['
|
48
|
+
// aggregatedData[timeKey]['totalDbRuntime'] += item['duration']*0.35;
|
49
|
+
// aggregatedData[timeKey]['totalViewRuntime'] += item['duration']*0.45;
|
50
|
+
// aggregatedData[timeKey]['totalOther'] += item['duration']*0.2;
|
50
51
|
});
|
51
52
|
|
52
53
|
|
@@ -8,6 +8,7 @@ var current_sort_field = 'real_start_time';
|
|
8
8
|
var start_time = Date.now();
|
9
9
|
var data_gathered_counter = 0;
|
10
10
|
var time_cursor = <%= Time.now.to_f * 1000 %>;
|
11
|
+
var limit = 500;
|
11
12
|
|
12
13
|
function fetchDataAndUpdateStorage(onSuccess) {
|
13
14
|
start_time = Date.now();
|
@@ -20,7 +21,6 @@ function fetchDataAndUpdateStorage(onSuccess) {
|
|
20
21
|
|
21
22
|
}
|
22
23
|
function fetchAndProcessData(cursor, onSuccess) {
|
23
|
-
var limit = 1000;
|
24
24
|
var type = typeof fetch_type !== 'undefined' ? fetch_type : 'timestamps';
|
25
25
|
|
26
26
|
// Make an AJAX request to fetch latest data
|
@@ -29,26 +29,6 @@ function fetchAndProcessData(cursor, onSuccess) {
|
|
29
29
|
newData = newData.map(request => calcDurations(request));
|
30
30
|
|
31
31
|
processData(allData, null, newData, onSuccess);
|
32
|
-
|
33
|
-
// Find the latest request in the newly fetched data
|
34
|
-
// var latestRequest = newData.reduce((latest, current) => current.real_end_time > latest.real_end_time ? current : latest, newData[0]);
|
35
|
-
|
36
|
-
// 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
|
37
|
-
// if (data_gathered_counter < 5 && latestRequest && latestRequest.real_end_time < start_time && newData.length === limit) {
|
38
|
-
// fetchAndProcessData(var time_cursor = <%= Time.now.to_f * 1000 %>;, onSuccess);
|
39
|
-
// } else {
|
40
|
-
// try {
|
41
|
-
// // Store the updated data back to local storage
|
42
|
-
// compress(JSON.stringify(allData), function(result, error) {
|
43
|
-
// if(result != null) {
|
44
|
-
// localStorage.setItem('builder_apm_requests', result);
|
45
|
-
// }
|
46
|
-
// });
|
47
|
-
// } catch(e) {
|
48
|
-
// console.error("Error storing data to local storage. Might be out of storage space.", e);
|
49
|
-
// alert('not enough local storage')
|
50
|
-
// }
|
51
|
-
// onSuccess(allData);
|
52
32
|
|
53
33
|
});
|
54
34
|
}
|
@@ -78,7 +58,7 @@ function processData(storedData, error, newData, onSuccess) {
|
|
78
58
|
// Update the cursor
|
79
59
|
if (newData.length > 0) {
|
80
60
|
var lastRequest = newData[newData.length - 1];
|
81
|
-
time_cursor = lastRequest.
|
61
|
+
time_cursor = lastRequest.end_time-0.001;
|
82
62
|
}
|
83
63
|
} catch(e) {
|
84
64
|
console.error("Error storing data to local storage. Might be out of storage space.", e);
|
@@ -220,7 +200,7 @@ function getNPlusOneRequests(requestArray) {
|
|
220
200
|
function aggregateRequests(requestArray) {
|
221
201
|
let aggregates = {};
|
222
202
|
requestArray.forEach(request => {
|
223
|
-
let key = `${request.
|
203
|
+
let key = `${request.controller_action}`;
|
224
204
|
if (!aggregates[key]) {
|
225
205
|
aggregates[key] = {
|
226
206
|
count: 0,
|
@@ -40,7 +40,7 @@ $(document).ready(function() {
|
|
40
40
|
var row = $('<tr>');
|
41
41
|
|
42
42
|
$('<td>').text(new Date(item['start_time']).toLocaleString()).appendTo(row);
|
43
|
-
$('<td>').addClass('long_text').text(item['
|
43
|
+
$('<td>').addClass('long_text').text(item['controller_action']).appendTo(row);
|
44
44
|
$('<td>').text(item['method']).appendTo(row);
|
45
45
|
$('<td>').text(item['status']).appendTo(row);
|
46
46
|
$('<td>').append(item['exception_class']).appendTo(row);
|
@@ -57,13 +57,10 @@ $(document).ready(function() {
|
|
57
57
|
|
58
58
|
// Action column
|
59
59
|
var actionTd = $('<td>');
|
60
|
-
var
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
window.location.href = '<%= request_details_path %>?request_id=' + item['request_id'];
|
65
|
-
});
|
66
|
-
actionButton.appendTo(actionTd);
|
60
|
+
var actionLink = $('<a>').text('Details');
|
61
|
+
actionLink.attr('href', '<%= request_details_path %>?request_id=' + item['request_id']);
|
62
|
+
actionLink.attr('target', '_blank');
|
63
|
+
actionLink.appendTo(actionTd);
|
67
64
|
actionTd.appendTo(row);
|
68
65
|
|
69
66
|
// Append the row to the table body
|
@@ -39,22 +39,19 @@ $(document).ready(function() {
|
|
39
39
|
var row = $('<tr>');
|
40
40
|
|
41
41
|
$('<td>').text(new Date(item['start_time']).toLocaleString()).appendTo(row);
|
42
|
-
$('<td>').addClass('long_text').text(item['
|
42
|
+
$('<td>').addClass('long_text').text(item['controller_action']).appendTo(row);
|
43
43
|
$('<td>').text(item['method']).appendTo(row);
|
44
44
|
$('<td>').text(item['status']).appendTo(row);
|
45
45
|
$('<td>').append(renderDuration(item['duration'])).appendTo(row);
|
46
46
|
$('<td>').append(renderDuration(item['db_runtime'])).appendTo(row);
|
47
47
|
$('<td>').append(renderDuration(item['view_runtime'])).appendTo(row);
|
48
48
|
// Action column
|
49
|
+
|
49
50
|
var actionTd = $('<td>');
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
actionLink.attr('href', '<%= request_details_path %>?request_id=' + item['request_id']);
|
55
|
-
actionLink.attr('target', '_blank');
|
56
|
-
actionLink.appendTo(actionTd);
|
57
|
-
}
|
51
|
+
var actionLink = $('<a>').text('Details');
|
52
|
+
actionLink.attr('href', '<%= request_details_path %>?request_id=' + item['request_id']);
|
53
|
+
actionLink.attr('target', '_blank');
|
54
|
+
actionLink.appendTo(actionTd);
|
58
55
|
actionTd.appendTo(row);
|
59
56
|
|
60
57
|
// Append the row to the table body
|
@@ -42,22 +42,18 @@ $(document).ready(function() {
|
|
42
42
|
var row = $('<tr>');
|
43
43
|
|
44
44
|
$('<td>').text(new Date(item['start_time']).toLocaleString()).appendTo(row);
|
45
|
-
$('<td>').addClass('long_text').text(item['
|
45
|
+
$('<td>').addClass('long_text').text(item['controller_action']).appendTo(row);
|
46
46
|
$('<td>').text(item['method']).appendTo(row);
|
47
47
|
$('<td>').text(item['status']).appendTo(row);
|
48
|
-
$('<td>').append(renderDuration(item['
|
49
|
-
$('<td>').append(renderDuration(item['
|
48
|
+
$('<td>').append(renderDuration(item['duration'])).appendTo(row);
|
49
|
+
$('<td>').append(renderDuration(item['db_runtime'])).appendTo(row);
|
50
50
|
$('<td>').append(renderDuration(item['view_runtime'])).appendTo(row);
|
51
51
|
// Action column
|
52
52
|
var actionTd = $('<td>');
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
actionLink.attr('href', '<%= request_details_path %>?request_id=' + item['request_id']);
|
58
|
-
actionLink.attr('target', '_blank');
|
59
|
-
actionLink.appendTo(actionTd);
|
60
|
-
}
|
53
|
+
var actionLink = $('<a>').text('Details');
|
54
|
+
actionLink.attr('href', '<%= request_details_path %>?request_id=' + item['request_id']);
|
55
|
+
actionLink.attr('target', '_blank');
|
56
|
+
actionLink.appendTo(actionTd);
|
61
57
|
actionTd.appendTo(row);
|
62
58
|
|
63
59
|
// Append the row to the table body
|
@@ -40,7 +40,7 @@ $(document).ready(function() {
|
|
40
40
|
var row = $('<tr>');
|
41
41
|
|
42
42
|
$('<td>').text(new Date(item['start_time']).toLocaleString()).appendTo(row);
|
43
|
-
$('<td>').addClass('long_text').text(item['
|
43
|
+
$('<td>').addClass('long_text').text(item['controller_action']).appendTo(row);
|
44
44
|
$('<td>').text(item['method']).appendTo(row);
|
45
45
|
$('<td>').text(item['status']).appendTo(row);
|
46
46
|
$('<td>').append(renderDuration(item['duration'])).appendTo(row);
|
@@ -49,13 +49,12 @@ $(document).ready(function() {
|
|
49
49
|
// Action column
|
50
50
|
var actionTd = $('<td>');
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
}
|
52
|
+
|
53
|
+
var actionTd = $('<td>');
|
54
|
+
var actionLink = $('<a>').text('Details');
|
55
|
+
actionLink.attr('href', '<%= request_details_path %>?request_id=' + item['request_id']);
|
56
|
+
actionLink.attr('target', '_blank');
|
57
|
+
actionLink.appendTo(actionTd);
|
59
58
|
actionTd.appendTo(row);
|
60
59
|
|
61
60
|
// Append the row to the table body
|
@@ -4,11 +4,11 @@
|
|
4
4
|
<thead>
|
5
5
|
<tr>
|
6
6
|
<th class="sortable" data-field="start_time">Time</th>
|
7
|
-
<th class="sortable" data-field="
|
7
|
+
<th class="sortable" data-field="controller_action">Controller#Action</th>
|
8
8
|
<th class="sortable" data-field="method">Method</th>
|
9
9
|
<th class="sortable" data-field="status">Status</th>
|
10
|
-
<th class="sortable" data-field="
|
11
|
-
<th class="sortable" data-field="
|
10
|
+
<th class="sortable" data-field="duration_time">Duration (ms)</th>
|
11
|
+
<th class="sortable" data-field="db_runtime">DB Runtime (ms)</th>
|
12
12
|
<th class="sortable" data-field="view_runtime">View Runtime (ms)</th>
|
13
13
|
</tr>
|
14
14
|
</thead>
|
@@ -4,11 +4,11 @@
|
|
4
4
|
<thead>
|
5
5
|
<tr>
|
6
6
|
<th class="sortable" data-field="start_time">Time</th>
|
7
|
-
<th class="sortable" data-field="
|
7
|
+
<th class="sortable" data-field="controller_action">Controller#Action</th>
|
8
8
|
<th class="sortable" data-field="method">Method</th>
|
9
9
|
<th class="sortable" data-field="status">Status</th>
|
10
|
-
<th class="sortable" data-field="
|
11
|
-
<th class="sortable" data-field="
|
10
|
+
<th class="sortable" data-field="duration_time">Duration (ms)</th>
|
11
|
+
<th class="sortable" data-field="db_runtime">DB Runtime (ms)</th>
|
12
12
|
<th class="sortable" data-field="view_runtime">View Runtime (ms)</th>
|
13
13
|
</tr>
|
14
14
|
</thead>
|
@@ -4,11 +4,11 @@
|
|
4
4
|
<thead>
|
5
5
|
<tr>
|
6
6
|
<th class="sortable" data-field="start_time">Time</th>
|
7
|
-
<th class="sortable" data-field="
|
7
|
+
<th class="sortable" data-field="controller_action">Controller#Action</th>
|
8
8
|
<th class="sortable" data-field="method">Method</th>
|
9
9
|
<th class="sortable" data-field="status">Status</th>
|
10
|
-
<th class="sortable" data-field="
|
11
|
-
<th class="sortable" data-field="
|
10
|
+
<th class="sortable" data-field="duration_time">Duration (ms)</th>
|
11
|
+
<th class="sortable" data-field="db_runtime">DB Runtime (ms)</th>
|
12
12
|
<th class="sortable" data-field="view_runtime">View Runtime (ms)</th>
|
13
13
|
</tr>
|
14
14
|
</thead>
|
@@ -8,9 +8,10 @@ module BuilderApm
|
|
8
8
|
|
9
9
|
def call(env)
|
10
10
|
request_id = env["action_dispatch.request_id"]
|
11
|
-
Thread.current[
|
11
|
+
Thread.current[:request_id] = request_id
|
12
12
|
Thread.current[:n_plus_one_duration] = 0
|
13
13
|
Thread.current[:has_n_plus_one] = false
|
14
|
+
Thread.current[:db_runtime] = 0
|
14
15
|
start_time = Time.now.to_f * 1000
|
15
16
|
|
16
17
|
@status, @headers, @response = @app.call(env)
|
@@ -20,47 +21,99 @@ module BuilderApm
|
|
20
21
|
end_time = Time.now.to_f * 1000
|
21
22
|
handle_timing(start_time, end_time, request_id)
|
22
23
|
|
23
|
-
|
24
|
-
Thread.current[:has_n_plus_one] = nil
|
25
|
-
Thread.current[:n_plus_one_duration] = nil
|
24
|
+
clean_up_thread_values
|
26
25
|
|
27
26
|
[@status, @headers, @response]
|
28
27
|
end
|
29
28
|
|
30
29
|
private
|
31
30
|
|
31
|
+
def clean_up_thread_values
|
32
|
+
Thread.current['request_data'] = nil
|
33
|
+
Thread.current[:request_id] = nil
|
34
|
+
Thread.current[:has_n_plus_one] = nil
|
35
|
+
Thread.current[:n_plus_one_duration] = nil
|
36
|
+
Thread.current[:db_runtime] = nil
|
37
|
+
Thread.current[:stack] = nil
|
38
|
+
Thread.current[:sql_event_id] = nil
|
39
|
+
end
|
40
|
+
|
32
41
|
def handle_timing(start_time, end_time, request_id)
|
33
42
|
duration = end_time - start_time;
|
34
43
|
data = Thread.current['request_data']
|
35
44
|
|
36
45
|
if data
|
46
|
+
data[:controller] = data[:controller].gsub("::", ":") if data[:controller]
|
37
47
|
data[:has_n_plus_one] = Thread.current[:has_n_plus_one]
|
38
48
|
data[:n_plus_one_duration] = Thread.current[:n_plus_one_duration]
|
39
49
|
data[:real_start_time] = start_time
|
40
50
|
data[:real_end_time] = end_time
|
51
|
+
data[:calc_db_runtime] = Thread.current[:db_runtime]
|
41
52
|
data[:real_duration_time] = end_time - start_time
|
42
53
|
data[:stack][0][:start_time] = start_time
|
43
54
|
data[:stack][0][:end_time] = end_time
|
44
55
|
data[:stack][0][:duration] = end_time - start_time
|
45
56
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
save_to_redis(data)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def save_to_redis(data)
|
62
|
+
begin
|
63
|
+
@redis_client.pipelined do |pipeline|
|
64
|
+
pipeline.rpush("builder_apm:Analysis:#{data[:controller]}##{data[:action]}:duration", data[:real_duration_time]||0)
|
65
|
+
pipeline.rpush("builder_apm:Analysis:#{data[:controller]}##{data[:action]}:db_runtime", data[:db_runtime]||0)
|
66
|
+
pipeline.rpush("builder_apm:Analysis:#{data[:controller]}##{data[:action]}:view_runtime", data[:view_runtime]||0)
|
67
|
+
end_time = data[:real_end_time]
|
68
|
+
simplfied_data = table_data(data)
|
69
|
+
pipeline.zadd("builder_apm:dashboard", end_time, dashboard_data(data))
|
70
|
+
pipeline.zadd("builder_apm:timestamps", end_time, simplfied_data)
|
71
|
+
pipeline.zadd("builder_apm:errors", end_time, table_data_with_errors(data)) if data[:status] == 500
|
72
|
+
pipeline.zadd("builder_apm:n_plus_one", end_time, simplfied_data) if data[:has_n_plus_one]
|
73
|
+
pipeline.zadd("builder_apm:slow", end_time, simplfied_data) if data[:real_duration_time] > 1500
|
74
|
+
ttl = (2.hour + 1.minute).to_i
|
75
|
+
pipeline.set("builder_apm:Request:#{data[:request_id]}", data.to_json, ex: ttl)
|
61
76
|
end
|
77
|
+
rescue => e
|
78
|
+
Rails.logger.error "Redis Missing?"
|
79
|
+
Rails.logger.error e.message
|
80
|
+
Rails.logger.error e.backtrace
|
62
81
|
end
|
63
82
|
end
|
83
|
+
|
84
|
+
def dashboard_data(data)
|
85
|
+
JSON.dump({
|
86
|
+
start_time: data[:real_start_time],
|
87
|
+
duration: data[:real_duration_time],
|
88
|
+
db_runtime: data[:calc_db_runtime],
|
89
|
+
view_runtime: data[:view_runtime]
|
90
|
+
})
|
91
|
+
end
|
92
|
+
|
93
|
+
def table_data_with_errors(data)
|
94
|
+
tbl_data = table_data(data, false)
|
95
|
+
|
96
|
+
tbl_data[:exception_class] = data[:exception_class] || ""
|
97
|
+
tbl_data[:exception_message] = data[:exception_message] || ""
|
98
|
+
tbl_data[:exception_backtrace] = data[:exception_backtrace] || []
|
99
|
+
|
100
|
+
JSON.dump(tbl_data)
|
101
|
+
end
|
102
|
+
|
103
|
+
def table_data(data, jsonify = true)
|
104
|
+
tbl_data = {
|
105
|
+
start_time: data[:real_start_time],
|
106
|
+
end_time: data[:real_end_time],
|
107
|
+
controller_action: "#{data[:controller]}##{data[:action]}",
|
108
|
+
method: data[:method],
|
109
|
+
status: data[:status],
|
110
|
+
duration: data[:real_duration_time],
|
111
|
+
db_runtime: data[:calc_db_runtime] > 0 ? data[:calc_db_runtime] : data[:db_runtime],
|
112
|
+
view_runtime: data[:view_runtime],
|
113
|
+
request_id: data[:request_id]
|
114
|
+
}
|
115
|
+
jsonify ? JSON.dump(tbl_data) : tbl_data
|
116
|
+
end
|
64
117
|
end
|
65
118
|
end
|
66
119
|
end
|
@@ -19,7 +19,7 @@ module BuilderApm
|
|
19
19
|
return if name == "SCHEMA" || Thread.current[:request_id].nil?
|
20
20
|
|
21
21
|
triggering_line = determine_triggering_line(caller)
|
22
|
-
|
22
|
+
Thread.current[:db_runtime] += event.duration
|
23
23
|
sql_query_data = build_sql_query_data(event, triggering_line)
|
24
24
|
store_sql_query_data(sql_query_data)
|
25
25
|
end
|
data/lib/builder_apm/version.rb
CHANGED
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: builder_apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Ketelle
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
11
|
date: 2023-07-26 00:00:00.000000000 Z
|
@@ -113,11 +113,11 @@ files:
|
|
113
113
|
- lib/generators/builder_apm/templates/builder_apm_config.rb
|
114
114
|
- lib/generators/builder_apm/templates/create_builder_apm_requests.rb
|
115
115
|
- lib/generators/builder_apm/templates/create_builder_apm_sql_queries.rb
|
116
|
-
homepage:
|
116
|
+
homepage:
|
117
117
|
licenses:
|
118
118
|
- MIT
|
119
119
|
metadata: {}
|
120
|
-
post_install_message:
|
120
|
+
post_install_message:
|
121
121
|
rdoc_options: []
|
122
122
|
require_paths:
|
123
123
|
- lib
|
@@ -132,8 +132,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
132
|
- !ruby/object:Gem::Version
|
133
133
|
version: '0'
|
134
134
|
requirements: []
|
135
|
-
rubygems_version: 3.
|
136
|
-
signing_key:
|
135
|
+
rubygems_version: 3.1.4
|
136
|
+
signing_key:
|
137
137
|
specification_version: 4
|
138
138
|
summary: Write a short summary, because RubyGems requires one.
|
139
139
|
test_files: []
|