perfetto 0.1.1 → 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.
- checksums.yaml +4 -4
- data/README.md +66 -0
- data/example/example.png +0 -0
- data/example/example.rb +64 -0
- data/lib/perfetto/configure.rb +11 -0
- data/lib/perfetto/core_ext/configurable.rb +45 -0
- data/lib/perfetto/interceptor.rb +34 -0
- data/lib/perfetto/perfetto.rb +33 -5
- data/lib/perfetto/version.rb +1 -1
- data/lib/perfetto.rb +19 -4
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a32a441d8046750cb3a306de9a3081e07fecd7c1223d53f7151db609d23f43d
|
4
|
+
data.tar.gz: 8dc578f6032ef6fb709b5a60b2fddf38afea8aa8f877cc27964f0db37dc52948
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29d28eb4c2153d6d798d0f9e17cd91e20dc68c6eb30af3d30210b39d96570a8494adedb0a2b01f9fddf68325bbdb365eb90b731d7c5560f9234a526455003b93
|
7
|
+
data.tar.gz: 585e6f74925e4c56cf1b524f1960d479ca9b5641dd7dff779225553512a51d7a4b970ba523de3554fa8f8debd5a975a8f71d817b59ecd10af34144d7548c0221
|
data/README.md
CHANGED
@@ -3,3 +3,69 @@
|
|
3
3
|
## Visualization
|
4
4
|
|
5
5
|
https://ui.perfetto.dev/
|
6
|
+
|
7
|
+
# Usage
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
|
11
|
+
require "perfetto"
|
12
|
+
|
13
|
+
Perfetto.setup enable_tracing: true
|
14
|
+
|
15
|
+
Perfetto.start_tracing
|
16
|
+
|
17
|
+
# Slice
|
18
|
+
# Stack frame is inferred from the begin event with the same category 'cpu_work'
|
19
|
+
Perfetto.trace_event_begin "cpu_work", "example_task"
|
20
|
+
sleep 0.1
|
21
|
+
Perfetto.trace_event_end "cpu_work"
|
22
|
+
|
23
|
+
# Slice with debug info
|
24
|
+
# Same as above, but "key"=>"value" is added to the event details
|
25
|
+
Perfetto.trace_event_begin_with_debug_info "cpu_work", "example_task2", "key", "value"
|
26
|
+
sleep 0.1
|
27
|
+
Perfetto.trace_event_end "cpu_work"
|
28
|
+
|
29
|
+
# Counter
|
30
|
+
10.times do |n|
|
31
|
+
Perfetto.trace_counter "rendering", "frame_rate", n.even? ? 60 : 30
|
32
|
+
sleep 0.1
|
33
|
+
end
|
34
|
+
Perfetto.trace_counter "rendering", "frame_rate", 0
|
35
|
+
|
36
|
+
# Instant
|
37
|
+
Perfetto.trace_event_instant "cpu_work", "example_instant"
|
38
|
+
|
39
|
+
sleep 0.1
|
40
|
+
|
41
|
+
# Instant with debug info
|
42
|
+
Perfetto.trace_event_instant_with_debug_info "cpu_work", "example_instant2", "key", "value"
|
43
|
+
|
44
|
+
sleep 0.1
|
45
|
+
|
46
|
+
class Foo
|
47
|
+
def bar(a, b = 1, c: 2)
|
48
|
+
yield(a + b + c)
|
49
|
+
end
|
50
|
+
|
51
|
+
def baz(x)
|
52
|
+
puts x
|
53
|
+
sleep 0.1
|
54
|
+
end
|
55
|
+
|
56
|
+
# Intercept instance methods
|
57
|
+
include Perfetto::Interceptor
|
58
|
+
pftrace_all
|
59
|
+
end
|
60
|
+
|
61
|
+
f = Foo.new
|
62
|
+
f.bar(1, 2, c: 3) do |n|
|
63
|
+
n.times do |x|
|
64
|
+
f.baz x + n
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
Perfetto.stop_tracing "example.pftrace"
|
69
|
+
```
|
70
|
+
|
71
|
+

|
data/example/example.png
ADDED
Binary file
|
data/example/example.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Naming/MethodParameterName
|
4
|
+
|
5
|
+
require "perfetto"
|
6
|
+
|
7
|
+
Perfetto.setup enable_tracing: true
|
8
|
+
|
9
|
+
Perfetto.start_tracing
|
10
|
+
|
11
|
+
# Slice
|
12
|
+
# Stack frame is inferred from the begin event with the same category 'cpu_work'
|
13
|
+
Perfetto.trace_event_begin "cpu_work", "example_task"
|
14
|
+
sleep 0.1
|
15
|
+
Perfetto.trace_event_end "cpu_work"
|
16
|
+
|
17
|
+
# Slice with debug info
|
18
|
+
# Same as above, but "key"=>"value" is added to the event details
|
19
|
+
Perfetto.trace_event_begin_with_debug_info "cpu_work", "example_task2", "key", "value"
|
20
|
+
sleep 0.1
|
21
|
+
Perfetto.trace_event_end "cpu_work"
|
22
|
+
|
23
|
+
# Counter
|
24
|
+
10.times do |n|
|
25
|
+
Perfetto.trace_counter "rendering", "frame_rate", n.even? ? 60 : 30
|
26
|
+
sleep 0.1
|
27
|
+
end
|
28
|
+
Perfetto.trace_counter "rendering", "frame_rate", 0
|
29
|
+
|
30
|
+
# Instant
|
31
|
+
Perfetto.trace_event_instant "cpu_work", "example_instant"
|
32
|
+
|
33
|
+
sleep 0.1
|
34
|
+
|
35
|
+
# Instant with debug info
|
36
|
+
Perfetto.trace_event_instant_with_debug_info "cpu_work", "example_instant2", "key", "value"
|
37
|
+
|
38
|
+
sleep 0.1
|
39
|
+
|
40
|
+
class Foo
|
41
|
+
def bar(a, b = 1, c: 2)
|
42
|
+
yield(a + b + c)
|
43
|
+
end
|
44
|
+
|
45
|
+
def baz(x)
|
46
|
+
puts x
|
47
|
+
sleep 0.1
|
48
|
+
end
|
49
|
+
|
50
|
+
# Intercept instance methods
|
51
|
+
include Perfetto::Interceptor
|
52
|
+
pftrace_all
|
53
|
+
end
|
54
|
+
|
55
|
+
f = Foo.new
|
56
|
+
f.bar(1, 2, c: 3) do |n|
|
57
|
+
n.times do |x|
|
58
|
+
f.baz x + n
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Perfetto.stop_tracing "example.pftrace"
|
63
|
+
|
64
|
+
# rubocop:enable Naming/MethodParameterName
|
@@ -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
|
data/lib/perfetto/perfetto.rb
CHANGED
@@ -7,11 +7,39 @@ module Perfetto
|
|
7
7
|
alias stop_tracing_native stop_tracing
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
13
19
|
|
14
|
-
|
15
|
-
|
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
|
16
44
|
end
|
17
45
|
end
|
data/lib/perfetto/version.rb
CHANGED
data/lib/perfetto.rb
CHANGED
@@ -2,8 +2,23 @@
|
|
2
2
|
|
3
3
|
require_relative "perfetto/version"
|
4
4
|
|
5
|
-
|
6
|
-
require_relative "perfetto/
|
5
|
+
require_relative "perfetto/core_ext/configurable"
|
6
|
+
require_relative "perfetto/configure"
|
7
7
|
|
8
|
-
#
|
9
|
-
|
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.
|
12
|
+
module Perfetto
|
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
|
24
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: perfetto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
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-
|
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:
|
@@ -21,6 +21,8 @@ files:
|
|
21
21
|
- ".rubocop.yml"
|
22
22
|
- README.md
|
23
23
|
- Rakefile
|
24
|
+
- example/example.png
|
25
|
+
- example/example.rb
|
24
26
|
- ext/perfetto/LICENSE
|
25
27
|
- ext/perfetto/README.md
|
26
28
|
- ext/perfetto/extconf.rb
|
@@ -30,6 +32,9 @@ files:
|
|
30
32
|
- ext/perfetto/sdk.cc
|
31
33
|
- ext/perfetto/sdk.h
|
32
34
|
- lib/perfetto.rb
|
35
|
+
- lib/perfetto/configure.rb
|
36
|
+
- lib/perfetto/core_ext/configurable.rb
|
37
|
+
- lib/perfetto/interceptor.rb
|
33
38
|
- lib/perfetto/perfetto.rb
|
34
39
|
- lib/perfetto/version.rb
|
35
40
|
- sig/perfetto.rbs
|