ruby-static-tracing 0.0.1 → 0.0.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 +5 -5
- data/ext/ruby-static-tracing/extconf.rb +9 -8
- data/ext/ruby-static-tracing/linux/provider.c +145 -0
- data/ext/ruby-static-tracing/linux/provider.h +69 -0
- data/ext/ruby-static-tracing/linux/ruby_static_tracing.c +43 -0
- data/ext/ruby-static-tracing/linux/ruby_static_tracing.h +19 -0
- data/ext/ruby-static-tracing/linux/tracepoint.c +226 -0
- data/ext/ruby-static-tracing/linux/tracepoint.h +57 -0
- data/lib/ruby-static-tracing.rb +57 -2
- data/lib/ruby-static-tracing/configuration.rb +71 -0
- data/lib/ruby-static-tracing/platform.rb +8 -2
- data/lib/ruby-static-tracing/provider.rb +61 -0
- data/lib/ruby-static-tracing/tracepoint.rb +41 -0
- data/lib/ruby-static-tracing/tracers.rb +3 -0
- data/lib/ruby-static-tracing/tracers/concerns/latency_tracer.rb +16 -0
- data/lib/ruby-static-tracing/tracers/latency_tracer.rb +67 -0
- data/lib/ruby-static-tracing/version.rb +3 -1
- metadata +56 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 394cdc6b04834088de888916e5ebcfb9481a8c75
|
4
|
+
data.tar.gz: 744d75e5564b7e3e0021d64cf2e141b97090e999
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e23b757367de4ddb676dbaac7da56d0d4ccb70e0bc7d4762df30c66221d0c5ec9cd2a2e2cc448c11c3bc11607d2e52b76d9eae451ed40a49883abf4cc478f2ff
|
7
|
+
data.tar.gz: 8ab4b39ffc8e234d9570bfc3cc1b62a019c3cbe7b1a4bcb595a7d09e01e9acd5280d9e5b97d6c597d9bab85970395f85d1183a50b0290e61d59e5d29d13132ca
|
@@ -3,25 +3,26 @@ $LOAD_PATH.unshift File.expand_path("../../../lib", __FILE__)
|
|
3
3
|
require 'mkmf'
|
4
4
|
require 'ruby-static-tracing/platform'
|
5
5
|
|
6
|
-
unless StaticTracing.linux?
|
7
|
-
end
|
8
|
-
|
9
6
|
def platform_dir(platform)
|
10
7
|
File.expand_path("../../../ext/ruby-static-tracing/#{platform}/", __FILE__)
|
11
8
|
end
|
12
9
|
|
13
|
-
if StaticTracing.linux?
|
10
|
+
if StaticTracing::Platform.linux?
|
14
11
|
abort 'libstapsdt.h is missing, please install libstapsdt' unless find_header('libstapsdt.h')
|
15
|
-
|
12
|
+
|
16
13
|
have_header 'libstapsdt.h'
|
17
|
-
|
18
|
-
|
14
|
+
|
15
|
+
unless have_library('stapsdt')
|
16
|
+
abort "libstapsdt is missing, please install it"
|
17
|
+
end
|
18
|
+
|
19
|
+
$CFLAGS = "-D_GNU_SOURCE -Wall " # -Werror complaining
|
19
20
|
if ENV.key?('DEBUG')
|
20
21
|
$CFLAGS << "-O0 -g -DDEBUG"
|
21
22
|
else
|
22
23
|
$CFLAGS << "-O3"
|
23
24
|
end
|
24
|
-
|
25
|
+
|
25
26
|
create_makefile('ruby-static-tracing/ruby_static_tracing', platform_dir("linux"))
|
26
27
|
else
|
27
28
|
# FIXME properly stub this.
|
@@ -0,0 +1,145 @@
|
|
1
|
+
#include "provider.h"
|
2
|
+
|
3
|
+
static const rb_data_type_t
|
4
|
+
static_tracing_provider_type;
|
5
|
+
|
6
|
+
// Forward decls
|
7
|
+
static const char*
|
8
|
+
check_name_arg(VALUE name);
|
9
|
+
|
10
|
+
/*
|
11
|
+
Wraps ProviderInit from libstapsdt
|
12
|
+
*/
|
13
|
+
VALUE
|
14
|
+
provider_initialize(VALUE self, VALUE name)
|
15
|
+
{
|
16
|
+
const char *c_name_str = NULL;
|
17
|
+
static_tracing_provider_t *res = NULL;
|
18
|
+
|
19
|
+
// Check and cast arguments
|
20
|
+
c_name_str = check_name_arg(name);
|
21
|
+
|
22
|
+
// Build semian resource structure
|
23
|
+
TypedData_Get_Struct(self, static_tracing_provider_t, &static_tracing_provider_type, res);
|
24
|
+
res->sdt_provider = providerInit(c_name_str);
|
25
|
+
return self;
|
26
|
+
}
|
27
|
+
|
28
|
+
// Internal function used to register a tracepoint against a provider instance
|
29
|
+
SDTProbe_t
|
30
|
+
*provider_add_tracepoint_internal(VALUE self, const char* name, int argc, Tracepoint_arg_types *args)
|
31
|
+
{
|
32
|
+
static_tracing_provider_t *res = NULL;
|
33
|
+
SDTProbe_t *probe;
|
34
|
+
|
35
|
+
TypedData_Get_Struct(self, static_tracing_provider_t, &static_tracing_provider_type, res);
|
36
|
+
|
37
|
+
switch(argc)
|
38
|
+
{
|
39
|
+
case 0: probe = providerAddProbe(res->sdt_provider, name, 0); break;
|
40
|
+
case 1: probe = providerAddProbe(res->sdt_provider, name, argc, args[0]); break;
|
41
|
+
case 2: probe = providerAddProbe(res->sdt_provider, name, argc, args[0], args[1]); break;
|
42
|
+
case 3: probe = providerAddProbe(res->sdt_provider, name, argc, args[0], args[1], args[2]); break;
|
43
|
+
case 4: probe = providerAddProbe(res->sdt_provider, name, argc, args[0], args[1], args[2], args[3]); break;
|
44
|
+
case 5: probe = providerAddProbe(res->sdt_provider, name, argc, args[0], args[1], args[2], args[3], args[4]); break;
|
45
|
+
case 6: probe = providerAddProbe(res->sdt_provider, name, argc, args[0], args[1], args[2], args[3], args[4], args[5]); break;
|
46
|
+
default: probe = providerAddProbe(res->sdt_provider, name, 0); break;
|
47
|
+
}
|
48
|
+
|
49
|
+
return probe;
|
50
|
+
}
|
51
|
+
|
52
|
+
/*
|
53
|
+
Wraps providerLoad from libstapsdt
|
54
|
+
*/
|
55
|
+
VALUE
|
56
|
+
provider_enable(VALUE self)
|
57
|
+
{
|
58
|
+
static_tracing_provider_t *res = NULL;
|
59
|
+
TypedData_Get_Struct(self, static_tracing_provider_t, &static_tracing_provider_type, res);
|
60
|
+
return providerLoad(res->sdt_provider) == 0 ? Qtrue : Qfalse;
|
61
|
+
}
|
62
|
+
|
63
|
+
/*
|
64
|
+
Wraps providerUnload from libstapsdt
|
65
|
+
*/
|
66
|
+
VALUE
|
67
|
+
provider_disable(VALUE self)
|
68
|
+
{
|
69
|
+
static_tracing_provider_t *res = NULL;
|
70
|
+
TypedData_Get_Struct(self, static_tracing_provider_t, &static_tracing_provider_type, res);
|
71
|
+
return providerUnload(res->sdt_provider) == 0 ? Qtrue : Qfalse;
|
72
|
+
}
|
73
|
+
|
74
|
+
/*
|
75
|
+
Wraps providerUnload from libstapsdt
|
76
|
+
*/
|
77
|
+
VALUE
|
78
|
+
provider_destroy(VALUE self)
|
79
|
+
{
|
80
|
+
static_tracing_provider_t *res = NULL;
|
81
|
+
TypedData_Get_Struct(self, static_tracing_provider_t, &static_tracing_provider_type, res);
|
82
|
+
providerDestroy(res->sdt_provider);
|
83
|
+
return Qnil;
|
84
|
+
}
|
85
|
+
|
86
|
+
// Allocate a static_tracing_provider_type struct for ruby memory management
|
87
|
+
VALUE
|
88
|
+
static_tracing_provider_alloc(VALUE klass)
|
89
|
+
{
|
90
|
+
static_tracing_provider_t *res;
|
91
|
+
VALUE obj = TypedData_Make_Struct(klass, static_tracing_provider_t, &static_tracing_provider_type, res);
|
92
|
+
return obj;
|
93
|
+
}
|
94
|
+
|
95
|
+
|
96
|
+
static const char*
|
97
|
+
check_name_arg(VALUE name)
|
98
|
+
{
|
99
|
+
const char *c_name_str = NULL;
|
100
|
+
|
101
|
+
if (TYPE(name) != T_SYMBOL && TYPE(name) != T_STRING) {
|
102
|
+
rb_raise(rb_eTypeError, "name must be a symbol or string");
|
103
|
+
}
|
104
|
+
if (TYPE(name) == T_SYMBOL) {
|
105
|
+
c_name_str = rb_id2name(rb_to_id(name));
|
106
|
+
} else if (TYPE(name) == T_STRING) {
|
107
|
+
c_name_str = RSTRING_PTR(name);
|
108
|
+
}
|
109
|
+
|
110
|
+
return c_name_str;
|
111
|
+
}
|
112
|
+
|
113
|
+
static inline void
|
114
|
+
static_tracing_provider_mark(void *ptr)
|
115
|
+
{
|
116
|
+
/* noop */
|
117
|
+
}
|
118
|
+
|
119
|
+
static inline void
|
120
|
+
static_tracing_provider_free(void *ptr)
|
121
|
+
{
|
122
|
+
static_tracing_provider_t *res = (static_tracing_provider_t *) ptr;
|
123
|
+
//if (res->name) {
|
124
|
+
// free(res->name);
|
125
|
+
// res->name = NULL;
|
126
|
+
//}
|
127
|
+
xfree(res);
|
128
|
+
}
|
129
|
+
|
130
|
+
static inline size_t
|
131
|
+
static_tracing_provider_memsize(const void *ptr)
|
132
|
+
{
|
133
|
+
return sizeof(static_tracing_provider_t);
|
134
|
+
}
|
135
|
+
|
136
|
+
static const rb_data_type_t
|
137
|
+
static_tracing_provider_type = {
|
138
|
+
"static_tracing_provider",
|
139
|
+
{
|
140
|
+
static_tracing_provider_mark,
|
141
|
+
static_tracing_provider_free,
|
142
|
+
static_tracing_provider_memsize
|
143
|
+
},
|
144
|
+
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
145
|
+
};
|
@@ -0,0 +1,69 @@
|
|
1
|
+
/*
|
2
|
+
For core static tracing functions exposed directly to ruby.
|
3
|
+
Functions here are associated with rubyland operations.
|
4
|
+
*/
|
5
|
+
#ifndef STATIC_TRACING_PROVIDER_H
|
6
|
+
#define STATIC_TRACING_PROVIDER_H
|
7
|
+
|
8
|
+
#include <ruby.h>
|
9
|
+
// Include libstapsdt.h to wrap
|
10
|
+
#include <libstapsdt.h>
|
11
|
+
|
12
|
+
#include "ruby_static_tracing.h"
|
13
|
+
#include "tracepoint.h"
|
14
|
+
|
15
|
+
typedef struct {
|
16
|
+
char *name;
|
17
|
+
SDTProvider_t *sdt_provider;
|
18
|
+
VALUE tracepoints;
|
19
|
+
} static_tracing_provider_t;
|
20
|
+
|
21
|
+
/*
|
22
|
+
* call-seq:
|
23
|
+
* StaticTracing::Provider.new(id) -> provider
|
24
|
+
*
|
25
|
+
* Creates a new Provider.
|
26
|
+
*/
|
27
|
+
VALUE
|
28
|
+
provider_initialize(VALUE self, VALUE id);
|
29
|
+
|
30
|
+
/*
|
31
|
+
* call-seq:
|
32
|
+
* provider.enable() -> true
|
33
|
+
*
|
34
|
+
* Enable this provider
|
35
|
+
*
|
36
|
+
* Return true if the enable operation succeeded
|
37
|
+
*/
|
38
|
+
VALUE
|
39
|
+
provider_enable(VALUE self);
|
40
|
+
|
41
|
+
/*
|
42
|
+
* call-seq:
|
43
|
+
* provider.disable() -> true
|
44
|
+
*
|
45
|
+
* Disable this provider
|
46
|
+
*
|
47
|
+
* Return true if the disable operation succeeded
|
48
|
+
*/
|
49
|
+
VALUE
|
50
|
+
provider_disable(VALUE self);
|
51
|
+
/*
|
52
|
+
* call-seq:
|
53
|
+
* provider.destroy() -> true
|
54
|
+
*
|
55
|
+
* Destroys this provider.
|
56
|
+
*
|
57
|
+
* Return true if the destory operation succeeded
|
58
|
+
*/
|
59
|
+
VALUE
|
60
|
+
provider_destroy(VALUE self);
|
61
|
+
|
62
|
+
// Allocate a static_tracing_provider_type struct for ruby memory management
|
63
|
+
VALUE
|
64
|
+
static_tracing_provider_alloc(VALUE klass);
|
65
|
+
|
66
|
+
SDTProbe_t
|
67
|
+
*provider_add_tracepoint_internal(VALUE self, const char* name, int argc, Tracepoint_arg_types *args);
|
68
|
+
|
69
|
+
#endif //STATIC_TRACING_PROVIDER_H
|
@@ -1,4 +1,47 @@
|
|
1
|
+
#include "provider.h"
|
2
|
+
#include "tracepoint.h"
|
3
|
+
|
1
4
|
void Init_ruby_static_tracing()
|
2
5
|
{
|
6
|
+
VALUE cStaticTracing, cProvider, cTracepoint;
|
7
|
+
|
8
|
+
cStaticTracing = rb_const_get(rb_cObject, rb_intern("StaticTracing"));
|
9
|
+
|
10
|
+
/*
|
11
|
+
* Document-class: StaticTracing::Provider
|
12
|
+
*
|
13
|
+
* Provider is the wrapper around libstapsdt
|
14
|
+
*/
|
15
|
+
cProvider = rb_const_get(cStaticTracing, rb_intern("Provider"));
|
16
|
+
|
17
|
+
/*
|
18
|
+
* Document-class: Statictracing::Tracepoint
|
19
|
+
*
|
20
|
+
* A Tracepoint is a wrapper around an SDTProbe
|
21
|
+
*/
|
22
|
+
cTracepoint = rb_const_get(cStaticTracing, rb_intern("Tracepoint"));
|
3
23
|
|
24
|
+
/* Document-class: StaticTracing::SyscallError
|
25
|
+
*
|
26
|
+
* Represents failures to fire a tracepoint or register a provider
|
27
|
+
*/
|
28
|
+
eUSDT = rb_const_get(cStaticTracing, rb_intern("USDTError"));
|
29
|
+
|
30
|
+
/* Document-class: StaticTracing::InternalError
|
31
|
+
*
|
32
|
+
* An internal StaticTracing error. These errors may constitute bugs.
|
33
|
+
*/
|
34
|
+
eInternal = rb_const_get(cStaticTracing, rb_intern("InternalError"));
|
35
|
+
|
36
|
+
rb_define_alloc_func(cProvider, static_tracing_provider_alloc);
|
37
|
+
rb_define_method(cProvider, "provider_initialize", provider_initialize, 1);
|
38
|
+
rb_define_method(cProvider, "enable", provider_enable, 0);
|
39
|
+
rb_define_method(cProvider, "disable", provider_disable, 0);
|
40
|
+
rb_define_method(cProvider, "destroy", provider_destroy, 0);
|
41
|
+
|
42
|
+
rb_define_alloc_func(cTracepoint, static_tracing_tracepoint_alloc);
|
43
|
+
rb_define_method(cTracepoint, "tracepoint_initialize", tracepoint_initialize, 3);
|
44
|
+
rb_define_method(cTracepoint, "fire_tracepoint", tracepoint_fire, 1);
|
45
|
+
rb_define_method(cTracepoint, "enabled?", tracepoint_enabled, 0);
|
4
46
|
}
|
47
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
/*
|
2
|
+
System, 3rd party, and project includes
|
3
|
+
Implements Init_ruby_static_tracing, which is used as C/Ruby entrypoint.
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef RUBY_STATIC_TRACING_H
|
7
|
+
#define RUBY_STATIC_TRACING_H
|
8
|
+
|
9
|
+
typedef enum TRACEPOINT_ARG_TYPES_ENUM {
|
10
|
+
Integer = int64, // STAP enum type -8
|
11
|
+
String = uint64, // STAP enum type 8
|
12
|
+
} Tracepoint_arg_types;
|
13
|
+
|
14
|
+
#include "provider.h"
|
15
|
+
|
16
|
+
void Init_ruby_static_tracing();
|
17
|
+
VALUE eUSDT, eInternal;
|
18
|
+
|
19
|
+
#endif //RUBY_STATIC_TRACING_H
|
@@ -0,0 +1,226 @@
|
|
1
|
+
#include "tracepoint.h"
|
2
|
+
#include "provider.h"
|
3
|
+
|
4
|
+
static const rb_data_type_t
|
5
|
+
static_tracing_tracepoint_type;
|
6
|
+
|
7
|
+
static const char*
|
8
|
+
check_name_arg(VALUE provider);
|
9
|
+
|
10
|
+
static const char*
|
11
|
+
check_provider_arg(VALUE provider);
|
12
|
+
|
13
|
+
static Tracepoint_arg_types
|
14
|
+
*check_vargs(int *argc, VALUE vargs);
|
15
|
+
|
16
|
+
static Tracepoint_fire_arg
|
17
|
+
*check_fire_args(int *argc, VALUE vargs);
|
18
|
+
|
19
|
+
VALUE
|
20
|
+
tracepoint_initialize(VALUE self, VALUE provider, VALUE name, VALUE vargs)
|
21
|
+
{
|
22
|
+
VALUE cStaticTracing, cProvider, cProviderInst;
|
23
|
+
static_tracing_tracepoint_t *tracepoint = NULL;
|
24
|
+
const char *c_name_str = NULL;
|
25
|
+
int argc = 0;
|
26
|
+
|
27
|
+
c_name_str = check_name_arg(name);
|
28
|
+
check_provider_arg(provider); // FIXME should only accept string
|
29
|
+
Tracepoint_arg_types *args = check_vargs(&argc, vargs);
|
30
|
+
|
31
|
+
/// Get a handle to global provider list for lookup
|
32
|
+
cStaticTracing = rb_const_get(rb_cObject, rb_intern("StaticTracing"));
|
33
|
+
cProvider = rb_const_get(cStaticTracing, rb_intern("Provider"));
|
34
|
+
cProviderInst = rb_funcall(cProvider, rb_intern("register"), 1, provider);
|
35
|
+
|
36
|
+
// Use the provider to register a tracepoint
|
37
|
+
SDTProbe_t *probe = provider_add_tracepoint_internal(cProviderInst, c_name_str, argc, args);
|
38
|
+
TypedData_Get_Struct(self, static_tracing_tracepoint_t, &static_tracing_tracepoint_type, tracepoint);
|
39
|
+
|
40
|
+
// Stare the tracepoint handle in our struct
|
41
|
+
tracepoint->sdt_tracepoint = probe;
|
42
|
+
tracepoint->args = args;
|
43
|
+
|
44
|
+
return self;
|
45
|
+
}
|
46
|
+
|
47
|
+
VALUE
|
48
|
+
tracepoint_fire(VALUE self, VALUE vargs)
|
49
|
+
{
|
50
|
+
static_tracing_tracepoint_t *res = NULL;
|
51
|
+
TypedData_Get_Struct(self, static_tracing_tracepoint_t, &static_tracing_tracepoint_type, res);
|
52
|
+
int argc = 0;
|
53
|
+
|
54
|
+
Tracepoint_fire_arg *args = check_fire_args(&argc, vargs);
|
55
|
+
switch(argc)
|
56
|
+
{
|
57
|
+
case 0: probeFire(res->sdt_tracepoint); break;
|
58
|
+
case 1: probeFire(res->sdt_tracepoint, args[0]); break;
|
59
|
+
case 2: probeFire(res->sdt_tracepoint, args[0], args[1]); break;
|
60
|
+
case 3: probeFire(res->sdt_tracepoint, args[0], args[1], args[2]); break;
|
61
|
+
case 4: probeFire(res->sdt_tracepoint, args[0], args[1], args[2], args[3]); break;
|
62
|
+
case 5: probeFire(res->sdt_tracepoint, args[0], args[1], args[2], args[3], args[4]); break;
|
63
|
+
case 6: probeFire(res->sdt_tracepoint, args[0], args[1], args[2], args[3], args[4], args[5]); break;
|
64
|
+
default: probeFire(res->sdt_tracepoint); break;
|
65
|
+
}
|
66
|
+
|
67
|
+
return Qnil;
|
68
|
+
}
|
69
|
+
|
70
|
+
VALUE
|
71
|
+
tracepoint_enabled(VALUE self)
|
72
|
+
{
|
73
|
+
static_tracing_tracepoint_t *res = NULL;
|
74
|
+
TypedData_Get_Struct(self, static_tracing_tracepoint_t, &static_tracing_tracepoint_type, res);
|
75
|
+
return probeIsEnabled(res->sdt_tracepoint) == 1 ? Qtrue : Qfalse;
|
76
|
+
}
|
77
|
+
|
78
|
+
static const char*
|
79
|
+
check_name_arg(VALUE name)
|
80
|
+
{
|
81
|
+
const char *c_name_str = NULL;
|
82
|
+
|
83
|
+
if (TYPE(name) != T_SYMBOL && TYPE(name) != T_STRING) {
|
84
|
+
rb_raise(rb_eTypeError, "name must be a symbol or string");
|
85
|
+
}
|
86
|
+
if (TYPE(name) == T_SYMBOL) {
|
87
|
+
c_name_str = rb_id2name(rb_to_id(name));
|
88
|
+
} else if (TYPE(name) == T_STRING) {
|
89
|
+
c_name_str = RSTRING_PTR(name);
|
90
|
+
}
|
91
|
+
|
92
|
+
return c_name_str;
|
93
|
+
}
|
94
|
+
|
95
|
+
static const char*
|
96
|
+
check_provider_arg(VALUE provider)
|
97
|
+
{
|
98
|
+
const char *c_provider_str = NULL;
|
99
|
+
|
100
|
+
if (TYPE(provider) != T_SYMBOL && TYPE(provider) != T_STRING) {
|
101
|
+
rb_raise(rb_eTypeError, "provider must be a symbol or string");
|
102
|
+
}
|
103
|
+
if (TYPE(provider) == T_SYMBOL) {
|
104
|
+
c_provider_str = rb_id2name(rb_to_id(provider));
|
105
|
+
} else if (TYPE(provider) == T_STRING) {
|
106
|
+
c_provider_str = RSTRING_PTR(provider);
|
107
|
+
}
|
108
|
+
|
109
|
+
return c_provider_str;
|
110
|
+
}
|
111
|
+
|
112
|
+
static Tracepoint_arg_types
|
113
|
+
*check_vargs(int *argc, VALUE vargs)
|
114
|
+
{
|
115
|
+
if(TYPE(vargs) == T_ARRAY)
|
116
|
+
{
|
117
|
+
VALUE rLength = rb_funcall(vargs, rb_intern("length"), 0, Qnil);
|
118
|
+
*argc = NUM2INT(rLength);
|
119
|
+
|
120
|
+
if(*argc > 6)
|
121
|
+
{
|
122
|
+
printf("ERROR - passed %i args, maximum 6 argument types can be passed", *argc);
|
123
|
+
return NULL;
|
124
|
+
}
|
125
|
+
|
126
|
+
Tracepoint_arg_types *args = malloc(*argc * sizeof(Tracepoint_arg_types));
|
127
|
+
for (int i = 0; i < *argc; i++)
|
128
|
+
{
|
129
|
+
VALUE str = rb_funcall(rb_ary_entry(vargs, i), rb_intern("to_s"), 0, Qnil);
|
130
|
+
const char* cStr = RSTRING_PTR(str);
|
131
|
+
if (strcmp(cStr, "Integer")) {
|
132
|
+
args[i] = Integer;
|
133
|
+
} else if (strcmp(cStr, "String")) {
|
134
|
+
args[i] = String;
|
135
|
+
} else {
|
136
|
+
printf("ERROR - type \"%s\" is unsupported\n", cStr);
|
137
|
+
}
|
138
|
+
}
|
139
|
+
return args;
|
140
|
+
} else {
|
141
|
+
printf("ERROR - array was expected\n");
|
142
|
+
return NULL;
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
static Tracepoint_fire_arg
|
147
|
+
*check_fire_args(int *argc, VALUE vargs)
|
148
|
+
{
|
149
|
+
if(TYPE(vargs) == T_ARRAY)
|
150
|
+
{
|
151
|
+
VALUE rLength = rb_funcall(vargs, rb_intern("length"), 0, Qnil);
|
152
|
+
*argc = NUM2INT(rLength);
|
153
|
+
|
154
|
+
if(*argc > 6)
|
155
|
+
{
|
156
|
+
printf("ERROR - passed %i args, maximum 6 argument types can be passed", *argc);
|
157
|
+
return NULL;
|
158
|
+
}
|
159
|
+
|
160
|
+
Tracepoint_fire_arg *args = malloc(*argc * sizeof(Tracepoint_fire_arg));
|
161
|
+
//printf("SIZE: %i ARGC: %i \n", sizeof(Tracepoint_fire_arg), *argc);
|
162
|
+
for (int i = 0; i < *argc; i++)
|
163
|
+
{
|
164
|
+
VALUE val = rb_ary_entry(vargs, i);
|
165
|
+
switch(TYPE(val))
|
166
|
+
{
|
167
|
+
case T_FIXNUM:
|
168
|
+
args[i].intval = FIX2LONG(val);
|
169
|
+
break;
|
170
|
+
case T_STRING:
|
171
|
+
args[i].strval = RSTRING_PTR(val);
|
172
|
+
break;
|
173
|
+
default:
|
174
|
+
printf("ERROR unsupported type passed for argument %i to fire\n", i);
|
175
|
+
break;
|
176
|
+
}
|
177
|
+
}
|
178
|
+
return args;
|
179
|
+
} else {
|
180
|
+
printf("ERROR - array was expected\n");
|
181
|
+
return NULL;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
// Allocate a static_tracing_tracepoint_type struct for ruby memory management
|
186
|
+
VALUE
|
187
|
+
static_tracing_tracepoint_alloc(VALUE klass)
|
188
|
+
{
|
189
|
+
static_tracing_tracepoint_t *res;
|
190
|
+
VALUE obj = TypedData_Make_Struct(klass, static_tracing_tracepoint_t, &static_tracing_tracepoint_type, res);
|
191
|
+
return obj;
|
192
|
+
}
|
193
|
+
|
194
|
+
static inline void
|
195
|
+
static_tracing_tracepoint_mark(void *ptr)
|
196
|
+
{
|
197
|
+
/* noop */
|
198
|
+
}
|
199
|
+
|
200
|
+
static inline void
|
201
|
+
static_tracing_tracepoint_free(void *ptr)
|
202
|
+
{
|
203
|
+
static_tracing_tracepoint_t *res = (static_tracing_tracepoint_t *) ptr;
|
204
|
+
//if (res->name) {
|
205
|
+
// free(res->name);
|
206
|
+
// res->name = NULL;
|
207
|
+
//}
|
208
|
+
xfree(res);
|
209
|
+
}
|
210
|
+
|
211
|
+
static inline size_t
|
212
|
+
static_tracing_tracepoint_memsize(const void *ptr)
|
213
|
+
{
|
214
|
+
return sizeof(static_tracing_provider_t);
|
215
|
+
}
|
216
|
+
|
217
|
+
static const rb_data_type_t
|
218
|
+
static_tracing_tracepoint_type = {
|
219
|
+
"static_tracing_tracepoint",
|
220
|
+
{
|
221
|
+
static_tracing_tracepoint_mark,
|
222
|
+
static_tracing_tracepoint_free,
|
223
|
+
static_tracing_tracepoint_memsize
|
224
|
+
},
|
225
|
+
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
226
|
+
};
|
@@ -0,0 +1,57 @@
|
|
1
|
+
/*
|
2
|
+
For core static tracing functions exposed directly to ruby.
|
3
|
+
Functions here are associated with rubyland operations.
|
4
|
+
*/
|
5
|
+
#ifndef STATIC_TRACING_TRACEPOINT_H
|
6
|
+
#define STATIC_TRACING_TRACEPOINT_H
|
7
|
+
|
8
|
+
#include <ruby.h>
|
9
|
+
// Include libstapsdt.h to wrap
|
10
|
+
#include <libstapsdt.h>
|
11
|
+
// Probably need to include provider.h to be able to initialize self
|
12
|
+
|
13
|
+
#include "ruby_static_tracing.h"
|
14
|
+
|
15
|
+
typedef union {
|
16
|
+
unsigned long long intval;
|
17
|
+
char * strval;
|
18
|
+
} Tracepoint_fire_arg;
|
19
|
+
|
20
|
+
typedef struct {
|
21
|
+
char *name;
|
22
|
+
SDTProbe_t *sdt_tracepoint;
|
23
|
+
Tracepoint_arg_types *args;
|
24
|
+
} static_tracing_tracepoint_t;
|
25
|
+
|
26
|
+
/*
|
27
|
+
* call-seq:
|
28
|
+
* StaticTracing::Tracepoint.new(provider, id, *vargs) -> tracepoint
|
29
|
+
*
|
30
|
+
* Creates a new tracepoint on a provider
|
31
|
+
*/
|
32
|
+
VALUE
|
33
|
+
tracepoint_initialize(VALUE self, VALUE provider, VALUE id, VALUE vargs);
|
34
|
+
|
35
|
+
/*
|
36
|
+
* call-seq:
|
37
|
+
* tracepoint.fire(*vargs) -> true
|
38
|
+
*
|
39
|
+
* Fires data for the tracepoint to be probed
|
40
|
+
*/
|
41
|
+
VALUE
|
42
|
+
tracepoint_fire(VALUE self, VALUE vargs);
|
43
|
+
|
44
|
+
/*
|
45
|
+
* call-seq:
|
46
|
+
* tracepoint.enabled? -> true
|
47
|
+
*
|
48
|
+
* Checks if the tracepoint is enabled, indicating it is being traced
|
49
|
+
*/
|
50
|
+
VALUE
|
51
|
+
tracepoint_enabled(VALUE self);
|
52
|
+
|
53
|
+
// Allocate a static_tracing_tracepoint_type struct for ruby memory management
|
54
|
+
VALUE
|
55
|
+
static_tracing_tracepoint_alloc(VALUE klass);
|
56
|
+
|
57
|
+
#endif //STATIC_TRACING_TRACEPOINT_H
|
data/lib/ruby-static-tracing.rb
CHANGED
@@ -1,26 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
1
5
|
require 'ruby-static-tracing/version'
|
2
6
|
require 'ruby-static-tracing/platform'
|
7
|
+
require 'ruby-static-tracing/provider'
|
8
|
+
require 'ruby-static-tracing/tracepoint'
|
9
|
+
require 'ruby-static-tracing/configuration'
|
10
|
+
require 'ruby-static-tracing/tracers'
|
3
11
|
|
4
12
|
# FIXME Including StaticTracing should cause every method in a module or class to be registered
|
5
13
|
# Implement this by introspecting all methods on the includor, and wrapping them.
|
6
14
|
module StaticTracing
|
7
15
|
extend self
|
8
16
|
|
17
|
+
BaseError = Class.new(StandardError)
|
18
|
+
USDTError = Class.new(BaseError)
|
19
|
+
InternalError = Class.new(BaseError)
|
20
|
+
|
21
|
+
attr_accessor :logger
|
22
|
+
|
23
|
+
self.logger = Logger.new(STDERR)
|
24
|
+
|
25
|
+
def issue_disabled_tracepoints_warning
|
26
|
+
return if defined?(@warning_issued)
|
27
|
+
@warning_issued = true
|
28
|
+
logger.info("USDT tracepoints are not presently supported supported on #{RUBY_PLATFORM} - all operations will no-op")
|
29
|
+
end
|
30
|
+
|
31
|
+
# Efficiently return the current monotonic clocktime.
|
32
|
+
# Wraps libc clock_gettime
|
33
|
+
# The overhead of this is tested to be on the order of 10 microseconds under normal conditions
|
34
|
+
# You should inline this method in your tracer to avoid an extra method call.
|
35
|
+
def nsec
|
36
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
|
37
|
+
end
|
38
|
+
|
9
39
|
# Should indicate if static tracing is enabled - a global constant
|
10
40
|
def enabled?
|
41
|
+
!!@enabled
|
11
42
|
end
|
12
43
|
|
13
44
|
# Overwrite the definition of all functions that are enabled
|
14
45
|
# with a wrapped version that has tracing enabled
|
15
|
-
def enable
|
46
|
+
def enable!
|
47
|
+
tracers.each(&:enable!)
|
48
|
+
@enabled = true
|
16
49
|
end
|
17
50
|
|
18
51
|
# Overwrite the definition of all functions to their original definition,
|
19
52
|
# no longer wrapping them
|
20
|
-
def disable
|
53
|
+
def disable!
|
54
|
+
@enabled = false
|
55
|
+
end
|
56
|
+
|
57
|
+
# Retrieves a hash of all registered providers
|
58
|
+
def providers
|
59
|
+
@providers ||= {}
|
60
|
+
end
|
61
|
+
|
62
|
+
def tracers
|
63
|
+
@tracers ||= []
|
64
|
+
end
|
65
|
+
|
66
|
+
def toggle_tracing!
|
67
|
+
enabled? ? disable! : enable!
|
68
|
+
end
|
69
|
+
|
70
|
+
def configure
|
71
|
+
yield Configuration.instance
|
21
72
|
end
|
22
73
|
end
|
23
74
|
|
24
75
|
# FIXME add signal handlers to enable-disable on specific process signals
|
25
76
|
# within a trap handler.
|
26
77
|
# Specify default signals, but allow these to be overidden for easier integration
|
78
|
+
|
79
|
+
# This loads the actual C extension, we might want to guard it
|
80
|
+
# for cases where the extension isn't yet built
|
81
|
+
require 'ruby-static-tracing/ruby_static_tracing' if StaticTracing::Platform.linux?
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
module StaticTracing
|
6
|
+
class Configuration
|
7
|
+
module Modes
|
8
|
+
ON = 'ON'
|
9
|
+
OFF = 'OFF'
|
10
|
+
SIGNAL = 'SIGNAL'
|
11
|
+
|
12
|
+
module SIGNALS
|
13
|
+
SIGPROF = 'PROF'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def instance
|
19
|
+
@instance ||= new
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :mode, :signal
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@mode = Modes::SIGNAL
|
27
|
+
@signal = Modes::SIGNALS::SIGPROF
|
28
|
+
enable_trap
|
29
|
+
end
|
30
|
+
|
31
|
+
def mode=(new_mode)
|
32
|
+
handle_old_mode
|
33
|
+
@mode = new_mode
|
34
|
+
handle_new_mode
|
35
|
+
end
|
36
|
+
|
37
|
+
def signal=(new_signal)
|
38
|
+
disable_trap
|
39
|
+
@signal = new_signal
|
40
|
+
enable_trap
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_tracer(tracer)
|
44
|
+
StaticTracing.tracers << tracer
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def handle_old_mode
|
50
|
+
disable_trap if @mode == Modes::SIGNAL
|
51
|
+
end
|
52
|
+
|
53
|
+
def handle_new_mode
|
54
|
+
if @mode == Modes::SIGNAL
|
55
|
+
enable_trap
|
56
|
+
elsif @mode == Modes::ON
|
57
|
+
StaticTracing.enable!
|
58
|
+
elsif @mode == Modes::OFF
|
59
|
+
StaticTracing.disable!
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def disable_trap
|
64
|
+
Signal.trap(@signal, 'DEFAULT')
|
65
|
+
end
|
66
|
+
|
67
|
+
def enable_trap
|
68
|
+
Signal.trap(@signal) { StaticTracing.toggle_tracing! }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StaticTracing
|
4
|
+
class Provider #:nodoc:
|
5
|
+
attr_accessor :name
|
6
|
+
class ProviderNotFound < StandardError; end
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def register(namespace)
|
10
|
+
providers[namespace] ||= new(namespace)
|
11
|
+
end
|
12
|
+
|
13
|
+
def fetch(namespace)
|
14
|
+
providers.fetch(namespace) do
|
15
|
+
raise ProviderNotFound
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def providers
|
22
|
+
@providers ||= {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :namespace
|
27
|
+
|
28
|
+
def initialize(namespace)
|
29
|
+
if StaticTracing::Platform.linux?
|
30
|
+
provider_initialize(namespace)
|
31
|
+
else
|
32
|
+
StaticTracing.issue_disabled_tracepoints_warning
|
33
|
+
end
|
34
|
+
@namespace = namespace
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_tracepoint(method_name, *args)
|
38
|
+
Tracepoint.new(namespace, method_name, *args)
|
39
|
+
end
|
40
|
+
|
41
|
+
# FIXME - how to store list of tracepoints on provider? Allocate map in C?
|
42
|
+
# def tracepoints
|
43
|
+
# []
|
44
|
+
# end
|
45
|
+
def enable
|
46
|
+
end
|
47
|
+
|
48
|
+
def disable
|
49
|
+
end
|
50
|
+
|
51
|
+
# FIXME add binding to check if enabled
|
52
|
+
def enabled?
|
53
|
+
end
|
54
|
+
|
55
|
+
def destroy
|
56
|
+
end
|
57
|
+
|
58
|
+
def provider_initialize(*)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StaticTracing
|
4
|
+
class Tracepoint #:nodoc:
|
5
|
+
|
6
|
+
class InvalidArgumentError < StandardError; end
|
7
|
+
class InvalidArgType < StandardError; end
|
8
|
+
|
9
|
+
VALID_ARGS_TYPES = [Integer, String]
|
10
|
+
|
11
|
+
attr_reader :provider, :name, :args
|
12
|
+
|
13
|
+
def initialize(provider, name, *args)
|
14
|
+
@provider = provider
|
15
|
+
@name = name
|
16
|
+
validate_args(args)
|
17
|
+
@args = args
|
18
|
+
|
19
|
+
if StaticTracing::Platform.linux?
|
20
|
+
tracepoint_initialize(provider, name, args)
|
21
|
+
else
|
22
|
+
StaticTracing.issue_disabled_tracepoints_warning
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def fire(*values)
|
27
|
+
values.each_with_index do |arg, i|
|
28
|
+
raise InvalidArgumentError unless arg.is_a?(args[i])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def enabled?
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def validate_args(values)
|
38
|
+
raise InvalidArgType unless values.all? { |value| VALID_ARGS_TYPES.include?(value) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ruby-static-tracing/tracers/latency_tracer'
|
4
|
+
|
5
|
+
module StaticTracing
|
6
|
+
module Tracers
|
7
|
+
module Concerns
|
8
|
+
module LatencyTracer
|
9
|
+
def self.included(base)
|
10
|
+
methods = base.public_instance_methods(false)
|
11
|
+
StaticTracing::Tracers::LatencyTracer.register(base, methods)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'unmixer'
|
3
|
+
|
4
|
+
using Unmixer
|
5
|
+
|
6
|
+
module StaticTracing
|
7
|
+
module Tracers
|
8
|
+
class LatencyTracer
|
9
|
+
class LatencyModuleGenerator < Module
|
10
|
+
def initialize(provider, methods)
|
11
|
+
methods.each do |method|
|
12
|
+
define_method(method) do |*args, &block|
|
13
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
|
14
|
+
result = super(*args, &block)
|
15
|
+
duration = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond) - start_time
|
16
|
+
LatencyTracer.fire_tracepoint(provider, method, duration)
|
17
|
+
result
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def register(klass, method_names, provider: nil)
|
25
|
+
provider ||= underscore(klass.name)
|
26
|
+
latency_module = LatencyModuleGenerator.new(provider, Array(method_names))
|
27
|
+
modified_classes[klass] = latency_module
|
28
|
+
end
|
29
|
+
|
30
|
+
def enable!
|
31
|
+
modified_classes.each do |klass, latency_module|
|
32
|
+
klass.prepend latency_module
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def disable!
|
37
|
+
modified_classes.each do |klass, latency_module|
|
38
|
+
klass.instance_eval { unprepend latency_module }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def fire_tracepoint(provider, name, duration)
|
43
|
+
return
|
44
|
+
tracepoint(provider, name).fire(name, duration)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def tracepoint(provider, name)
|
50
|
+
@tracepoints[name] ||= StaticTracing::Tracepoint.new(provider, name, String, Interger)
|
51
|
+
end
|
52
|
+
|
53
|
+
def modified_classes
|
54
|
+
@modified_classes ||= {}
|
55
|
+
end
|
56
|
+
|
57
|
+
def underscore(class_name)
|
58
|
+
class_name.gsub(/::/, '_').
|
59
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
60
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
61
|
+
tr("-", "_").
|
62
|
+
downcase
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-static-tracing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dale Hamel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -38,6 +38,48 @@ dependencies:
|
|
38
38
|
- - "<"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '11.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mocha
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
41
83
|
description: " A Ruby C extension that enables defining static tracepoints\n from
|
42
84
|
within a ruby context. \n"
|
43
85
|
email: dale.hamel@srvthe.net
|
@@ -47,9 +89,20 @@ extensions:
|
|
47
89
|
extra_rdoc_files: []
|
48
90
|
files:
|
49
91
|
- ext/ruby-static-tracing/extconf.rb
|
92
|
+
- ext/ruby-static-tracing/linux/provider.c
|
93
|
+
- ext/ruby-static-tracing/linux/provider.h
|
50
94
|
- ext/ruby-static-tracing/linux/ruby_static_tracing.c
|
95
|
+
- ext/ruby-static-tracing/linux/ruby_static_tracing.h
|
96
|
+
- ext/ruby-static-tracing/linux/tracepoint.c
|
97
|
+
- ext/ruby-static-tracing/linux/tracepoint.h
|
51
98
|
- lib/ruby-static-tracing.rb
|
99
|
+
- lib/ruby-static-tracing/configuration.rb
|
52
100
|
- lib/ruby-static-tracing/platform.rb
|
101
|
+
- lib/ruby-static-tracing/provider.rb
|
102
|
+
- lib/ruby-static-tracing/tracepoint.rb
|
103
|
+
- lib/ruby-static-tracing/tracers.rb
|
104
|
+
- lib/ruby-static-tracing/tracers/concerns/latency_tracer.rb
|
105
|
+
- lib/ruby-static-tracing/tracers/latency_tracer.rb
|
53
106
|
- lib/ruby-static-tracing/version.rb
|
54
107
|
homepage: https://github.com/dalehamel/ruby-static-tracing
|
55
108
|
licenses:
|
@@ -71,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
124
|
version: '0'
|
72
125
|
requirements: []
|
73
126
|
rubyforge_project:
|
74
|
-
rubygems_version: 2.
|
127
|
+
rubygems_version: 2.6.8
|
75
128
|
signing_key:
|
76
129
|
specification_version: 4
|
77
130
|
summary: USDT tracing for Ruby
|