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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/ext/ruby-static-tracing/darwin/provider.c +40 -52
  3. data/ext/ruby-static-tracing/darwin/provider.h +2 -3
  4. data/ext/ruby-static-tracing/darwin/ruby_static_tracing.c +4 -5
  5. data/ext/ruby-static-tracing/darwin/tracepoint.c +66 -91
  6. data/ext/ruby-static-tracing/darwin/tracepoint.h +4 -4
  7. data/ext/ruby-static-tracing/extconf.rb +40 -36
  8. data/ext/ruby-static-tracing/include/ruby_static_tracing.h +2 -1
  9. data/ext/ruby-static-tracing/lib/deps-extconf.rb +30 -28
  10. data/ext/ruby-static-tracing/lib/post-extconf.rb +23 -21
  11. data/ext/ruby-static-tracing/linux/provider.c +87 -61
  12. data/ext/ruby-static-tracing/linux/provider.h +16 -4
  13. data/ext/ruby-static-tracing/linux/ruby_static_tracing.c +7 -7
  14. data/ext/ruby-static-tracing/linux/tracepoint.c +86 -96
  15. data/ext/ruby-static-tracing/linux/tracepoint.h +2 -2
  16. data/ext/ruby-static-tracing/linux/types.h +2 -2
  17. data/lib/ruby-static-tracing.rb +11 -3
  18. data/lib/ruby-static-tracing/configuration.rb +11 -0
  19. data/lib/ruby-static-tracing/platform.rb +5 -1
  20. data/lib/ruby-static-tracing/provider.rb +50 -26
  21. data/lib/ruby-static-tracing/tracepoint.rb +19 -9
  22. data/lib/ruby-static-tracing/tracepoints.rb +2 -0
  23. data/lib/ruby-static-tracing/tracer/base.rb +2 -0
  24. data/lib/ruby-static-tracing/tracer/concerns/latency_tracer.rb +2 -0
  25. data/lib/ruby-static-tracing/tracer/helpers.rb +8 -8
  26. data/lib/ruby-static-tracing/tracer/latency.rb +1 -1
  27. data/lib/ruby-static-tracing/tracer/stack.rb +4 -2
  28. data/lib/ruby-static-tracing/tracers.rb +9 -0
  29. data/lib/ruby-static-tracing/version.rb +2 -1
  30. 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
- extend self
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
- class Provider #:nodoc:
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 do |provider|
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 do |provider|
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
- def initialize(namespace)
45
- if StaticTracing::Platform.supported_platform?
46
- provider_initialize(namespace)
47
- else
48
- StaticTracing.issue_disabled_tracepoints_warning
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
- @namespace = namespace
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
- # FIXME - how to store list of tracepoints on provider? Allocate map in C?
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
- # FIXME add binding to check if enabled
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
- def destroy
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
- def provider_initialize(*)
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 #:nodoc:
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 :provider, :name, :args
20
+ attr_reader :provider_name, :name, :args
22
21
 
23
- def initialize(provider, name, *args)
24
- @provider = provider
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(provider, name, args)
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 enabled?
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| VALID_ARGS_TYPES.include?(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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'unmixer'
2
4
  using Unmixer
3
5
 
@@ -3,6 +3,8 @@
3
3
  module StaticTracing
4
4
  module Tracer
5
5
  module Concerns
6
+ # Including this module will cause the target
7
+ # to have latency tracers added around every method
6
8
  module Latency
7
9
  def self.included(base)
8
10
  methods = base.public_instance_methods(false)
@@ -1,17 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module StaticTracing
2
4
  module Tracer
3
5
  module Helpers
4
- extend self
6
+ module_function
5
7
 
6
8
  def underscore(class_name)
7
- class_name.gsub(/::/, '_').
8
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
9
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
10
- tr("-", "_").
11
- downcase
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
-
@@ -3,7 +3,7 @@
3
3
  module StaticTracing
4
4
  module Tracer
5
5
  class Latency < Base
6
- set_wrapping_function -> (*args, &block) {
6
+ set_wrapping_function lambda { |*args, &block|
7
7
  start_time = StaticTracing.nsec
8
8
  result = super(*args, &block)
9
9
  duration = StaticTracing.nsec - start_time
@@ -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 -> (*args, &block) {
7
- current_stack = self.send(:caller).join("\n")
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
 
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StaticTracing
4
- VERSION = '0.0.13'
4
+ # The current version of this gem
5
+ VERSION = '0.0.14'
5
6
  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.13
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-20 00:00:00.000000000 Z
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: rake-compiler
28
+ name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0.9'
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.9'
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: minitest
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: mocha
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: pry-byebug
112
+ name: simplecov
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
115
  - - ">="