perfetto 0.1.0 → 0.1.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.
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Perfetto
4
+ # Global configuration
5
+ class Configure
6
+ extend Configurable
7
+
8
+ set :enable_tracing, false
9
+ set :buffer_size_kb, 1024
10
+ end
11
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copy-pasted from https://github.com/midori-rb/midori.rb/blob/master/lib/midori/core_ext/configurable.rb
4
+ # rubocop:disable Style/OptionalBooleanParameter
5
+ # rubocop:disable Style/DocumentDynamicEvalDefinition
6
+ module Configurable
7
+ # Sets an option to the given value.
8
+ # @param [Symbol] option the name of config
9
+ # @param [Object] value value to the name
10
+ # @param [Boolean] read_only Generate option= method or not
11
+ # @return [nil] nil
12
+ def set(option, value = (not_set = true), read_only = false)
13
+ raise ArgumentError if not_set
14
+
15
+ setter = proc { |val| set option, val }
16
+ getter = proc { value }
17
+
18
+ define_singleton("#{option}=", setter) unless read_only
19
+ define_singleton(option, getter)
20
+ define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
21
+
22
+ self
23
+ end
24
+
25
+ private
26
+
27
+ # Dynamically defines a method on settings.
28
+ # @param [String] name method name
29
+ # @param [Proc] content method content
30
+ # @return [nil] nil
31
+ def define_singleton(name, content = Proc.new)
32
+ singleton_class.class_eval do
33
+ undef_method(name) if method_defined? name
34
+ if content.is_a?(String)
35
+ class_eval("def #{name}() #{content}; end", __FILE__,
36
+ __LINE__ - 1)
37
+ else
38
+ define_method(name, &content)
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ # rubocop:enable Style/OptionalBooleanParameter
45
+ # rubocop:enable Style/DocumentDynamicEvalDefinition
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Perfetto
4
+ # To intercept method calls in other classes
5
+ module Interceptor
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ # Class methods for the interceptor
11
+ module ClassMethods
12
+ if Perfetto::Configure.enable_tracing
13
+ def pftrace(method_name)
14
+ original_method = instance_method(method_name)
15
+ alias_method "pftrace_#{method_name}", method_name
16
+ define_method(method_name) do |*args, **kwargs, &block|
17
+ Perfetto.trace_event_begin self.class.name, method_name.to_s
18
+ original_method.bind(self).call(*args, **kwargs, &block)
19
+ Perfetto.trace_event_end self.class.name
20
+ end
21
+ end
22
+
23
+ def pftrace_all
24
+ instance_methods(false).each do |method_name|
25
+ pftrace method_name
26
+ end
27
+ end
28
+ else # When tracing is disabled
29
+ def pftrace(_method_name); end
30
+ def pftrace_all; end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ruby wrapper for native extension
4
+ module Perfetto
5
+ class << self
6
+ alias start_tracing_native start_tracing
7
+ alias stop_tracing_native stop_tracing
8
+ end
9
+
10
+ if Perfetto::Configure.enable_tracing
11
+ # Default arguments implemented in this wrapper
12
+ def self.start_tracing
13
+ start_tracing_native Configure.buffer_size_kb
14
+ end
15
+
16
+ def self.stop_tracing(trace_file_name = "#{Time.now.strftime("%Y%m%d%H%M%S")}.pftrace")
17
+ stop_tracing_native trace_file_name
18
+ end
19
+
20
+ # Methods implemented in native extension
21
+ # We don't want to proxy these methods because they are called very frequently on hot paths
22
+ # def self.start_tracing; end
23
+ # def self.stop_tracing(_trace_file_name); end
24
+ # def self.trace_event_begin(_class_name, _method_name); end
25
+ # def self.trace_event_end(_class_name); end
26
+ # def self.trace_counter(_class_name, _counter_name, _counter_value); end
27
+ # def self.trace_counter_i64(_class_name, _counter_name, _counter_value); end
28
+ # def self.trace_counter_double(_class_name, _counter_name, _counter_value); end
29
+ # def self.trace_event_instant(_class_name, _method_name); end
30
+ # def self.trace_event_begin_with_debug_info(_class_name, _method_name, _debug_key, _debug_value); end
31
+ # def self.trace_event_instant_with_debug_info(_class_name, _method_name, _debug_key, _debug_value); end
32
+ else
33
+ # Stub methods
34
+ def self.start_tracing; end
35
+ def self.stop_tracing(_trace_file_name); end
36
+ def self.trace_event_begin(_class_name, _method_name); end
37
+ def self.trace_event_end(_class_name); end
38
+ def self.trace_counter(_class_name, _counter_name, _counter_value); end
39
+ def self.trace_counter_i64(_class_name, _counter_name, _counter_value); end
40
+ def self.trace_counter_double(_class_name, _counter_name, _counter_value); end
41
+ def self.trace_event_instant(_class_name, _method_name); end
42
+ def self.trace_event_begin_with_debug_info(_class_name, _method_name, _debug_key, _debug_value); end
43
+ def self.trace_event_instant_with_debug_info(_class_name, _method_name, _debug_key, _debug_value); end
44
+ end
45
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Perfetto
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.2"
5
5
  end
