perfetto 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  - - ">="