ruby-static-tracing 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/ruby-static-tracing/darwin/provider.c +40 -52
- data/ext/ruby-static-tracing/darwin/provider.h +2 -3
- data/ext/ruby-static-tracing/darwin/ruby_static_tracing.c +4 -5
- data/ext/ruby-static-tracing/darwin/tracepoint.c +66 -91
- data/ext/ruby-static-tracing/darwin/tracepoint.h +4 -4
- data/ext/ruby-static-tracing/extconf.rb +40 -36
- data/ext/ruby-static-tracing/include/ruby_static_tracing.h +2 -1
- data/ext/ruby-static-tracing/lib/deps-extconf.rb +30 -28
- data/ext/ruby-static-tracing/lib/post-extconf.rb +23 -21
- data/ext/ruby-static-tracing/linux/provider.c +87 -61
- data/ext/ruby-static-tracing/linux/provider.h +16 -4
- data/ext/ruby-static-tracing/linux/ruby_static_tracing.c +7 -7
- data/ext/ruby-static-tracing/linux/tracepoint.c +86 -96
- data/ext/ruby-static-tracing/linux/tracepoint.h +2 -2
- data/ext/ruby-static-tracing/linux/types.h +2 -2
- data/lib/ruby-static-tracing.rb +11 -3
- data/lib/ruby-static-tracing/configuration.rb +11 -0
- data/lib/ruby-static-tracing/platform.rb +5 -1
- data/lib/ruby-static-tracing/provider.rb +50 -26
- data/lib/ruby-static-tracing/tracepoint.rb +19 -9
- data/lib/ruby-static-tracing/tracepoints.rb +2 -0
- data/lib/ruby-static-tracing/tracer/base.rb +2 -0
- data/lib/ruby-static-tracing/tracer/concerns/latency_tracer.rb +2 -0
- data/lib/ruby-static-tracing/tracer/helpers.rb +8 -8
- data/lib/ruby-static-tracing/tracer/latency.rb +1 -1
- data/lib/ruby-static-tracing/tracer/stack.rb +4 -2
- data/lib/ruby-static-tracing/tracers.rb +9 -0
- data/lib/ruby-static-tracing/version.rb +2 -1
- metadata +42 -14
@@ -1,17 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module StaticTracing
|
4
|
+
# Platform detection for ruby-static-tracing
|
4
5
|
module Platform
|
5
|
-
|
6
|
+
module_function
|
6
7
|
|
8
|
+
# Returns true if platform is linux
|
7
9
|
def linux?
|
8
10
|
/linux/.match(RUBY_PLATFORM)
|
9
11
|
end
|
10
12
|
|
13
|
+
# Returns true if platform is darwin
|
11
14
|
def darwin?
|
12
15
|
/darwin/.match(RUBY_PLATFORM)
|
13
16
|
end
|
14
17
|
|
18
|
+
# Returns true if platform is known to be supported
|
15
19
|
def supported_platform?
|
16
20
|
linux? || darwin?
|
17
21
|
end
|
@@ -1,77 +1,101 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module StaticTracing
|
4
|
-
|
4
|
+
# A wrapper for a USDT tracepoint provider
|
5
|
+
# This corresponds to a namespace of tracepoints
|
6
|
+
# By convention, we will often create one per
|
7
|
+
# class or module.
|
8
|
+
class Provider
|
5
9
|
attr_accessor :name
|
10
|
+
|
11
|
+
# Provider couldn't be found in collection
|
6
12
|
class ProviderNotFound < StandardError; end
|
7
13
|
|
8
14
|
class << self
|
15
|
+
# Gets a provider by name
|
16
|
+
# or creates one if not exists
|
9
17
|
def register(namespace)
|
10
18
|
providers[namespace] ||= new(namespace)
|
11
19
|
end
|
12
20
|
|
21
|
+
# Gets a provider instance by name
|
13
22
|
def fetch(namespace)
|
14
23
|
providers.fetch(namespace) do
|
15
24
|
raise ProviderNotFound
|
16
25
|
end
|
17
26
|
end
|
18
27
|
|
28
|
+
# Enables each provider, ensuring
|
29
|
+
# it is loaded into memeory
|
19
30
|
def enable!
|
20
|
-
providers.values.each
|
21
|
-
provider.enable
|
22
|
-
end
|
31
|
+
providers.values.each(&:enable)
|
23
32
|
end
|
24
33
|
|
34
|
+
# Forcefully disables all providers,
|
35
|
+
# unloading them from memory
|
25
36
|
def disable!
|
26
|
-
providers.values.each
|
27
|
-
provider.disable
|
28
|
-
end
|
37
|
+
providers.values.each(&:disable)
|
29
38
|
end
|
30
39
|
|
31
40
|
def clean
|
41
|
+
# FIXME: this should free first
|
32
42
|
@providers = {}
|
33
43
|
end
|
34
44
|
|
35
45
|
private
|
36
46
|
|
47
|
+
# A global collection of providers
|
37
48
|
def providers
|
38
49
|
@providers ||= {}
|
39
50
|
end
|
40
51
|
end
|
41
52
|
|
42
|
-
attr_reader :namespace
|
53
|
+
attr_reader :namespace, :tracepoints
|
43
54
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
55
|
+
# Adds a new tracepoint to this provider
|
56
|
+
# FIXME - should this be a dictionary, or are duplicate names allowed?
|
57
|
+
def add_tracepoint(tracepoint, *args)
|
58
|
+
if tracepoint.is_a?(String)
|
59
|
+
tracepoint = Tracepoint.new(namespace, tracepoint, *args)
|
60
|
+
elsif tracepoint.is_a?(Tracepoint)
|
61
|
+
@tracepoints << tracepoint
|
49
62
|
end
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
def add_tracepoint(method_name, *args)
|
54
|
-
Tracepoint.new(namespace, method_name, *args)
|
63
|
+
tracepoint
|
55
64
|
end
|
56
65
|
|
57
|
-
#
|
58
|
-
# def tracepoints
|
59
|
-
# []
|
60
|
-
# end
|
66
|
+
# Enable the provider, loading it into memory
|
61
67
|
def enable
|
68
|
+
@enabled = _enable_provider
|
62
69
|
end
|
63
70
|
|
71
|
+
# Disables the provider, unloading it from memory
|
64
72
|
def disable
|
73
|
+
@enabled = !_disable_provider
|
65
74
|
end
|
66
75
|
|
67
|
-
#
|
76
|
+
# Returns true if the provider is enabled,
|
77
|
+
# meaning it is loaded into memory
|
68
78
|
def enabled?
|
79
|
+
@enabled
|
69
80
|
end
|
70
81
|
|
71
|
-
|
72
|
-
end
|
82
|
+
# Only supported on systems (linux) where backed by file
|
83
|
+
def path; end
|
84
|
+
|
85
|
+
def destroy; end
|
86
|
+
|
87
|
+
private
|
73
88
|
|
74
|
-
|
89
|
+
# ALWAYS use register, never call .new dilectly
|
90
|
+
def initialize(namespace)
|
91
|
+
if StaticTracing::Platform.supported_platform?
|
92
|
+
provider_initialize(namespace)
|
93
|
+
@enabled = false
|
94
|
+
else
|
95
|
+
StaticTracing.issue_disabled_tracepoints_warning
|
96
|
+
end
|
97
|
+
@namespace = namespace
|
98
|
+
@tracepoints = []
|
75
99
|
end
|
76
100
|
end
|
77
101
|
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module StaticTracing
|
4
|
-
class Tracepoint
|
5
|
-
|
4
|
+
class Tracepoint
|
6
5
|
class InvalidArgumentError < StandardError
|
7
6
|
def initialize(argument, expected_type)
|
8
7
|
error_message = <<~ERROR_MESSAGE
|
@@ -16,23 +15,29 @@ module StaticTracing
|
|
16
15
|
end
|
17
16
|
class InvalidArgType < StandardError; end
|
18
17
|
|
19
|
-
VALID_ARGS_TYPES = [Integer, String]
|
18
|
+
VALID_ARGS_TYPES = [Integer, String].freeze
|
20
19
|
|
21
|
-
attr_reader :
|
20
|
+
attr_reader :provider_name, :name, :args
|
22
21
|
|
23
|
-
|
24
|
-
|
22
|
+
# Creates a new tracepoint.
|
23
|
+
# If a provider by the name specified doesn't exist already,
|
24
|
+
# one will be added implicitly.
|
25
|
+
def initialize(provider_name, name, *args)
|
26
|
+
@provider_name = provider_name
|
25
27
|
@name = name
|
26
28
|
validate_args(args)
|
27
29
|
@args = args
|
28
30
|
|
29
31
|
if StaticTracing::Platform.supported_platform?
|
30
|
-
tracepoint_initialize(
|
32
|
+
tracepoint_initialize(provider_name, name, args)
|
33
|
+
provider.add_tracepoint(self)
|
31
34
|
else
|
32
35
|
StaticTracing.issue_disabled_tracepoints_warning
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
39
|
+
# Fire a tracepoint, sending the data off to be received by
|
40
|
+
# a tracing program like dtrace
|
36
41
|
def fire(*values)
|
37
42
|
values.each_with_index do |arg, i|
|
38
43
|
raise InvalidArgumentError.new(arg, args[i]) unless arg.is_a?(args[i])
|
@@ -40,13 +45,18 @@ module StaticTracing
|
|
40
45
|
_fire_tracepoint(values)
|
41
46
|
end
|
42
47
|
|
43
|
-
def
|
48
|
+
def provider
|
49
|
+
Provider.fetch(@provider_name)
|
44
50
|
end
|
45
51
|
|
52
|
+
# Returns true if a tracepoint is currently
|
53
|
+
# attached to, indicating we should fire it
|
54
|
+
def enabled?; end
|
55
|
+
|
46
56
|
private
|
47
57
|
|
48
58
|
def validate_args(values)
|
49
|
-
raise InvalidArgType unless values.all? { |value|
|
59
|
+
raise InvalidArgType unless values.all? { |value| VALID_ARGS_TYPES.include?(value) }
|
50
60
|
end
|
51
61
|
end
|
52
62
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module StaticTracing
|
4
|
+
# FIXME: - why do we need this class? We should store tracepoints
|
5
|
+
# on providers, and get the list of all tracepoints from the list of providers
|
4
6
|
class Tracepoints
|
5
7
|
class ProviderMissingError < StandardError; end
|
6
8
|
class TracepointMissingError < StandardError; end
|
@@ -1,17 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StaticTracing
|
2
4
|
module Tracer
|
3
5
|
module Helpers
|
4
|
-
|
6
|
+
module_function
|
5
7
|
|
6
8
|
def underscore(class_name)
|
7
|
-
class_name.gsub(/::/, '_')
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
class_name.gsub(/::/, '_')
|
10
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
11
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
12
|
+
.tr('-', '_')
|
13
|
+
.downcase
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
16
|
-
|
17
|
-
|
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
module StaticTracing
|
4
4
|
module Tracer
|
5
|
+
# A stack tracer gets the stack trace at point when
|
6
|
+
# the tracer is executed
|
5
7
|
class Stack < Base
|
6
|
-
set_wrapping_function
|
7
|
-
current_stack =
|
8
|
+
set_wrapping_function lambda { |*args, &block|
|
9
|
+
current_stack = send(:caller).join("\n")
|
8
10
|
method_name = __method__.to_s
|
9
11
|
provider = Tracer::Helpers.underscore(self.class.name)
|
10
12
|
Tracepoints.get(provider, method_name).fire(method_name, current_stack)
|
@@ -1,7 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module StaticTracing
|
4
|
+
# Tracers are a layer of abstraction above tracepoints. They are opinionated
|
5
|
+
# and contextual ways of applying tracepoints to an application.
|
4
6
|
class Tracers
|
7
|
+
# Error for an invalid tracer
|
5
8
|
class InvalidTracerError < StandardError
|
6
9
|
def initialize
|
7
10
|
msg = <<~MSG
|
@@ -17,18 +20,24 @@ module StaticTracing
|
|
17
20
|
class << self
|
18
21
|
def add(tracer)
|
19
22
|
raise InvalidTracerError unless tracer < StaticTracing::Tracer::Base
|
23
|
+
|
20
24
|
tracers << tracer
|
21
25
|
end
|
22
26
|
|
27
|
+
# Enables each tracer, overriding original
|
28
|
+
# method definition with traced one
|
23
29
|
def enable!
|
24
30
|
tracers.each(&:enable!)
|
25
31
|
end
|
26
32
|
|
33
|
+
# Disables each tracer, replacing the method definition
|
27
34
|
def disable!
|
28
35
|
tracers.each(&:disable!)
|
29
36
|
end
|
30
37
|
|
38
|
+
# Clears all tracers
|
31
39
|
def clean
|
40
|
+
# FIXME: - actuallly ensure destroyed to avoid memory leaks
|
32
41
|
@tracers = []
|
33
42
|
end
|
34
43
|
|
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.14
|
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-04-
|
11
|
+
date: 2019-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: unmixer
|
@@ -25,19 +25,47 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mocha
|
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: pry-byebug
|
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'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rake
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,21 +81,21 @@ dependencies:
|
|
53
81
|
- !ruby/object:Gem::Version
|
54
82
|
version: '11.0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
84
|
+
name: rake-compiler
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
|
-
- - "
|
87
|
+
- - "~>"
|
60
88
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
89
|
+
version: '0.9'
|
62
90
|
type: :development
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
|
-
- - "
|
94
|
+
- - "~>"
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
96
|
+
version: '0.9'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
98
|
+
name: rubocop
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
72
100
|
requirements:
|
73
101
|
- - ">="
|
@@ -81,7 +109,7 @@ dependencies:
|
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '0'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
112
|
+
name: simplecov
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
86
114
|
requirements:
|
87
115
|
- - ">="
|