appsignal 4.2.0 → 4.5.17
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 +443 -0
- data/README.md +0 -3
- data/Rakefile +1 -1
- data/appsignal.gemspec +2 -1
- data/build_matrix.yml +33 -0
- data/ext/agent.rb +27 -27
- data/ext/appsignal_extension.c +90 -73
- data/ext/base.rb +3 -1
- data/lib/appsignal/check_in/event.rb +55 -0
- data/lib/appsignal/check_in/scheduler.rb +8 -2
- data/lib/appsignal/check_in.rb +9 -8
- data/lib/appsignal/config.rb +36 -15
- data/lib/appsignal/custom_marker.rb +72 -0
- data/lib/appsignal/environment.rb +1 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +4 -6
- data/lib/appsignal/event_formatter/view_component/render_formatter.rb +4 -6
- data/lib/appsignal/helpers/instrumentation.rb +5 -0
- data/lib/appsignal/hooks/active_job.rb +25 -5
- data/lib/appsignal/hooks/at_exit.rb +18 -4
- data/lib/appsignal/hooks/ownership.rb +44 -0
- data/lib/appsignal/hooks.rb +1 -0
- data/lib/appsignal/integrations/capistrano/appsignal.cap +4 -8
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +8 -11
- data/lib/appsignal/integrations/http.rb +2 -1
- data/lib/appsignal/integrations/ownership.rb +51 -0
- data/lib/appsignal/integrations/rake.rb +14 -2
- data/lib/appsignal/integrations/sidekiq.rb +14 -3
- data/lib/appsignal/internal_errors.rb +19 -0
- data/lib/appsignal/logger.rb +121 -69
- data/lib/appsignal/marker.rb +1 -1
- data/lib/appsignal/probes/sidekiq.rb +5 -1
- data/lib/appsignal/rack/body_wrapper.rb +1 -1
- data/lib/appsignal/rack/event_handler.rb +7 -5
- data/lib/appsignal/transaction.rb +91 -13
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +82 -11
- data/resources/cacert.pem +164 -87
- metadata +8 -4
data/ext/appsignal_extension.c
CHANGED
@@ -15,6 +15,30 @@ static inline VALUE make_ruby_string(appsignal_string_t string) {
|
|
15
15
|
return str;
|
16
16
|
}
|
17
17
|
|
18
|
+
const rb_data_type_t transaction_data_type = {
|
19
|
+
.wrap_struct_name = "Appsignal::Extension::Transaction",
|
20
|
+
.function = {
|
21
|
+
.dfree = appsignal_free_transaction,
|
22
|
+
},
|
23
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
24
|
+
};
|
25
|
+
|
26
|
+
const rb_data_type_t data_data_type = {
|
27
|
+
.wrap_struct_name = "Appsignal::Extension::Data",
|
28
|
+
.function = {
|
29
|
+
.dfree = appsignal_free_data,
|
30
|
+
},
|
31
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
32
|
+
};
|
33
|
+
|
34
|
+
const rb_data_type_t span_data_type = {
|
35
|
+
.wrap_struct_name = "Appsignal::Extension::Span",
|
36
|
+
.function = {
|
37
|
+
.dfree = appsignal_free_span,
|
38
|
+
},
|
39
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
40
|
+
};
|
41
|
+
|
18
42
|
VALUE Appsignal;
|
19
43
|
VALUE Extension;
|
20
44
|
VALUE Transaction;
|
@@ -64,7 +88,7 @@ static VALUE start_transaction(VALUE self, VALUE transaction_id, VALUE namespace
|
|
64
88
|
);
|
65
89
|
|
66
90
|
if (transaction) {
|
67
|
-
return
|
91
|
+
return TypedData_Wrap_Struct(Transaction, &transaction_data_type, transaction);
|
68
92
|
} else {
|
69
93
|
return Qnil;
|
70
94
|
}
|
@@ -75,7 +99,7 @@ static VALUE start_event(VALUE self, VALUE gc_duration_ms) {
|
|
75
99
|
|
76
100
|
Check_Type(gc_duration_ms, T_FIXNUM);
|
77
101
|
|
78
|
-
|
102
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
79
103
|
|
80
104
|
appsignal_start_event(transaction, NUM2LONG(gc_duration_ms));
|
81
105
|
|
@@ -91,7 +115,7 @@ static VALUE finish_event(VALUE self, VALUE name, VALUE title, VALUE body, VALUE
|
|
91
115
|
Check_Type(title, T_STRING);
|
92
116
|
Check_Type(body_format, T_FIXNUM);
|
93
117
|
|
94
|
-
|
118
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
95
119
|
|
96
120
|
body_type = TYPE(body);
|
97
121
|
if (body_type == T_STRING) {
|
@@ -103,8 +127,8 @@ static VALUE finish_event(VALUE self, VALUE name, VALUE title, VALUE body, VALUE
|
|
103
127
|
FIX2INT(body_format),
|
104
128
|
FIX2LONG(gc_duration_ms)
|
105
129
|
);
|
106
|
-
} else if (body_type ==
|
107
|
-
|
130
|
+
} else if (body_type == T_DATA) {
|
131
|
+
TypedData_Get_Struct(body, appsignal_data_t, &data_data_type, body_data);
|
108
132
|
appsignal_finish_event_data(
|
109
133
|
transaction,
|
110
134
|
make_appsignal_string(name),
|
@@ -134,7 +158,7 @@ static VALUE record_event(VALUE self, VALUE name, VALUE title, VALUE body, VALUE
|
|
134
158
|
}
|
135
159
|
Check_Type(body_format, T_FIXNUM);
|
136
160
|
|
137
|
-
|
161
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
138
162
|
|
139
163
|
body_type = TYPE(body);
|
140
164
|
if (body_type == T_STRING) {
|
@@ -147,8 +171,8 @@ static VALUE record_event(VALUE self, VALUE name, VALUE title, VALUE body, VALUE
|
|
147
171
|
NUM2LONG(duration),
|
148
172
|
NUM2LONG(gc_duration_ms)
|
149
173
|
);
|
150
|
-
} else if (body_type ==
|
151
|
-
|
174
|
+
} else if (body_type == T_DATA) {
|
175
|
+
TypedData_Get_Struct(body, appsignal_data_t, &data_data_type, body_data);
|
152
176
|
appsignal_record_event_data(
|
153
177
|
transaction,
|
154
178
|
make_appsignal_string(name),
|
@@ -171,10 +195,10 @@ static VALUE set_transaction_error(VALUE self, VALUE name, VALUE message, VALUE
|
|
171
195
|
|
172
196
|
Check_Type(name, T_STRING);
|
173
197
|
Check_Type(message, T_STRING);
|
174
|
-
Check_Type(backtrace, RUBY_T_DATA);
|
175
198
|
|
176
|
-
|
177
|
-
|
199
|
+
backtrace_data = rb_check_typeddata(backtrace, &data_data_type);
|
200
|
+
|
201
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
178
202
|
|
179
203
|
appsignal_set_transaction_error(
|
180
204
|
transaction,
|
@@ -190,10 +214,10 @@ static VALUE set_transaction_sample_data(VALUE self, VALUE key, VALUE payload) {
|
|
190
214
|
appsignal_data_t* payload_data;
|
191
215
|
|
192
216
|
Check_Type(key, T_STRING);
|
193
|
-
Check_Type(payload, RUBY_T_DATA);
|
194
217
|
|
195
|
-
|
196
|
-
|
218
|
+
payload_data = rb_check_typeddata(payload, &data_data_type);
|
219
|
+
|
220
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
197
221
|
|
198
222
|
appsignal_set_transaction_sample_data(
|
199
223
|
transaction,
|
@@ -207,7 +231,7 @@ static VALUE set_transaction_action(VALUE self, VALUE action) {
|
|
207
231
|
appsignal_transaction_t* transaction;
|
208
232
|
|
209
233
|
Check_Type(action, T_STRING);
|
210
|
-
|
234
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
211
235
|
|
212
236
|
appsignal_set_transaction_action(
|
213
237
|
transaction,
|
@@ -220,7 +244,7 @@ static VALUE set_transaction_namespace(VALUE self, VALUE namespace) {
|
|
220
244
|
appsignal_transaction_t* transaction;
|
221
245
|
|
222
246
|
Check_Type(namespace, T_STRING);
|
223
|
-
|
247
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
224
248
|
|
225
249
|
appsignal_set_transaction_namespace(
|
226
250
|
transaction,
|
@@ -238,7 +262,7 @@ static VALUE set_transaction_queue_start(VALUE self, VALUE queue_start) {
|
|
238
262
|
rb_raise(rb_eTypeError, "queue_start should be an Integer");
|
239
263
|
}
|
240
264
|
|
241
|
-
|
265
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
242
266
|
|
243
267
|
appsignal_set_transaction_queue_start(
|
244
268
|
transaction,
|
@@ -252,7 +276,7 @@ static VALUE set_transaction_metadata(VALUE self, VALUE key, VALUE value) {
|
|
252
276
|
|
253
277
|
Check_Type(key, T_STRING);
|
254
278
|
Check_Type(value, T_STRING);
|
255
|
-
|
279
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
256
280
|
|
257
281
|
appsignal_set_transaction_metadata(
|
258
282
|
transaction,
|
@@ -267,7 +291,7 @@ static VALUE finish_transaction(VALUE self, VALUE gc_duration_ms) {
|
|
267
291
|
int sample;
|
268
292
|
|
269
293
|
Check_Type(gc_duration_ms, T_FIXNUM);
|
270
|
-
|
294
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
271
295
|
|
272
296
|
sample = appsignal_finish_transaction(transaction, NUM2LONG(gc_duration_ms));
|
273
297
|
return sample == 1 ? Qtrue : Qfalse;
|
@@ -278,7 +302,7 @@ static VALUE duplicate_transaction(VALUE self, VALUE new_transaction_id) {
|
|
278
302
|
appsignal_transaction_t* duplicate_transaction;
|
279
303
|
|
280
304
|
Check_Type(new_transaction_id, T_STRING);
|
281
|
-
|
305
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
282
306
|
|
283
307
|
duplicate_transaction = appsignal_duplicate_transaction(
|
284
308
|
transaction,
|
@@ -286,10 +310,9 @@ static VALUE duplicate_transaction(VALUE self, VALUE new_transaction_id) {
|
|
286
310
|
);
|
287
311
|
|
288
312
|
if (duplicate_transaction) {
|
289
|
-
return
|
313
|
+
return TypedData_Wrap_Struct(
|
290
314
|
Transaction,
|
291
|
-
|
292
|
-
appsignal_free_transaction,
|
315
|
+
&transaction_data_type,
|
293
316
|
duplicate_transaction
|
294
317
|
);
|
295
318
|
} else {
|
@@ -300,7 +323,7 @@ static VALUE duplicate_transaction(VALUE self, VALUE new_transaction_id) {
|
|
300
323
|
static VALUE complete_transaction(VALUE self) {
|
301
324
|
appsignal_transaction_t* transaction;
|
302
325
|
|
303
|
-
|
326
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
304
327
|
|
305
328
|
appsignal_complete_transaction(transaction);
|
306
329
|
return Qnil;
|
@@ -310,7 +333,7 @@ static VALUE transaction_to_json(VALUE self) {
|
|
310
333
|
appsignal_transaction_t* transaction;
|
311
334
|
appsignal_string_t json;
|
312
335
|
|
313
|
-
|
336
|
+
TypedData_Get_Struct(self, appsignal_transaction_t, &transaction_data_type, transaction);
|
314
337
|
|
315
338
|
json = appsignal_transaction_to_json(transaction);
|
316
339
|
|
@@ -327,7 +350,7 @@ static VALUE data_map_new(VALUE self) {
|
|
327
350
|
data = appsignal_data_map_new();
|
328
351
|
|
329
352
|
if (data) {
|
330
|
-
return
|
353
|
+
return TypedData_Wrap_Struct(Data, &data_data_type, data);
|
331
354
|
} else {
|
332
355
|
return Qnil;
|
333
356
|
}
|
@@ -339,7 +362,7 @@ static VALUE data_array_new(VALUE self) {
|
|
339
362
|
data = appsignal_data_array_new();
|
340
363
|
|
341
364
|
if (data) {
|
342
|
-
return
|
365
|
+
return TypedData_Wrap_Struct(Data, &data_data_type, data);
|
343
366
|
} else {
|
344
367
|
return Qnil;
|
345
368
|
}
|
@@ -351,7 +374,7 @@ static VALUE data_set_string(VALUE self, VALUE key, VALUE value) {
|
|
351
374
|
Check_Type(key, T_STRING);
|
352
375
|
Check_Type(value, T_STRING);
|
353
376
|
|
354
|
-
|
377
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
355
378
|
|
356
379
|
appsignal_data_map_set_string(
|
357
380
|
data,
|
@@ -371,7 +394,7 @@ static VALUE data_set_integer(VALUE self, VALUE key, VALUE value) {
|
|
371
394
|
rb_raise(rb_eTypeError, "wrong argument type %s (expected Integer)", rb_obj_classname(value));
|
372
395
|
}
|
373
396
|
|
374
|
-
|
397
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
375
398
|
|
376
399
|
appsignal_data_map_set_integer(
|
377
400
|
data,
|
@@ -388,7 +411,7 @@ static VALUE data_set_float(VALUE self, VALUE key, VALUE value) {
|
|
388
411
|
Check_Type(key, T_STRING);
|
389
412
|
Check_Type(value, T_FLOAT);
|
390
413
|
|
391
|
-
|
414
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
392
415
|
|
393
416
|
appsignal_data_map_set_float(
|
394
417
|
data,
|
@@ -404,7 +427,7 @@ static VALUE data_set_boolean(VALUE self, VALUE key, VALUE value) {
|
|
404
427
|
|
405
428
|
Check_Type(key, T_STRING);
|
406
429
|
|
407
|
-
|
430
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
408
431
|
|
409
432
|
appsignal_data_map_set_boolean(
|
410
433
|
data,
|
@@ -420,7 +443,7 @@ static VALUE data_set_nil(VALUE self, VALUE key) {
|
|
420
443
|
|
421
444
|
Check_Type(key, T_STRING);
|
422
445
|
|
423
|
-
|
446
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
424
447
|
|
425
448
|
appsignal_data_map_set_null(
|
426
449
|
data,
|
@@ -435,10 +458,9 @@ static VALUE data_set_data(VALUE self, VALUE key, VALUE value) {
|
|
435
458
|
appsignal_data_t* value_data;
|
436
459
|
|
437
460
|
Check_Type(key, T_STRING);
|
438
|
-
|
461
|
+
value_data = rb_check_typeddata(value, &data_data_type);
|
439
462
|
|
440
|
-
|
441
|
-
Data_Get_Struct(value, appsignal_data_t, value_data);
|
463
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
442
464
|
|
443
465
|
appsignal_data_map_set_data(
|
444
466
|
data,
|
@@ -454,7 +476,7 @@ static VALUE data_append_string(VALUE self, VALUE value) {
|
|
454
476
|
|
455
477
|
Check_Type(value, T_STRING);
|
456
478
|
|
457
|
-
|
479
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
458
480
|
|
459
481
|
appsignal_data_array_append_string(
|
460
482
|
data,
|
@@ -472,7 +494,7 @@ static VALUE data_append_integer(VALUE self, VALUE value) {
|
|
472
494
|
rb_raise(rb_eTypeError, "wrong argument type %s (expected Integer)", rb_obj_classname(value));
|
473
495
|
}
|
474
496
|
|
475
|
-
|
497
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
476
498
|
|
477
499
|
appsignal_data_array_append_integer(
|
478
500
|
data,
|
@@ -487,7 +509,7 @@ static VALUE data_append_float(VALUE self, VALUE value) {
|
|
487
509
|
|
488
510
|
Check_Type(value, T_FLOAT);
|
489
511
|
|
490
|
-
|
512
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
491
513
|
|
492
514
|
appsignal_data_array_append_float(
|
493
515
|
data,
|
@@ -500,7 +522,7 @@ static VALUE data_append_float(VALUE self, VALUE value) {
|
|
500
522
|
static VALUE data_append_boolean(VALUE self, VALUE value) {
|
501
523
|
appsignal_data_t* data;
|
502
524
|
|
503
|
-
|
525
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
504
526
|
|
505
527
|
appsignal_data_array_append_boolean(
|
506
528
|
data,
|
@@ -513,7 +535,7 @@ static VALUE data_append_boolean(VALUE self, VALUE value) {
|
|
513
535
|
static VALUE data_append_nil(VALUE self) {
|
514
536
|
appsignal_data_t* data;
|
515
537
|
|
516
|
-
|
538
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
517
539
|
|
518
540
|
appsignal_data_array_append_null(data);
|
519
541
|
|
@@ -524,10 +546,9 @@ static VALUE data_append_data(VALUE self, VALUE value) {
|
|
524
546
|
appsignal_data_t* data;
|
525
547
|
appsignal_data_t* value_data;
|
526
548
|
|
527
|
-
|
549
|
+
value_data = rb_check_typeddata(value, &data_data_type);
|
528
550
|
|
529
|
-
|
530
|
-
Data_Get_Struct(value, appsignal_data_t, value_data);
|
551
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
531
552
|
|
532
553
|
appsignal_data_array_append_data(
|
533
554
|
data,
|
@@ -541,12 +562,12 @@ static VALUE data_equal(VALUE self, VALUE other) {
|
|
541
562
|
appsignal_data_t* data;
|
542
563
|
appsignal_data_t* other_data;
|
543
564
|
|
544
|
-
if (TYPE(other) !=
|
565
|
+
if (TYPE(other) != T_DATA) {
|
545
566
|
return Qfalse;
|
546
567
|
}
|
547
568
|
|
548
|
-
|
549
|
-
|
569
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
570
|
+
TypedData_Get_Struct(other, appsignal_data_t, &data_data_type, other_data);
|
550
571
|
|
551
572
|
if (appsignal_data_equal(data, other_data) == 1) {
|
552
573
|
return Qtrue;
|
@@ -559,7 +580,7 @@ static VALUE data_to_s(VALUE self) {
|
|
559
580
|
appsignal_data_t* data;
|
560
581
|
appsignal_string_t json;
|
561
582
|
|
562
|
-
|
583
|
+
TypedData_Get_Struct(self, appsignal_data_t, &data_data_type, data);
|
563
584
|
|
564
585
|
json = appsignal_data_to_json(data);
|
565
586
|
|
@@ -578,7 +599,7 @@ static VALUE root_span_new(VALUE self, VALUE namespace) {
|
|
578
599
|
span = appsignal_create_root_span(make_appsignal_string(namespace));
|
579
600
|
|
580
601
|
if (span) {
|
581
|
-
return
|
602
|
+
return TypedData_Wrap_Struct(Span, &span_data_type, span);
|
582
603
|
} else {
|
583
604
|
return Qnil;
|
584
605
|
}
|
@@ -588,12 +609,12 @@ static VALUE child_span_new(VALUE self) {
|
|
588
609
|
appsignal_span_t* parent;
|
589
610
|
appsignal_span_t* span;
|
590
611
|
|
591
|
-
|
612
|
+
TypedData_Get_Struct(self, appsignal_span_t, &span_data_type, parent);
|
592
613
|
|
593
614
|
span = appsignal_create_child_span(parent);
|
594
615
|
|
595
616
|
if (span) {
|
596
|
-
return
|
617
|
+
return TypedData_Wrap_Struct(Span, &span_data_type, span);
|
597
618
|
} else {
|
598
619
|
return Qnil;
|
599
620
|
}
|
@@ -604,7 +625,7 @@ static VALUE set_span_name(VALUE self, VALUE name) {
|
|
604
625
|
|
605
626
|
Check_Type(name, T_STRING);
|
606
627
|
|
607
|
-
|
628
|
+
TypedData_Get_Struct(self, appsignal_span_t, &span_data_type, span);
|
608
629
|
|
609
630
|
appsignal_set_span_name(span, make_appsignal_string(name));
|
610
631
|
return Qnil;
|
@@ -616,10 +637,10 @@ static VALUE add_span_error(VALUE self, VALUE name, VALUE message, VALUE backtra
|
|
616
637
|
|
617
638
|
Check_Type(name, T_STRING);
|
618
639
|
Check_Type(message, T_STRING);
|
619
|
-
Check_Type(backtrace, RUBY_T_DATA);
|
620
640
|
|
621
|
-
|
622
|
-
|
641
|
+
backtrace_data = rb_check_typeddata(backtrace, &data_data_type);
|
642
|
+
|
643
|
+
TypedData_Get_Struct(self, appsignal_span_t, &span_data_type, span);
|
623
644
|
|
624
645
|
appsignal_add_span_error(
|
625
646
|
span,
|
@@ -635,10 +656,10 @@ static VALUE set_span_sample_data(VALUE self, VALUE key, VALUE payload) {
|
|
635
656
|
appsignal_data_t* payload_data;
|
636
657
|
|
637
658
|
Check_Type(key, T_STRING);
|
638
|
-
Check_Type(payload, RUBY_T_DATA);
|
639
659
|
|
640
|
-
|
641
|
-
|
660
|
+
payload_data = rb_check_typeddata(payload, &data_data_type);
|
661
|
+
|
662
|
+
TypedData_Get_Struct(self, appsignal_span_t, &span_data_type, span);
|
642
663
|
|
643
664
|
appsignal_set_span_sample_data(
|
644
665
|
span,
|
@@ -654,7 +675,7 @@ static VALUE set_span_attribute_string(VALUE self, VALUE key, VALUE value) {
|
|
654
675
|
Check_Type(key, T_STRING);
|
655
676
|
Check_Type(value, T_STRING);
|
656
677
|
|
657
|
-
|
678
|
+
TypedData_Get_Struct(self, appsignal_span_t, &span_data_type, span);
|
658
679
|
|
659
680
|
appsignal_set_span_attribute_string(
|
660
681
|
span,
|
@@ -675,7 +696,7 @@ static VALUE set_span_attribute_int(VALUE self, VALUE key, VALUE value) {
|
|
675
696
|
rb_raise(rb_eTypeError, "wrong argument type %s (expected Integer)", rb_obj_classname(value));
|
676
697
|
}
|
677
698
|
|
678
|
-
|
699
|
+
TypedData_Get_Struct(self, appsignal_span_t, &span_data_type, span);
|
679
700
|
|
680
701
|
appsignal_set_span_attribute_int(
|
681
702
|
span,
|
@@ -691,7 +712,7 @@ static VALUE set_span_attribute_bool(VALUE self, VALUE key, VALUE value) {
|
|
691
712
|
|
692
713
|
Check_Type(key, T_STRING);
|
693
714
|
|
694
|
-
|
715
|
+
TypedData_Get_Struct(self, appsignal_span_t, &span_data_type, span);
|
695
716
|
|
696
717
|
appsignal_set_span_attribute_bool(
|
697
718
|
span,
|
@@ -708,7 +729,7 @@ static VALUE set_span_attribute_double(VALUE self, VALUE key, VALUE value) {
|
|
708
729
|
Check_Type(key, T_STRING);
|
709
730
|
Check_Type(value, T_FLOAT);
|
710
731
|
|
711
|
-
|
732
|
+
TypedData_Get_Struct(self, appsignal_span_t, &span_data_type, span);
|
712
733
|
|
713
734
|
appsignal_set_span_attribute_double(
|
714
735
|
span,
|
@@ -723,7 +744,7 @@ static VALUE span_to_json(VALUE self) {
|
|
723
744
|
appsignal_span_t* span;
|
724
745
|
appsignal_string_t json;
|
725
746
|
|
726
|
-
|
747
|
+
TypedData_Get_Struct(self, appsignal_span_t, &span_data_type, span);
|
727
748
|
|
728
749
|
json = appsignal_span_to_json(span);
|
729
750
|
|
@@ -737,7 +758,7 @@ static VALUE span_to_json(VALUE self) {
|
|
737
758
|
static VALUE close_span(VALUE self) {
|
738
759
|
appsignal_span_t* span;
|
739
760
|
|
740
|
-
|
761
|
+
TypedData_Get_Struct(self, appsignal_span_t, &span_data_type, span);
|
741
762
|
|
742
763
|
appsignal_close_span(span);
|
743
764
|
|
@@ -751,9 +772,8 @@ static VALUE a_log(VALUE self, VALUE group, VALUE severity, VALUE format, VALUE
|
|
751
772
|
Check_Type(severity, T_FIXNUM);
|
752
773
|
Check_Type(format, T_FIXNUM);
|
753
774
|
Check_Type(message, T_STRING);
|
754
|
-
Check_Type(attributes, RUBY_T_DATA);
|
755
775
|
|
756
|
-
|
776
|
+
attributes_data = rb_check_typeddata(attributes, &data_data_type);
|
757
777
|
|
758
778
|
appsignal_log(
|
759
779
|
make_appsignal_string(group),
|
@@ -771,9 +791,8 @@ static VALUE set_gauge(VALUE self, VALUE key, VALUE value, VALUE tags) {
|
|
771
791
|
|
772
792
|
Check_Type(key, T_STRING);
|
773
793
|
Check_Type(value, T_FLOAT);
|
774
|
-
Check_Type(tags, RUBY_T_DATA);
|
775
794
|
|
776
|
-
|
795
|
+
tags_data = rb_check_typeddata(tags, &data_data_type);
|
777
796
|
|
778
797
|
appsignal_set_gauge(
|
779
798
|
make_appsignal_string(key),
|
@@ -788,9 +807,8 @@ static VALUE increment_counter(VALUE self, VALUE key, VALUE count, VALUE tags) {
|
|
788
807
|
|
789
808
|
Check_Type(key, T_STRING);
|
790
809
|
Check_Type(count, T_FLOAT);
|
791
|
-
Check_Type(tags, RUBY_T_DATA);
|
792
810
|
|
793
|
-
|
811
|
+
tags_data = rb_check_typeddata(tags, &data_data_type);
|
794
812
|
|
795
813
|
appsignal_increment_counter(
|
796
814
|
make_appsignal_string(key),
|
@@ -805,9 +823,8 @@ static VALUE add_distribution_value(VALUE self, VALUE key, VALUE value, VALUE ta
|
|
805
823
|
|
806
824
|
Check_Type(key, T_STRING);
|
807
825
|
Check_Type(value, T_FLOAT);
|
808
|
-
Check_Type(tags, RUBY_T_DATA);
|
809
826
|
|
810
|
-
|
827
|
+
tags_data = rb_check_typeddata(tags, &data_data_type);
|
811
828
|
|
812
829
|
appsignal_add_distribution_value(
|
813
830
|
make_appsignal_string(key),
|
@@ -821,7 +838,7 @@ static void track_allocation(rb_event_flag_t flag, VALUE arg1, VALUE arg2, ID ar
|
|
821
838
|
appsignal_track_allocation();
|
822
839
|
}
|
823
840
|
|
824
|
-
static VALUE install_allocation_event_hook() {
|
841
|
+
static VALUE install_allocation_event_hook(VALUE self) {
|
825
842
|
// This event hook is only available on Ruby 2.1 and 2.2
|
826
843
|
#if defined(RUBY_INTERNAL_EVENT_NEWOBJ)
|
827
844
|
rb_add_event_hook(
|
@@ -834,7 +851,7 @@ static VALUE install_allocation_event_hook() {
|
|
834
851
|
return Qnil;
|
835
852
|
}
|
836
853
|
|
837
|
-
static VALUE running_in_container() {
|
854
|
+
static VALUE running_in_container(VALUE self) {
|
838
855
|
return appsignal_running_in_container() == 1 ? Qtrue : Qfalse;
|
839
856
|
}
|
840
857
|
|
data/ext/base.rb
CHANGED
@@ -145,7 +145,9 @@ def download_archive(type)
|
|
145
145
|
return open(*args)
|
146
146
|
end
|
147
147
|
rescue => error
|
148
|
-
|
148
|
+
backtrace = error.backtrace.join("\n")
|
149
|
+
download_errors <<
|
150
|
+
"- URL: #{download_url}\n Error: #{error.class}: #{error.message}\n#{backtrace}"
|
149
151
|
next
|
150
152
|
end
|
151
153
|
end
|
@@ -66,6 +66,61 @@ module Appsignal
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
69
|
+
|
70
|
+
def deduplicate_cron!(events) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
|
71
|
+
# Remove redundant cron check-in events from the given list of events.
|
72
|
+
# This is done by removing redundant *pairs* of events -- that is,
|
73
|
+
# for each identifier, only send one complete pair of start and
|
74
|
+
# finish events. Remove all other complete pairs of start and finish
|
75
|
+
# events for that identifier, but keep any other start or finish events
|
76
|
+
# that don't have a matching pair.
|
77
|
+
#
|
78
|
+
# Note that this method assumes that the events in this list have already
|
79
|
+
# been rejected based on `Event.redundant?`, so we don't check to remove
|
80
|
+
# check-in events that are functionally identical.
|
81
|
+
start_digests = Hash.new { |h, k| h[k] = Set.new }
|
82
|
+
finish_digests = Hash.new { |h, k| h[k] = Set.new }
|
83
|
+
complete_digests = Hash.new { |h, k| h[k] = Set.new }
|
84
|
+
keep_digest = {}
|
85
|
+
|
86
|
+
# Compute a list of complete digests for each identifier, that is, digests
|
87
|
+
# for which both a start and finish cron check-in event exist. Store the
|
88
|
+
# last seen digest for each identifier as the one to keep.
|
89
|
+
events.each do |event|
|
90
|
+
if event[:check_in_type] == "cron"
|
91
|
+
if event[:kind] == "start"
|
92
|
+
start_digests[event[:identifier]] << event[:digest]
|
93
|
+
if finish_digests[event[:identifier]].include?(event[:digest])
|
94
|
+
complete_digests[event[:identifier]] << event[:digest]
|
95
|
+
keep_digest[event[:identifier]] = event[:digest]
|
96
|
+
end
|
97
|
+
elsif event[:kind] == "finish"
|
98
|
+
finish_digests[event[:identifier]] << event[:digest]
|
99
|
+
if start_digests[event[:identifier]].include?(event[:digest])
|
100
|
+
complete_digests[event[:identifier]] << event[:digest]
|
101
|
+
keep_digest[event[:identifier]] = event[:digest]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
start_digests = nil
|
108
|
+
finish_digests = nil
|
109
|
+
|
110
|
+
events.reject! do |event|
|
111
|
+
# Do not remove events that are not cron check-in events or that
|
112
|
+
# have an unknown kind.
|
113
|
+
return false unless
|
114
|
+
event[:check_in_type] == "cron" && (
|
115
|
+
event[:kind] == "start" ||
|
116
|
+
event[:kind] == "finish")
|
117
|
+
|
118
|
+
# Remove any event that is part of a complete digest pair, except
|
119
|
+
# for the one digest that should be kept.
|
120
|
+
keep_digest[event[:identifier]] != event[:digest] &&
|
121
|
+
complete_digests[event[:identifier]].include?(event[:digest])
|
122
|
+
end
|
123
|
+
end
|
69
124
|
end
|
70
125
|
end
|
71
126
|
end
|
@@ -95,7 +95,11 @@ module Appsignal
|
|
95
95
|
description = Event.describe(events)
|
96
96
|
|
97
97
|
begin
|
98
|
-
|
98
|
+
@transmitter ||= Transmitter.new(
|
99
|
+
"#{Appsignal.config[:logging_endpoint]}/check_ins/json"
|
100
|
+
)
|
101
|
+
|
102
|
+
response = @transmitter.transmit(events, :format => :ndjson)
|
99
103
|
|
100
104
|
if (200...300).include?(response.code.to_i)
|
101
105
|
Appsignal.internal_logger.debug("Transmitted #{description}")
|
@@ -157,7 +161,9 @@ module Appsignal
|
|
157
161
|
# Push a copy of the events to the queue, and clear the events array.
|
158
162
|
# This ensures that `@events` always contains events that have not
|
159
163
|
# yet been pushed to the queue.
|
160
|
-
@
|
164
|
+
events = @events.dup
|
165
|
+
Event.deduplicate_cron!(events)
|
166
|
+
@queue.push(events)
|
161
167
|
@events.clear
|
162
168
|
|
163
169
|
start_waker(BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS)
|
data/lib/appsignal/check_in.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
module Appsignal
|
4
4
|
module CheckIn
|
5
5
|
HEARTBEAT_CONTINUOUS_INTERVAL_SECONDS = 30
|
6
|
+
NEW_SCHEDULER_MUTEX = Mutex.new
|
7
|
+
|
6
8
|
class << self
|
7
9
|
# @api private
|
8
10
|
def continuous_heartbeats
|
@@ -82,16 +84,15 @@ module Appsignal
|
|
82
84
|
scheduler.schedule(event)
|
83
85
|
end
|
84
86
|
|
85
|
-
# @api private
|
86
|
-
def transmitter
|
87
|
-
@transmitter ||= Transmitter.new(
|
88
|
-
"#{Appsignal.config[:logging_endpoint]}/check_ins/json"
|
89
|
-
)
|
90
|
-
end
|
91
|
-
|
92
87
|
# @api private
|
93
88
|
def scheduler
|
94
|
-
@scheduler
|
89
|
+
return @scheduler if @scheduler
|
90
|
+
|
91
|
+
NEW_SCHEDULER_MUTEX.synchronize do
|
92
|
+
@scheduler ||= Scheduler.new
|
93
|
+
end
|
94
|
+
|
95
|
+
@scheduler
|
95
96
|
end
|
96
97
|
|
97
98
|
# @api private
|