ruby-static-tracing 0.0.13 → 0.0.14
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/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
|
- - ">="
|