data/lib/perfetto.rb CHANGED
@@ -2,7 +2,23 @@
2
2
 
3
3
  require_relative "perfetto/version"
4
4
 
5
+ require_relative "perfetto/core_ext/configurable"
6
+ require_relative "perfetto/configure"
7
+
8
+ # To minimize the overhead of tracing at runtime
9
+ # we determine whether to enable instrumentations
10
+ # at the first call to 'setup' method instead of
11
+ # every call to bussiness logics being traced.
5
12
  module Perfetto
6
- class Error < StandardError; end
7
- # Your code goes here...
13
+ def self.setup(enable_tracing: nil, buffer_size_kb: nil)
14
+ Configure.enable_tracing = enable_tracing unless enable_tracing.nil?
15
+ Configure.buffer_size_kb = buffer_size_kb unless buffer_size_kb.nil?
16
+
17
+ # Native extension
18
+ require_relative "perfetto/perfetto_native"
19
+ # Ruby wrapper
20
+ require_relative "perfetto/perfetto"
21
+ # Instrumentation Helper
22
+ require_relative "perfetto/interceptor"
23
+ end
8
24
  end
metadata CHANGED
@@ -1,26 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perfetto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kowalski Dark
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-01 00:00:00.000000000 Z
11
+ date: 2024-01-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Yet another event tracing library for Ruby.
14
14
  email:
15
15
  - github@akenonet.com
16
16
  executables: []
17
- extensions: []
17
+ extensions:
18
+ - ext/perfetto/extconf.rb
18
19
  extra_rdoc_files: []
19
20
  files:
20
21
  - ".rubocop.yml"
21
22
  - README.md
22
23
  - Rakefile
24
+ - example/example.png
25
+ - example/example.rb
26
+ - ext/perfetto/LICENSE
27
+ - ext/perfetto/README.md
28
+ - ext/perfetto/extconf.rb
29
+ - ext/perfetto/perfetto.c
30
+ - ext/perfetto/perfetto_internal.cc
31
+ - ext/perfetto/perfetto_internal.h
32
+ - ext/perfetto/sdk.cc
33
+ - ext/perfetto/sdk.h
23
34
  - lib/perfetto.rb
35
+ - lib/perfetto/configure.rb
36
+ - lib/perfetto/core_ext/configurable.rb
37
+ - lib/perfetto/interceptor.rb
38
+ - lib/perfetto/perfetto.rb
24
39
  - lib/perfetto/version.rb
25
40
  - sig/perfetto.rbs
26
41
  homepage: https://github.com/yet-another-ai/perfetto.rb
@@ -32,6 +47,7 @@ post_install_message:
32
47
  rdoc_options: []
33
48
  require_paths:
34
49
  - lib
50
+ - ext
35
51
  required_ruby_version: !ruby/object:Gem::Requirement
36
52
  requirements:
37
53
  - - ">="