vernier 1.6.0 → 1.7.0
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 +6 -3
- data/exe/vernier +14 -0
- data/ext/vernier/vernier.cc +6 -7
- data/lib/vernier/autorun.rb +8 -1
- data/lib/vernier/collector.rb +3 -0
- data/lib/vernier/output/firefox.rb +12 -1
- data/lib/vernier/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2419244a8929351d5c81f18b90766f20d7d9e29d4909c876deb06d2a9ad39f2d
|
4
|
+
data.tar.gz: 94ead7ad3797a5cca2311cebc0ba0a57de369b7a6d09a07cbe4b6fad1f8826ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25551c8b2d537ca00de410e0bbd2173a2cd0452462f8c8ed5c27fd9b6592fa60f7ff1eceb01b429eba69b1989287a7244acef7448b4335b3e2ef87e731af59df
|
7
|
+
data.tar.gz: e510284f293ae3efd17e82c8e643b800ccbce5d84ffca04ef35fb16b5edf796672080465384cb40ea59eeacc7cc3cea57cb25e73805183956359a4e58e464f8c
|
data/README.md
CHANGED
@@ -4,9 +4,11 @@ Next-generation Ruby 3.2.1+ sampling profiler. Tracks multiple threads, GVL acti
|
|
4
4
|
|
5
5
|
<img width="500" alt="Screenshot 2024-02-29 at 22 47 43" src="https://github.com/jhawthorn/vernier/assets/131752/aa995a41-d74f-405f-8ada-2522dd72c2c8">
|
6
6
|
|
7
|
-
## Examples
|
7
|
+
## Demos and Examples
|
8
8
|
|
9
|
-
[Livestreamed demo: Pairin' with Aaron (YouTube)](https://www.youtube.com/watch?v=9nvX3OHykGQ#t=
|
9
|
+
[Livestreamed demo: Pairin' with Aaron (YouTube)](https://www.youtube.com/watch?v=9nvX3OHykGQ#t=27m40)
|
10
|
+
|
11
|
+
[Overview at RubyKaigi 2024 (YouTube)](https://youtu.be/QSjN-H4hGsM)
|
10
12
|
|
11
13
|
Sidekiq jobs from Mastodon (time, threaded)
|
12
14
|
: https://share.firefox.dev/44jZRf3
|
@@ -131,8 +133,9 @@ ruby -r vernier -e 'Vernier.trace_retained(out: "irb_profile.json") { require "i
|
|
131
133
|
| `mode` | N/A | Sampling mode: `:wall`, `:retained`, or `:custom`. | `:wall` (`:wall`) |
|
132
134
|
| `out` | N/A | File to write the profile to. | N/A (Auto-generated) |
|
133
135
|
| `interval` | `vernier_interval` | Sampling interval (µs). Only in `:wall` mode. | `500` (`200`) |
|
134
|
-
| `allocation_interval` | `vernier_allocation_interval` | Allocation sampling interval. Only in `:wall` mode. | `0
|
136
|
+
| `allocation_interval` | `vernier_allocation_interval` | Allocation sampling interval. Only in `:wall` mode. | `0`/disabled (`200`) |
|
135
137
|
| `gc` | N/A | Run full GC cycle before profiling. Only in `:retained` mode. | `true` (N/A) |
|
138
|
+
| `metadata` | N/A | Metadata key-value pairs to include in the profile. | `{}` (N/A) |
|
136
139
|
|
137
140
|
## Development
|
138
141
|
|
data/exe/vernier
CHANGED
@@ -7,6 +7,15 @@ require "vernier/version"
|
|
7
7
|
|
8
8
|
module Vernier
|
9
9
|
module CLI
|
10
|
+
class Metadata < Array
|
11
|
+
require 'json'
|
12
|
+
require 'base64'
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
Base64.encode64(to_json)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
10
19
|
def self.run(options)
|
11
20
|
banner = <<-END
|
12
21
|
Usage: vernier run [FLAGS] -- COMMAND
|
@@ -38,6 +47,11 @@ FLAGS:
|
|
38
47
|
o.on('--hooks [HOOKS]', String, "enable instrumentation hooks, currently supported: rails") do |s|
|
39
48
|
options[:hooks] = s
|
40
49
|
end
|
50
|
+
o.on("--metadata KEY=VALUE", String, "Set metadata key-value pairs (can be specified multiple times)") do |kv|
|
51
|
+
key, value = kv.split('=')
|
52
|
+
options[:metadata] ||= Metadata.new
|
53
|
+
options[:metadata] << [key, value]
|
54
|
+
end
|
41
55
|
end
|
42
56
|
end
|
43
57
|
|
data/ext/vernier/vernier.cc
CHANGED
@@ -74,8 +74,7 @@ static const char *gvl_event_name(rb_event_flag_t event) {
|
|
74
74
|
return "no-event";
|
75
75
|
}
|
76
76
|
|
77
|
-
|
78
|
-
struct FrameInfo {
|
77
|
+
struct FuncInfo {
|
79
78
|
static const char *label_cstr(VALUE frame) {
|
80
79
|
VALUE label = rb_profile_frame_full_label(frame);
|
81
80
|
// Currently (2025-03-22, Ruby 3.4.2) this occurs when an iseq method
|
@@ -100,7 +99,7 @@ struct FrameInfo {
|
|
100
99
|
return NIL_P(first_lineno) ? 0 : FIX2INT(first_lineno);
|
101
100
|
}
|
102
101
|
|
103
|
-
|
102
|
+
FuncInfo(VALUE frame) :
|
104
103
|
label(label_cstr(frame)),
|
105
104
|
file(file_cstr(frame)),
|
106
105
|
first_lineno(first_lineno_int(frame)) { }
|
@@ -110,7 +109,7 @@ struct FrameInfo {
|
|
110
109
|
int first_lineno;
|
111
110
|
};
|
112
111
|
|
113
|
-
bool operator==(const
|
112
|
+
bool operator==(const FuncInfo& lhs, const FuncInfo& rhs) noexcept {
|
114
113
|
return
|
115
114
|
lhs.label == rhs.label &&
|
116
115
|
lhs.file == rhs.file &&
|
@@ -266,13 +265,13 @@ struct StackTable {
|
|
266
265
|
|
267
266
|
struct FrameWithInfo {
|
268
267
|
Frame frame;
|
269
|
-
|
268
|
+
FuncInfo info;
|
270
269
|
};
|
271
270
|
|
272
271
|
IndexMap<Frame> frame_map;
|
273
272
|
|
274
273
|
IndexMap<VALUE> func_map;
|
275
|
-
std::vector<
|
274
|
+
std::vector<FuncInfo> func_info_list;
|
276
275
|
|
277
276
|
struct StackNode {
|
278
277
|
std::unordered_map<Frame, int> children;
|
@@ -363,7 +362,7 @@ struct StackTable {
|
|
363
362
|
for (int i = func_info_list.size(); i < func_map.size(); i++) {
|
364
363
|
const auto &func = func_map[i];
|
365
364
|
// must not hold a mutex here
|
366
|
-
func_info_list.push_back(
|
365
|
+
func_info_list.push_back(FuncInfo(func));
|
367
366
|
}
|
368
367
|
}
|
369
368
|
|
data/lib/vernier/autorun.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require "tempfile"
|
2
2
|
require "vernier"
|
3
|
+
require "base64"
|
4
|
+
require "json"
|
3
5
|
|
4
6
|
module Vernier
|
5
7
|
module Autorun
|
@@ -19,10 +21,15 @@ module Vernier
|
|
19
21
|
interval = options.fetch(:interval, 500).to_i
|
20
22
|
allocation_interval = options.fetch(:allocation_interval, 0).to_i
|
21
23
|
hooks = options.fetch(:hooks, "").split(",")
|
24
|
+
metadata = if options[:metadata]
|
25
|
+
JSON.parse(Base64.decode64(@options[:metadata])).to_h { |k, v| [k.to_sym, v] }
|
26
|
+
else
|
27
|
+
{}
|
28
|
+
end
|
22
29
|
|
23
30
|
STDERR.puts("starting profiler with interval #{interval} and allocation interval #{allocation_interval}")
|
24
31
|
|
25
|
-
@collector = Vernier::Collector.new(:wall, interval:, allocation_interval:, hooks:)
|
32
|
+
@collector = Vernier::Collector.new(:wall, interval:, allocation_interval:, hooks:, metadata:)
|
26
33
|
@collector.start
|
27
34
|
end
|
28
35
|
|
data/lib/vernier/collector.rb
CHANGED
@@ -25,6 +25,8 @@ module Vernier
|
|
25
25
|
@hooks.each do |hook|
|
26
26
|
hook.enable
|
27
27
|
end
|
28
|
+
|
29
|
+
@user_metadata = options[:metadata] || {}
|
28
30
|
end
|
29
31
|
|
30
32
|
private def add_hook(hook)
|
@@ -79,6 +81,7 @@ module Vernier
|
|
79
81
|
result.meta[:mode] = @mode
|
80
82
|
result.meta[:out] = @out
|
81
83
|
result.meta[:gc] = @gc
|
84
|
+
result.meta[:user_metadata] = @user_metadata
|
82
85
|
|
83
86
|
result.stack_table = stack_table
|
84
87
|
@thread_names.finish
|
@@ -145,7 +145,18 @@ module Vernier
|
|
145
145
|
end,
|
146
146
|
sourceCodeIsNotOnSearchfox: true,
|
147
147
|
initialVisibleThreads: threads.each_index.to_a,
|
148
|
-
initialSelectedThreads: Array(threads.find_index(&:is_start))
|
148
|
+
initialSelectedThreads: Array(threads.find_index(&:is_start)),
|
149
|
+
vernierUserMetadata: profile.meta[:user_metadata],
|
150
|
+
extra: [
|
151
|
+
label: "User-Supplied Metadata",
|
152
|
+
entries: profile.meta[:user_metadata].map do |k, v|
|
153
|
+
{
|
154
|
+
label: k,
|
155
|
+
format: "string",
|
156
|
+
value: v
|
157
|
+
}
|
158
|
+
end
|
159
|
+
]
|
149
160
|
},
|
150
161
|
counters: counter_data,
|
151
162
|
libs: [],
|
data/lib/vernier/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vernier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Hawthorn
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-03
|
10
|
+
date: 2025-04-03 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activesupport
|