appsignal 1.2.0.alpha.1 → 1.2.0.alpha.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/CHANGELOG.md +2 -0
- data/ext/agent.yml +9 -9
- data/ext/appsignal_extension.c +82 -44
- data/lib/appsignal.rb +1 -0
- data/lib/appsignal/config.rb +5 -2
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +2 -4
- data/lib/appsignal/js_exception_transaction.rb +11 -13
- data/lib/appsignal/subscriber.rb +5 -8
- data/lib/appsignal/transaction.rb +34 -15
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +3 -1
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +3 -5
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +8 -12
- data/spec/lib/appsignal/subscriber_spec.rb +11 -13
- data/spec/lib/appsignal/transaction_spec.rb +65 -36
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 933e766ae7c1e093d8550927bb4585607a136935
|
4
|
+
data.tar.gz: 46996d9237382423ffe444ef48e199c3a6db6c0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed0342c7f1be05351ea7ceaed903a153a06b094e186158fab39cb8dcfd354c3b6a694fd02ec9f562c00add31a168ba8b4c2b2739fa8e4b57e98f7d95f1224957
|
7
|
+
data.tar.gz: 6de43ca1045c5200fa0e4355b728a5fd5e2a5d43d90e40a98313e60755968c2a3a378ed14c9f9da166591dfbb42705a509440b32e6ac3b5378a05acb37044138
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# 1.2.0
|
2
2
|
* Restart background thread when FD's are closed
|
3
|
+
* Beta version of collecting host metrics (disabled by default)
|
3
4
|
|
4
5
|
# 1.1.7
|
5
6
|
* Make logging resilient for closing FD's (daemons gem does this)
|
6
7
|
* Add support for using Resque through ActiveJob
|
8
|
+
* Rescue more expections in json generation
|
7
9
|
|
8
10
|
# 1.1.6
|
9
11
|
* Generic Rack instrumentation middleware
|
data/ext/agent.yml
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
---
|
2
|
-
version:
|
2
|
+
version: b9b98f1
|
3
3
|
triples:
|
4
4
|
x86_64-linux:
|
5
|
-
checksum:
|
6
|
-
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/
|
5
|
+
checksum: 69542d576478984d769257fb58639728a937872d35d3f9bb30da986e02d36909
|
6
|
+
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/b9b98f1/appsignal-agent-x86_64-linux-static.tar.gz
|
7
7
|
lib_filename: libappsignal.a
|
8
8
|
i686-linux:
|
9
|
-
checksum:
|
10
|
-
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/
|
9
|
+
checksum: 7bf25f151a255227c8bee0b75b8e8c75adc484f2b418c2dfc760e0a82869ed27
|
10
|
+
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/b9b98f1/appsignal-agent-i686-linux-static.tar.gz
|
11
11
|
lib_filename: libappsignal.a
|
12
12
|
x86-linux:
|
13
|
-
checksum:
|
14
|
-
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/
|
13
|
+
checksum: 7bf25f151a255227c8bee0b75b8e8c75adc484f2b418c2dfc760e0a82869ed27
|
14
|
+
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/b9b98f1/appsignal-agent-i686-linux-static.tar.gz
|
15
15
|
lib_filename: libappsignal.a
|
16
16
|
x86_64-darwin:
|
17
|
-
checksum:
|
18
|
-
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/
|
17
|
+
checksum: c8b0df3b38e9747d468e12bb7d7c6bfdc901b62d6138b5629c3969e78ff6cc4d
|
18
|
+
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/b9b98f1/appsignal-agent-x86_64-darwin-static.tar.gz
|
19
19
|
lib_filename: libappsignal.a
|
data/ext/appsignal_extension.c
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
#include "ruby/ruby.h"
|
2
2
|
#include "appsignal_extension.h"
|
3
3
|
|
4
|
+
VALUE Appsignal;
|
5
|
+
VALUE Extension;
|
6
|
+
VALUE ExtTransaction;
|
7
|
+
|
4
8
|
static VALUE start(VALUE self) {
|
5
9
|
appsignal_start();
|
6
10
|
|
@@ -14,27 +18,43 @@ static VALUE stop(VALUE self) {
|
|
14
18
|
}
|
15
19
|
|
16
20
|
static VALUE start_transaction(VALUE self, VALUE transaction_id, VALUE namespace) {
|
21
|
+
appsignal_transaction* transaction;
|
22
|
+
|
17
23
|
Check_Type(transaction_id, T_STRING);
|
18
24
|
|
19
|
-
|
25
|
+
transaction = appsignal_start_transaction(
|
26
|
+
StringValueCStr(transaction_id),
|
27
|
+
StringValueCStr(namespace)
|
28
|
+
);
|
29
|
+
|
30
|
+
if (transaction) {
|
31
|
+
return Data_Wrap_Struct(ExtTransaction, NULL, appsignal_free_transaction, transaction);
|
32
|
+
} else {
|
33
|
+
return Qnil;
|
34
|
+
}
|
20
35
|
}
|
21
36
|
|
22
|
-
static VALUE start_event(VALUE self
|
23
|
-
|
37
|
+
static VALUE start_event(VALUE self) {
|
38
|
+
appsignal_transaction* transaction;
|
39
|
+
|
40
|
+
Data_Get_Struct(self, appsignal_transaction, transaction);
|
41
|
+
|
42
|
+
appsignal_start_event(transaction);
|
24
43
|
|
25
|
-
appsignal_start_event(FIX2INT(transaction_index));
|
26
44
|
return Qnil;
|
27
45
|
}
|
28
46
|
|
29
|
-
static VALUE finish_event(VALUE self, VALUE
|
30
|
-
|
47
|
+
static VALUE finish_event(VALUE self, VALUE name, VALUE title, VALUE body, VALUE body_format) {
|
48
|
+
appsignal_transaction* transaction;
|
49
|
+
|
31
50
|
Check_Type(name, T_STRING);
|
32
51
|
Check_Type(title, T_STRING);
|
33
52
|
Check_Type(body, T_STRING);
|
34
53
|
Check_Type(body_format, T_FIXNUM);
|
54
|
+
Data_Get_Struct(self, appsignal_transaction, transaction);
|
35
55
|
|
36
56
|
appsignal_finish_event(
|
37
|
-
|
57
|
+
transaction,
|
38
58
|
StringValueCStr(name),
|
39
59
|
StringValueCStr(title),
|
40
60
|
StringValueCStr(body),
|
@@ -43,14 +63,16 @@ static VALUE finish_event(VALUE self, VALUE transaction_index, VALUE name, VALUE
|
|
43
63
|
return Qnil;
|
44
64
|
}
|
45
65
|
|
46
|
-
static VALUE set_transaction_error(VALUE self, VALUE
|
47
|
-
|
66
|
+
static VALUE set_transaction_error(VALUE self, VALUE name, VALUE message, VALUE backtrace) {
|
67
|
+
appsignal_transaction* transaction;
|
68
|
+
|
48
69
|
Check_Type(name, T_STRING);
|
49
70
|
Check_Type(message, T_STRING);
|
50
71
|
Check_Type(backtrace, T_STRING);
|
72
|
+
Data_Get_Struct(self, appsignal_transaction, transaction);
|
51
73
|
|
52
74
|
appsignal_set_transaction_error(
|
53
|
-
|
75
|
+
transaction,
|
54
76
|
StringValueCStr(name),
|
55
77
|
StringValueCStr(message),
|
56
78
|
StringValueCStr(backtrace)
|
@@ -58,67 +80,78 @@ static VALUE set_transaction_error(VALUE self, VALUE transaction_index, VALUE na
|
|
58
80
|
return Qnil;
|
59
81
|
}
|
60
82
|
|
61
|
-
static VALUE set_transaction_sample_data(VALUE self, VALUE
|
62
|
-
|
83
|
+
static VALUE set_transaction_sample_data(VALUE self, VALUE key, VALUE payload) {
|
84
|
+
appsignal_transaction* transaction;
|
85
|
+
|
63
86
|
Check_Type(key, T_STRING);
|
64
87
|
Check_Type(payload, T_STRING);
|
88
|
+
Data_Get_Struct(self, appsignal_transaction, transaction);
|
65
89
|
|
66
90
|
appsignal_set_transaction_sample_data(
|
67
|
-
|
91
|
+
transaction,
|
68
92
|
StringValueCStr(key),
|
69
93
|
StringValueCStr(payload)
|
70
94
|
);
|
71
95
|
return Qnil;
|
72
96
|
}
|
73
97
|
|
74
|
-
static VALUE set_transaction_action(VALUE self, VALUE
|
75
|
-
|
98
|
+
static VALUE set_transaction_action(VALUE self, VALUE action) {
|
99
|
+
appsignal_transaction* transaction;
|
100
|
+
|
76
101
|
Check_Type(action, T_STRING);
|
102
|
+
Data_Get_Struct(self, appsignal_transaction, transaction);
|
77
103
|
|
78
104
|
appsignal_set_transaction_action(
|
79
|
-
|
105
|
+
transaction,
|
80
106
|
StringValueCStr(action)
|
81
107
|
);
|
82
108
|
return Qnil;
|
83
109
|
}
|
84
110
|
|
85
|
-
static VALUE set_transaction_queue_start(VALUE self, VALUE
|
86
|
-
|
111
|
+
static VALUE set_transaction_queue_start(VALUE self, VALUE queue_start) {
|
112
|
+
appsignal_transaction* transaction;
|
113
|
+
|
87
114
|
Check_Type(queue_start, T_FIXNUM);
|
115
|
+
Data_Get_Struct(self, appsignal_transaction, transaction);
|
88
116
|
|
89
117
|
appsignal_set_transaction_queue_start(
|
90
|
-
|
118
|
+
transaction,
|
91
119
|
FIX2LONG(queue_start)
|
92
120
|
);
|
93
121
|
return Qnil;
|
94
122
|
}
|
95
123
|
|
96
|
-
static VALUE set_transaction_metadata(VALUE self, VALUE
|
97
|
-
|
124
|
+
static VALUE set_transaction_metadata(VALUE self, VALUE key, VALUE value) {
|
125
|
+
appsignal_transaction* transaction;
|
126
|
+
|
98
127
|
Check_Type(key, T_STRING);
|
99
128
|
Check_Type(value, T_STRING);
|
129
|
+
Data_Get_Struct(self, appsignal_transaction, transaction);
|
100
130
|
|
101
131
|
appsignal_set_transaction_metadata(
|
102
|
-
|
132
|
+
transaction,
|
103
133
|
StringValueCStr(key),
|
104
134
|
StringValueCStr(value)
|
105
135
|
);
|
106
136
|
return Qnil;
|
107
137
|
}
|
108
138
|
|
109
|
-
static VALUE finish_transaction(VALUE self
|
139
|
+
static VALUE finish_transaction(VALUE self) {
|
140
|
+
appsignal_transaction* transaction;
|
110
141
|
int sample;
|
111
142
|
|
112
|
-
|
143
|
+
Data_Get_Struct(self, appsignal_transaction, transaction);
|
113
144
|
|
114
|
-
sample = appsignal_finish_transaction(
|
145
|
+
sample = appsignal_finish_transaction(transaction);
|
115
146
|
return sample == 1 ? Qtrue : Qfalse;
|
116
147
|
}
|
117
148
|
|
118
|
-
static VALUE complete_transaction(VALUE self
|
119
|
-
|
149
|
+
static VALUE complete_transaction(VALUE self) {
|
150
|
+
appsignal_transaction* transaction;
|
151
|
+
|
152
|
+
Data_Get_Struct(self, appsignal_transaction, transaction);
|
120
153
|
|
121
|
-
appsignal_complete_transaction(
|
154
|
+
appsignal_complete_transaction(transaction);
|
122
155
|
return Qnil;
|
123
156
|
}
|
124
157
|
|
@@ -201,22 +234,27 @@ static VALUE install_gc_event_hooks() {
|
|
201
234
|
}
|
202
235
|
|
203
236
|
void Init_appsignal_extension(void) {
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
rb_define_singleton_method(Extension, "
|
210
|
-
rb_define_singleton_method(Extension, "
|
211
|
-
|
212
|
-
|
213
|
-
rb_define_singleton_method(Extension, "
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
237
|
+
Appsignal = rb_define_module("Appsignal");
|
238
|
+
Extension = rb_define_class_under(Appsignal, "Extension", rb_cObject);
|
239
|
+
ExtTransaction = rb_define_class_under(Extension, "ExtTransaction", rb_cObject);
|
240
|
+
|
241
|
+
// Starting and stopping
|
242
|
+
rb_define_singleton_method(Extension, "start", start, 0);
|
243
|
+
rb_define_singleton_method(Extension, "stop", stop, 0);
|
244
|
+
|
245
|
+
// Start transaction
|
246
|
+
rb_define_singleton_method(Extension, "start_transaction", start_transaction, 2);
|
247
|
+
|
248
|
+
// Transaction instance methods
|
249
|
+
rb_define_method(ExtTransaction, "start_event", start_event, 0);
|
250
|
+
rb_define_method(ExtTransaction, "finish_event", finish_event, 4);
|
251
|
+
rb_define_method(ExtTransaction, "set_error", set_transaction_error, 3);
|
252
|
+
rb_define_method(ExtTransaction, "set_sample_data", set_transaction_sample_data, 2);
|
253
|
+
rb_define_method(ExtTransaction, "set_action", set_transaction_action, 1);
|
254
|
+
rb_define_method(ExtTransaction, "set_queue_start", set_transaction_queue_start, 1);
|
255
|
+
rb_define_method(ExtTransaction, "set_metadata", set_transaction_metadata, 2);
|
256
|
+
rb_define_method(ExtTransaction, "finish", finish_transaction, 0);
|
257
|
+
rb_define_method(ExtTransaction, "complete", complete_transaction, 0);
|
220
258
|
|
221
259
|
// Event hook installation
|
222
260
|
rb_define_singleton_method(Extension, "install_allocation_event_hook", install_allocation_event_hook, 0);
|
data/lib/appsignal.rb
CHANGED
data/lib/appsignal/config.rb
CHANGED
@@ -18,7 +18,8 @@ module Appsignal
|
|
18
18
|
:frontend_error_catching_path => '/appsignal_error_catcher',
|
19
19
|
:enable_allocation_tracking => true,
|
20
20
|
:enable_gc_instrumentation => false,
|
21
|
-
:running_in_container => false
|
21
|
+
:running_in_container => false,
|
22
|
+
:collect_host_metrics => false
|
22
23
|
}.freeze
|
23
24
|
|
24
25
|
ENV_TO_KEY_MAPPING = {
|
@@ -40,7 +41,8 @@ module Appsignal
|
|
40
41
|
'APPSIGNAL_ENABLE_ALLOCATION_TRACKING' => :enable_allocation_tracking,
|
41
42
|
'APPSIGNAL_ENABLE_GC_INSTRUMENTATION' => :enable_gc_instrumentation,
|
42
43
|
'APPSIGNAL_RUNNING_IN_CONTAINER' => :running_in_container,
|
43
|
-
'APPSIGNAL_WORKING_DIR_PATH' => :working_dir_path
|
44
|
+
'APPSIGNAL_WORKING_DIR_PATH' => :working_dir_path,
|
45
|
+
'APPSIGNAL_COLLECT_HOST_METRICS' => :collect_host_metrics
|
44
46
|
}.freeze
|
45
47
|
|
46
48
|
attr_reader :root_path, :env, :initial_config, :config_hash
|
@@ -111,6 +113,7 @@ module Appsignal
|
|
111
113
|
ENV['APPSIGNAL_IGNORE_ACTIONS'] = config_hash[:ignore_actions].join(',')
|
112
114
|
ENV['APPSIGNAL_RUNNING_IN_CONTAINER'] = config_hash[:running_in_container].to_s
|
113
115
|
ENV['APPSIGNAL_WORKING_DIR_PATH'] = config_hash[:working_dir_path] if config_hash[:working_dir_path]
|
116
|
+
ENV['APPSIGNAL_COLLECT_HOST_METRICS'] = config_hash[:collect_host_metrics].to_s
|
114
117
|
end
|
115
118
|
|
116
119
|
protected
|
@@ -16,7 +16,7 @@ module Appsignal
|
|
16
16
|
store[event.request_id] = command
|
17
17
|
|
18
18
|
# Start this event
|
19
|
-
|
19
|
+
transaction.start_event
|
20
20
|
end
|
21
21
|
|
22
22
|
# Called by Mongo::Monitor when query succeeds
|
@@ -42,8 +42,7 @@ module Appsignal
|
|
42
42
|
command = store.delete(event.request_id) || {}
|
43
43
|
|
44
44
|
# Finish the event in the extension.
|
45
|
-
|
46
|
-
transaction.transaction_index,
|
45
|
+
transaction.finish_event(
|
47
46
|
'query.mongodb',
|
48
47
|
"#{event.command_name.to_s} | #{event.database_name} | #{result}",
|
49
48
|
Appsignal::Utils.json_generate(command),
|
@@ -51,6 +50,5 @@ module Appsignal
|
|
51
50
|
)
|
52
51
|
end
|
53
52
|
end
|
54
|
-
|
55
53
|
end
|
56
54
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Appsignal
|
2
2
|
class JSExceptionTransaction
|
3
|
-
attr_reader :uuid, :
|
3
|
+
attr_reader :uuid, :ext
|
4
4
|
|
5
5
|
def initialize(data)
|
6
6
|
@data = data
|
7
7
|
@uuid = SecureRandom.uuid
|
8
|
-
@
|
8
|
+
@ext = Appsignal::Extension.start_transaction(@uuid, Appsignal::Transaction::FRONTEND)
|
9
9
|
|
10
10
|
set_action
|
11
11
|
set_metadata
|
@@ -14,18 +14,17 @@ module Appsignal
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def set_action
|
17
|
-
|
17
|
+
@ext.set_action(@data['action'])
|
18
18
|
end
|
19
19
|
|
20
20
|
def set_metadata
|
21
|
-
|
22
|
-
|
21
|
+
@ext.set_metadata(
|
22
|
+
'path', @data['path']
|
23
23
|
) if @data['path']
|
24
24
|
end
|
25
25
|
|
26
26
|
def set_error
|
27
|
-
|
28
|
-
@transaction_index,
|
27
|
+
@ext.set_error(
|
29
28
|
@data['name'],
|
30
29
|
@data['message'],
|
31
30
|
Appsignal::Utils.json_generate(@data['backtrace'])
|
@@ -40,20 +39,19 @@ module Appsignal
|
|
40
39
|
}.each do |key, data|
|
41
40
|
next unless data.is_a?(Array) || data.is_a?(Hash)
|
42
41
|
begin
|
43
|
-
|
44
|
-
@transaction_index,
|
42
|
+
@ext.set_sample_data(
|
45
43
|
key.to_s,
|
46
44
|
Appsignal::Utils.json_generate(data)
|
47
45
|
)
|
48
|
-
rescue
|
49
|
-
Appsignal.logger.error("
|
46
|
+
rescue *Appsignal::Transaction::JSON_EXCEPTIONS => e
|
47
|
+
Appsignal.logger.error("Error generating JSON (#{e.class}: #{e.message}) for '#{backtrace.inspect}'")
|
50
48
|
end
|
51
49
|
end
|
52
50
|
end
|
53
51
|
|
54
52
|
def complete!
|
55
|
-
|
56
|
-
|
53
|
+
@ext.finish
|
54
|
+
@ext.complete
|
57
55
|
end
|
58
56
|
end
|
59
57
|
end
|
data/lib/appsignal/subscriber.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module Appsignal
|
2
2
|
class Subscriber
|
3
|
-
BLANK = ''.freeze
|
4
|
-
|
5
3
|
attr_reader :as_subscriber
|
6
4
|
|
7
5
|
def initialize
|
@@ -38,7 +36,7 @@ module Appsignal
|
|
38
36
|
return unless transaction = Appsignal::Transaction.current
|
39
37
|
return if transaction.nil_transaction? || transaction.paused?
|
40
38
|
|
41
|
-
|
39
|
+
transaction.start_event
|
42
40
|
end
|
43
41
|
|
44
42
|
def finish(name, id, payload)
|
@@ -46,12 +44,11 @@ module Appsignal
|
|
46
44
|
return if transaction.nil_transaction? || transaction.paused?
|
47
45
|
|
48
46
|
title, body, body_format = Appsignal::EventFormatter.format(name, payload)
|
49
|
-
|
50
|
-
transaction.transaction_index,
|
47
|
+
transaction.finish_event(
|
51
48
|
name,
|
52
|
-
title
|
53
|
-
body
|
54
|
-
body_format
|
49
|
+
title,
|
50
|
+
body,
|
51
|
+
body_format
|
55
52
|
)
|
56
53
|
end
|
57
54
|
end
|
@@ -3,6 +3,7 @@ module Appsignal
|
|
3
3
|
HTTP_REQUEST = 'http_request'.freeze
|
4
4
|
BACKGROUND_JOB = 'background_job'.freeze
|
5
5
|
FRONTEND = 'frontend'.freeze
|
6
|
+
BLANK = ''.freeze
|
6
7
|
|
7
8
|
# Based on what Rails uses + some variables we'd like to show
|
8
9
|
ENV_METHODS = %w(CONTENT_LENGTH AUTH_TYPE GATEWAY_INTERFACE
|
@@ -15,6 +16,13 @@ module Appsignal
|
|
15
16
|
HTTP_CACHE_CONTROL HTTP_CONNECTION HTTP_USER_AGENT HTTP_FROM HTTP_NEGOTIATE
|
16
17
|
HTTP_PRAGMA HTTP_REFERER HTTP_X_FORWARDED_FOR HTTP_CLIENT_IP HTTP_RANGE)
|
17
18
|
|
19
|
+
JSON_EXCEPTIONS = [
|
20
|
+
IOError,
|
21
|
+
NotImplementedError,
|
22
|
+
JSON::GeneratorError,
|
23
|
+
Encoding::UndefinedConversionError
|
24
|
+
].freeze
|
25
|
+
|
18
26
|
class << self
|
19
27
|
def create(id, namespace, request, options={})
|
20
28
|
# Check if we already have a running transaction
|
@@ -43,7 +51,7 @@ module Appsignal
|
|
43
51
|
end
|
44
52
|
end
|
45
53
|
|
46
|
-
attr_reader :
|
54
|
+
attr_reader :ext, :transaction_id, :namespace, :request, :paused, :tags, :options
|
47
55
|
|
48
56
|
def initialize(transaction_id, namespace, request, options={})
|
49
57
|
@transaction_id = transaction_id
|
@@ -55,7 +63,7 @@ module Appsignal
|
|
55
63
|
@options = options
|
56
64
|
@options[:params_method] ||= :params
|
57
65
|
|
58
|
-
@
|
66
|
+
@ext = Appsignal::Extension.start_transaction(@transaction_id, @namespace)
|
59
67
|
end
|
60
68
|
|
61
69
|
def nil_transaction?
|
@@ -63,10 +71,10 @@ module Appsignal
|
|
63
71
|
end
|
64
72
|
|
65
73
|
def complete
|
66
|
-
if
|
74
|
+
if @ext.finish
|
67
75
|
sample_data
|
68
76
|
end
|
69
|
-
|
77
|
+
@ext.complete
|
70
78
|
end
|
71
79
|
|
72
80
|
def pause!
|
@@ -91,7 +99,7 @@ module Appsignal
|
|
91
99
|
|
92
100
|
def set_action(action)
|
93
101
|
return unless action
|
94
|
-
|
102
|
+
@ext.set_action(action)
|
95
103
|
end
|
96
104
|
|
97
105
|
def set_http_or_background_action(from=request.params)
|
@@ -105,7 +113,7 @@ module Appsignal
|
|
105
113
|
|
106
114
|
def set_queue_start(start)
|
107
115
|
return unless start
|
108
|
-
|
116
|
+
@ext.set_queue_start(start)
|
109
117
|
end
|
110
118
|
|
111
119
|
def set_http_or_background_queue_start
|
@@ -118,18 +126,17 @@ module Appsignal
|
|
118
126
|
|
119
127
|
def set_metadata(key, value)
|
120
128
|
return unless key && value
|
121
|
-
|
129
|
+
@ext.set_metadata(key, value)
|
122
130
|
end
|
123
131
|
|
124
132
|
def set_sample_data(key, data)
|
125
133
|
return unless key && data && (data.is_a?(Array) || data.is_a?(Hash))
|
126
|
-
|
127
|
-
transaction_index,
|
134
|
+
@ext.set_sample_data(
|
128
135
|
key.to_s,
|
129
136
|
Appsignal::Utils.json_generate(data)
|
130
137
|
)
|
131
|
-
rescue
|
132
|
-
Appsignal.logger.error("
|
138
|
+
rescue *JSON_EXCEPTIONS => e
|
139
|
+
Appsignal.logger.error("Error generating JSON (#{e.class}: #{e.message}) for '#{data.inspect}'")
|
133
140
|
end
|
134
141
|
|
135
142
|
def sample_data
|
@@ -150,17 +157,29 @@ module Appsignal
|
|
150
157
|
return if Appsignal.is_ignored_error?(error)
|
151
158
|
|
152
159
|
backtrace = cleaned_backtrace(error.backtrace)
|
153
|
-
|
154
|
-
transaction_index,
|
160
|
+
@ext.set_error(
|
155
161
|
error.class.name,
|
156
162
|
error.message.to_s,
|
157
163
|
backtrace ? Appsignal::Utils.json_generate(backtrace) : ''
|
158
164
|
)
|
159
|
-
rescue
|
160
|
-
Appsignal.logger.error("
|
165
|
+
rescue *JSON_EXCEPTIONS => e
|
166
|
+
Appsignal.logger.error("Error generating JSON (#{e.class}: #{e.message}) for '#{backtrace.inspect}'")
|
161
167
|
end
|
162
168
|
alias_method :add_exception, :set_error
|
163
169
|
|
170
|
+
def start_event
|
171
|
+
@ext.start_event
|
172
|
+
end
|
173
|
+
|
174
|
+
def finish_event(name, title, body, body_format)
|
175
|
+
@ext.finish_event(
|
176
|
+
name,
|
177
|
+
title || BLANK,
|
178
|
+
body || BLANK,
|
179
|
+
body_format || 0
|
180
|
+
)
|
181
|
+
end
|
182
|
+
|
164
183
|
class GenericRequest
|
165
184
|
attr_reader :env
|
166
185
|
|
data/lib/appsignal/version.rb
CHANGED
@@ -33,7 +33,8 @@ describe Appsignal::Config do
|
|
33
33
|
:frontend_error_catching_path => '/appsignal_error_catcher',
|
34
34
|
:enable_allocation_tracking => true,
|
35
35
|
:enable_gc_instrumentation => false,
|
36
|
-
:running_in_container => false
|
36
|
+
:running_in_container => false,
|
37
|
+
:collect_host_metrics => false
|
37
38
|
}
|
38
39
|
end
|
39
40
|
|
@@ -112,6 +113,7 @@ describe Appsignal::Config do
|
|
112
113
|
ENV['APPSIGNAL_IGNORE_ACTIONS'].should == 'action1,action2'
|
113
114
|
ENV['APPSIGNAL_RUNNING_IN_CONTAINER'].should == 'false'
|
114
115
|
ENV['APPSIGNAL_WORKING_DIR_PATH'].should be_nil
|
116
|
+
ENV['APPSIGNAL_COLLECT_HOST_METRICS'].should == 'false'
|
115
117
|
end
|
116
118
|
|
117
119
|
context "if working_dir_path is set" do
|
@@ -31,10 +31,9 @@ describe Appsignal::Hooks::MongoMonitorSubscriber do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should start an event in the extension" do
|
34
|
-
|
35
|
-
.with(transaction.transaction_index)
|
34
|
+
transaction.should receive(:start_event)
|
36
35
|
|
37
|
-
|
36
|
+
subscriber.started(event)
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
@@ -80,8 +79,7 @@ describe Appsignal::Hooks::MongoMonitorSubscriber do
|
|
80
79
|
end
|
81
80
|
|
82
81
|
it "should finish the transaction in the extension" do
|
83
|
-
|
84
|
-
transaction.transaction_index,
|
82
|
+
transaction.should receive(:finish_event).with(
|
85
83
|
'query.mongodb',
|
86
84
|
'find | test | SUCCEEDED',
|
87
85
|
"{\"foo\":\"?\"}",
|
@@ -32,15 +32,14 @@ describe Appsignal::JSExceptionTransaction do
|
|
32
32
|
|
33
33
|
transaction.send :initialize, data
|
34
34
|
|
35
|
-
expect( transaction.
|
35
|
+
expect( transaction.ext ).not_to be_nil
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
describe "#set_base_data" do
|
40
40
|
it "should call `Appsignal::Extension.set_transaction_basedata`" do
|
41
|
-
expect(
|
42
|
-
|
43
|
-
'ExceptionIncidentComponent',
|
41
|
+
expect( transaction.ext ).to receive(:set_action).with(
|
42
|
+
'ExceptionIncidentComponent'
|
44
43
|
)
|
45
44
|
|
46
45
|
transaction.set_action
|
@@ -49,8 +48,7 @@ describe Appsignal::JSExceptionTransaction do
|
|
49
48
|
|
50
49
|
describe "#set_metadata" do
|
51
50
|
it "should call `Appsignal::Extension.set_transaction_metadata`" do
|
52
|
-
expect(
|
53
|
-
kind_of(Integer),
|
51
|
+
expect( transaction.ext ).to receive(:set_metadata).with(
|
54
52
|
'path',
|
55
53
|
'foo.bar/moo'
|
56
54
|
)
|
@@ -61,8 +59,7 @@ describe Appsignal::JSExceptionTransaction do
|
|
61
59
|
|
62
60
|
describe "#set_error" do
|
63
61
|
it "should call `Appsignal::Extension.set_transaction_error`" do
|
64
|
-
expect(
|
65
|
-
kind_of(Integer),
|
62
|
+
expect( transaction.ext ).to receive(:set_error).with(
|
66
63
|
'TypeError',
|
67
64
|
'foo is not a valid method',
|
68
65
|
"[\"foo.bar/js:11:1\",\"foo.bar/js:22:2\"]"
|
@@ -74,8 +71,7 @@ describe Appsignal::JSExceptionTransaction do
|
|
74
71
|
|
75
72
|
describe "#set_sample_data" do
|
76
73
|
it "should call `Appsignal::Extension.set_transaction_error_data`" do
|
77
|
-
expect(
|
78
|
-
kind_of(Integer),
|
74
|
+
expect( transaction.ext ).to receive(:set_sample_data).with(
|
79
75
|
'tags',
|
80
76
|
'["tag1"]'
|
81
77
|
)
|
@@ -86,8 +82,8 @@ describe Appsignal::JSExceptionTransaction do
|
|
86
82
|
|
87
83
|
describe "#complete!" do
|
88
84
|
it "should call all required methods" do
|
89
|
-
expect(
|
90
|
-
expect(
|
85
|
+
expect( transaction.ext ).to receive(:finish)
|
86
|
+
expect( transaction.ext ).to receive(:complete)
|
91
87
|
transaction.complete!
|
92
88
|
end
|
93
89
|
end
|
@@ -97,11 +97,11 @@ describe Appsignal::Subscriber do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
it "should call native start and finish event for every event" do
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
transaction.should_receive(:start_event).exactly(4).times
|
101
|
+
transaction.should_receive(:finish_event).with('one', nil, nil, nil).once
|
102
|
+
transaction.should_receive(:finish_event).with('two', nil, nil, nil).once
|
103
|
+
transaction.should_receive(:finish_event).with('two.three', nil, nil, nil).once
|
104
|
+
transaction.should_receive(:finish_event).with('one.three', nil, nil, nil).once
|
105
105
|
|
106
106
|
ActiveSupport::Notifications.instrument('one') do
|
107
107
|
ActiveSupport::Notifications.instrument('two') do
|
@@ -114,13 +114,12 @@ describe Appsignal::Subscriber do
|
|
114
114
|
end
|
115
115
|
|
116
116
|
it "should call finish with title and body if there is a formatter" do
|
117
|
-
|
118
|
-
|
119
|
-
kind_of(Integer),
|
117
|
+
transaction.should_receive(:start_event).once
|
118
|
+
transaction.should_receive(:finish_event).with(
|
120
119
|
'request.net_http',
|
121
120
|
'GET http://www.google.com',
|
122
|
-
|
123
|
-
|
121
|
+
nil,
|
122
|
+
nil
|
124
123
|
).once
|
125
124
|
|
126
125
|
ActiveSupport::Notifications.instrument(
|
@@ -132,9 +131,8 @@ describe Appsignal::Subscriber do
|
|
132
131
|
end
|
133
132
|
|
134
133
|
it "should call finish with title, body and body format if there is a formatter that returns it" do
|
135
|
-
|
136
|
-
|
137
|
-
kind_of(Integer),
|
134
|
+
transaction.should_receive(:start_event).once
|
135
|
+
transaction.should_receive(:finish_event).with(
|
138
136
|
'sql.active_record',
|
139
137
|
'Something load',
|
140
138
|
'SELECT * FROM something',
|
@@ -96,7 +96,7 @@ describe Appsignal::Transaction do
|
|
96
96
|
before { Appsignal::Transaction.create('2', Appsignal::Transaction::HTTP_REQUEST, {}) }
|
97
97
|
|
98
98
|
it "should complete the current transaction and set the thread appsignal_transaction to nil" do
|
99
|
-
Appsignal::
|
99
|
+
Appsignal::Transaction.current.should_receive(:complete)
|
100
100
|
|
101
101
|
Appsignal::Transaction.complete_current!
|
102
102
|
|
@@ -104,7 +104,7 @@ describe Appsignal::Transaction do
|
|
104
104
|
end
|
105
105
|
|
106
106
|
it "should still clear the transaction if there is an error" do
|
107
|
-
Appsignal::
|
107
|
+
Appsignal::Transaction.current.should_receive(:complete).and_raise 'Error'
|
108
108
|
|
109
109
|
Appsignal::Transaction.complete_current!
|
110
110
|
|
@@ -115,17 +115,17 @@ describe Appsignal::Transaction do
|
|
115
115
|
|
116
116
|
describe "#complete" do
|
117
117
|
it "should sample data if it needs to be sampled" do
|
118
|
-
|
119
|
-
Appsignal::Extension.should_receive(:complete_transaction)
|
118
|
+
transaction.ext.should_receive(:finish).and_return(true)
|
120
119
|
transaction.should_receive(:sample_data)
|
120
|
+
transaction.ext.should_receive(:complete)
|
121
121
|
|
122
122
|
transaction.complete
|
123
123
|
end
|
124
124
|
|
125
125
|
it "should not sample data if it does not need to be sampled" do
|
126
|
-
|
127
|
-
Appsignal::Extension.should_receive(:complete_transaction)
|
126
|
+
transaction.ext.should_receive(:finish).and_return(false)
|
128
127
|
transaction.should_not_receive(:sample_data)
|
128
|
+
transaction.ext.should_receive(:complete)
|
129
129
|
|
130
130
|
transaction.complete
|
131
131
|
end
|
@@ -170,13 +170,12 @@ describe Appsignal::Transaction do
|
|
170
170
|
context "initialization" do
|
171
171
|
subject { transaction }
|
172
172
|
|
173
|
+
its(:ext) { should_not be_nil }
|
173
174
|
its(:transaction_id) { should == '1' }
|
174
175
|
its(:namespace) { should == 'http_request' }
|
175
|
-
its(:transaction_index) { should be_a Integer }
|
176
176
|
its(:request) { should_not be_nil }
|
177
177
|
its(:paused) { should be_false }
|
178
178
|
its(:tags) { should == {} }
|
179
|
-
its(:transaction_index) { should be_a Integer }
|
180
179
|
|
181
180
|
context "options" do
|
182
181
|
subject { transaction.options }
|
@@ -214,8 +213,7 @@ describe Appsignal::Transaction do
|
|
214
213
|
|
215
214
|
describe "set_action" do
|
216
215
|
it "should set the action in extension" do
|
217
|
-
|
218
|
-
kind_of(Integer),
|
216
|
+
transaction.ext.should_receive(:set_action).with(
|
219
217
|
'PagesController#show'
|
220
218
|
).once
|
221
219
|
|
@@ -259,8 +257,7 @@ describe Appsignal::Transaction do
|
|
259
257
|
|
260
258
|
describe "set_queue_start" do
|
261
259
|
it "should set the queue start in extension" do
|
262
|
-
|
263
|
-
kind_of(Integer),
|
260
|
+
transaction.ext.should_receive(:set_queue_start).with(
|
264
261
|
10.0
|
265
262
|
).once
|
266
263
|
|
@@ -268,7 +265,7 @@ describe Appsignal::Transaction do
|
|
268
265
|
end
|
269
266
|
|
270
267
|
it "should not set the queue start in extension when value is nil" do
|
271
|
-
|
268
|
+
transaction.ext.should_not_receive(:set_queue_start)
|
272
269
|
|
273
270
|
transaction.set_queue_start(nil)
|
274
271
|
end
|
@@ -300,8 +297,7 @@ describe Appsignal::Transaction do
|
|
300
297
|
|
301
298
|
describe "#set_metadata" do
|
302
299
|
it "should set the metdata in extension" do
|
303
|
-
|
304
|
-
kind_of(Integer),
|
300
|
+
transaction.ext.should_receive(:set_metadata).with(
|
305
301
|
'request_method',
|
306
302
|
'GET'
|
307
303
|
).once
|
@@ -310,7 +306,7 @@ describe Appsignal::Transaction do
|
|
310
306
|
end
|
311
307
|
|
312
308
|
it "should not set the metdata in extension when value is nil" do
|
313
|
-
|
309
|
+
transaction.ext.should_not_receive(:set_metadata)
|
314
310
|
|
315
311
|
transaction.set_metadata('request_method', nil)
|
316
312
|
end
|
@@ -318,8 +314,7 @@ describe Appsignal::Transaction do
|
|
318
314
|
|
319
315
|
describe "set_sample_data" do
|
320
316
|
it "should generate json and set the data" do
|
321
|
-
|
322
|
-
kind_of(Integer),
|
317
|
+
transaction.ext.should_receive(:set_sample_data).with(
|
323
318
|
'params',
|
324
319
|
'{"controller":"blog_posts","action":"show","id":"1"}'
|
325
320
|
).once
|
@@ -335,8 +330,7 @@ describe Appsignal::Transaction do
|
|
335
330
|
end
|
336
331
|
|
337
332
|
it "should do nothing if the data cannot be converted to json" do
|
338
|
-
|
339
|
-
kind_of(Integer),
|
333
|
+
transaction.ext.should_not_receive(:set_sample_data).with(
|
340
334
|
'params',
|
341
335
|
kind_of(String)
|
342
336
|
)
|
@@ -347,28 +341,23 @@ describe Appsignal::Transaction do
|
|
347
341
|
|
348
342
|
describe "#sample_data" do
|
349
343
|
it "should sample data" do
|
350
|
-
|
351
|
-
kind_of(Integer),
|
344
|
+
transaction.ext.should_receive(:set_sample_data).with(
|
352
345
|
'environment',
|
353
346
|
"{\"CONTENT_LENGTH\":\"0\",\"REQUEST_METHOD\":\"GET\",\"SERVER_NAME\":\"example.org\",\"SERVER_PORT\":\"80\",\"PATH_INFO\":\"/blog\"}"
|
354
347
|
).once
|
355
|
-
|
356
|
-
kind_of(Integer),
|
348
|
+
transaction.ext.should_receive(:set_sample_data).with(
|
357
349
|
'session_data',
|
358
350
|
"{}"
|
359
351
|
).once
|
360
|
-
|
361
|
-
kind_of(Integer),
|
352
|
+
transaction.ext.should_receive(:set_sample_data).with(
|
362
353
|
'params',
|
363
354
|
'{"controller":"blog_posts","action":"show","id":"1"}'
|
364
355
|
).once
|
365
|
-
|
366
|
-
kind_of(Integer),
|
356
|
+
transaction.ext.should_receive(:set_sample_data).with(
|
367
357
|
'metadata',
|
368
358
|
'{"key":"value"}'
|
369
359
|
).once
|
370
|
-
|
371
|
-
kind_of(Integer),
|
360
|
+
transaction.ext.should_receive(:set_sample_data).with(
|
372
361
|
'tags',
|
373
362
|
"{}"
|
374
363
|
).once
|
@@ -387,22 +376,21 @@ describe Appsignal::Transaction do
|
|
387
376
|
|
388
377
|
it "should not add the error if it's in the ignored list" do
|
389
378
|
Appsignal.stub(:is_ignored_error? => true)
|
390
|
-
|
379
|
+
transaction.ext.should_not_receive(:set_error)
|
391
380
|
|
392
381
|
transaction.set_error(error)
|
393
382
|
end
|
394
383
|
|
395
384
|
it "should not add the error if appsignal is not active" do
|
396
385
|
Appsignal.stub(:active? => false)
|
397
|
-
|
386
|
+
transaction.ext.should_not_receive(:set_error)
|
398
387
|
|
399
388
|
transaction.set_error(error)
|
400
389
|
end
|
401
390
|
|
402
391
|
context "for a http request" do
|
403
392
|
it "should set an error in the extension" do
|
404
|
-
|
405
|
-
kind_of(Integer),
|
393
|
+
transaction.ext.should_receive(:set_error).with(
|
406
394
|
'RSpec::Mocks::Mock',
|
407
395
|
'test message',
|
408
396
|
"[\"line 1\"]"
|
@@ -420,8 +408,7 @@ describe Appsignal::Transaction do
|
|
420
408
|
end
|
421
409
|
|
422
410
|
it "should set an error in the extension" do
|
423
|
-
|
424
|
-
kind_of(Integer),
|
411
|
+
transaction.ext.should_receive(:set_error).with(
|
425
412
|
'RSpec::Mocks::Mock',
|
426
413
|
'',
|
427
414
|
"[\"line 1\"]"
|
@@ -432,6 +419,48 @@ describe Appsignal::Transaction do
|
|
432
419
|
end
|
433
420
|
end
|
434
421
|
|
422
|
+
describe "#start_event" do
|
423
|
+
it "should start the event in the extension" do
|
424
|
+
transaction.ext.should_receive(:start_event)
|
425
|
+
|
426
|
+
transaction.start_event
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
describe "finish_event" do
|
431
|
+
it "should finish the event in the extension" do
|
432
|
+
transaction.ext.should_receive(:finish_event).with(
|
433
|
+
'name',
|
434
|
+
'title',
|
435
|
+
'body',
|
436
|
+
1
|
437
|
+
)
|
438
|
+
|
439
|
+
transaction.finish_event(
|
440
|
+
'name',
|
441
|
+
'title',
|
442
|
+
'body',
|
443
|
+
1
|
444
|
+
)
|
445
|
+
end
|
446
|
+
|
447
|
+
it "should finish the event in the extension with nil arguments" do
|
448
|
+
transaction.ext.should_receive(:finish_event).with(
|
449
|
+
'name',
|
450
|
+
'',
|
451
|
+
'',
|
452
|
+
0
|
453
|
+
)
|
454
|
+
|
455
|
+
transaction.finish_event(
|
456
|
+
'name',
|
457
|
+
nil,
|
458
|
+
nil,
|
459
|
+
nil
|
460
|
+
)
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
435
464
|
context "generic request" do
|
436
465
|
let(:env) { {} }
|
437
466
|
subject { Appsignal::Transaction::GenericRequest.new(env) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appsignal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.0.alpha.
|
4
|
+
version: 1.2.0.alpha.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-05-
|
12
|
+
date: 2016-05-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|