pyroscope 0.3.0-x86_64-linux → 0.4.0-x86_64-linux
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 +47 -33
- data/ext/rbspy/Cargo.toml +2 -0
- data/ext/rbspy/src/lib.rs +192 -69
- data/lib/pyroscope/version.rb +1 -1
- data/lib/pyroscope.rb +68 -37
- data/lib/rbspy/rbspy.so +0 -0
- data/lib/rbspy.libs/libcom_err-f79b9776.so.2.1 +0 -0
- data/lib/rbspy.libs/libcrypto-142cf8a3.so.1.0.1e +0 -0
- data/lib/rbspy.libs/libgssapi_krb5-bb73e344.so.2.2 +0 -0
- data/lib/rbspy.libs/libk5crypto-ab4ddf4c.so.3.1 +0 -0
- data/lib/rbspy.libs/libkeyutils-68db41cc.so.1.3 +0 -0
- data/lib/rbspy.libs/libkrb5-7e4170ab.so.3.3 +0 -0
- data/lib/rbspy.libs/libkrb5support-2ce1fd50.so.0.1 +0 -0
- data/lib/rbspy.libs/libselinux-d72a37e2.so.1 +0 -0
- data/lib/rbspy.libs/libssl-09014658.so.1.0.1e +0 -0
- data/lib/thread_id/thread_id.so +0 -0
- data/pyroscope.gemspec +16 -2
- data/scripts/tests/test.rb +59 -0
- metadata +14 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7e0a308394bd54ce968d7649712148526d1696b363c3d6e37f8b62bf8d83ceb
|
4
|
+
data.tar.gz: 7527ddda6ca70869a9115e8264510fc09ea4880aaa3e3da749efa07bd83334da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef8491839fcb25cb469c8d44ab1a57ccfc8100fb6d08b8ba12192063dc89289e741cde042e1b66f73fc4345ec2c7418535968d8399d5f41a54b3918b26046693
|
7
|
+
data.tar.gz: 48d7c8c58f94ba89ad36728a998fc04ed49e38a4bb4809eb0d602c1a1a3f7b7168cdeb4f498cc3b84d28b4eeb9a0dd72634c3653b7417f7c0ac5281041e07db7
|
data/README.md
CHANGED
@@ -1,57 +1,71 @@
|
|
1
|
-
Pyroscope Ruby
|
2
|
-
=====================================
|
1
|
+
# Pyroscope Ruby Gem
|
3
2
|
|
4
|
-
**
|
5
|
-
buggy and is frequently updated. For the initial implementation, find it [here](https://github.com/pyroscope-io/pyroscope-ruby). Please report any [issues](https://github.com/pyroscope-io/pyroscope-rs/issues).
|
3
|
+
**Pyroscope integration for Ruby**
|
6
4
|
|
7
|
-
|
5
|
+
[](LICENSE)
|
6
|
+

|
7
|
+

|
8
|
+
[](https://badge.fury.io/rb/pyroscope)
|
8
9
|
|
9
|
-
|
10
|
-
Rust:
|
10
|
+
---
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
export PATH=$PATH:/root/.cargo/bin
|
15
|
-
```
|
12
|
+
### What is Pyroscope
|
13
|
+
[Pyroscope](https://github.com/pyroscope-io/pyroscope) is a tool that lets you continuously profile your applications to prevent and debug performance issues in your code. It consists of a low-overhead agent which sends data to the Pyroscope server which includes a custom-built storage engine. This allows for you to store and query any applications profiling data in an extremely efficient and cost effective way.
|
16
14
|
|
17
|
-
2. Building/Insalling from Rubygems
|
18
15
|
|
19
|
-
|
20
|
-
gem install pyroscope_beta
|
21
|
-
```
|
16
|
+
### Supported platforms
|
22
17
|
|
23
|
-
|
18
|
+
| Linux | macOS | Windows | Docker |
|
19
|
+
|:-----:|:-----:|:-------:|:------:|
|
20
|
+
| ✅ | ✅ | | ✅ |
|
24
21
|
|
25
|
-
|
22
|
+
### Profiling Ruby applications
|
26
23
|
|
24
|
+
Add the `pyroscope` gem to your Gemfile:
|
25
|
+
|
26
|
+
```bash
|
27
|
+
bundle add pyroscope
|
27
28
|
```
|
28
|
-
gem build pyroscope.gemspec
|
29
|
-
gem install ./pyroscope.gemspec
|
30
|
-
```
|
31
29
|
|
32
|
-
|
30
|
+
### Basic Configuration
|
31
|
+
|
32
|
+
Add the following code to your application. If you're using rails, put this into `config/initializers` directory. This code will initialize pyroscope profiler and start profiling:
|
33
33
|
|
34
|
-
|
34
|
+
```ruby
|
35
|
+
require 'pyroscope'
|
35
36
|
|
37
|
+
Pyroscope.configure do |config|
|
38
|
+
config.application_name = "my.ruby.app" # replace this with some name for your application
|
39
|
+
config.server_address = "http://my-pyroscope-server:4040" # replace this with the address of your pyroscope server
|
40
|
+
# config.auth_token = "{YOUR_API_KEY}" # optionally, if authentication is enabled, specify the API key
|
41
|
+
end
|
36
42
|
```
|
37
|
-
|
43
|
+
|
44
|
+
### Tags
|
45
|
+
|
46
|
+
Pyroscope ruby integration provides a number of ways to tag profiling data. For example, you can provide tags when you're initializing the profiler:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
require 'pyroscope'
|
38
50
|
|
39
51
|
Pyroscope.configure do |config|
|
40
|
-
config.application_name = "ruby.app"
|
41
|
-
config.server_address
|
42
|
-
|
52
|
+
config.application_name = "my.ruby.app"
|
53
|
+
config.server_address = "http://my-pyroscope-server:4040"
|
54
|
+
|
43
55
|
config.tags = {
|
44
|
-
|
56
|
+
"hostname" => ENV["HOSTNAME"],
|
45
57
|
}
|
46
58
|
end
|
47
59
|
```
|
48
60
|
|
49
|
-
|
61
|
+
or you can dynamically tag certain parts of your code:
|
50
62
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
Pyroscope.tag_wrapper({"profile": "profile-1"}) do
|
55
|
-
// Tagged profile
|
63
|
+
```ruby
|
64
|
+
Pyroscope.tag_wrapper({ "controller": "slow_controller_i_want_to_profile" }) do
|
65
|
+
slow_code
|
56
66
|
end
|
57
67
|
```
|
68
|
+
|
69
|
+
### Example
|
70
|
+
|
71
|
+
Check out this [example ruby project in our repository](https://github.com/pyroscope-io/pyroscope/tree/main/examples/ruby) for examples of how you can use these features.
|
data/ext/rbspy/Cargo.toml
CHANGED
@@ -12,6 +12,8 @@ crate-type = ["cdylib"]
|
|
12
12
|
pyroscope = { path = "../../../../" }
|
13
13
|
#pyroscope_rbspy = { version = "0.2" }
|
14
14
|
pyroscope_rbspy = { path = "../../../../pyroscope_backends/pyroscope_rbspy" }
|
15
|
+
ffikit = { path = "../../../ffikit" }
|
16
|
+
pretty_env_logger = "0.4.0"
|
15
17
|
|
16
18
|
[patch.crates-io]
|
17
19
|
read-process-memory = {git = "https://github.com/omarabid/read-process-memory.git", branch = "0.1.4-fix"}
|
data/ext/rbspy/src/lib.rs
CHANGED
@@ -1,45 +1,117 @@
|
|
1
|
-
use
|
2
|
-
use
|
3
|
-
use pyroscope_rbspy::{rbspy_backend, RbspyConfig};
|
1
|
+
use std::collections::hash_map::DefaultHasher;
|
2
|
+
use std::env;
|
4
3
|
use std::ffi::CStr;
|
5
|
-
use std::
|
4
|
+
use std::hash::Hasher;
|
6
5
|
use std::os::raw::c_char;
|
7
|
-
use std::
|
8
|
-
use std::sync::{Mutex, Once};
|
6
|
+
use std::str::FromStr;
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
}
|
8
|
+
use ffikit::Signal;
|
9
|
+
use pyroscope_rbspy::{rbspy_backend, RbspyConfig};
|
10
|
+
|
11
|
+
use pyroscope::{pyroscope::Compression, PyroscopeAgent};
|
12
|
+
use pyroscope::backend::{Report, StackFrame, Tag};
|
13
|
+
|
14
|
+
pub fn transform_report(report: Report) -> Report {
|
15
|
+
let cwd = env::current_dir().unwrap();
|
16
|
+
let cwd = cwd.to_str().unwrap_or("");
|
17
|
+
|
18
|
+
let data = report
|
19
|
+
.data
|
20
|
+
.iter()
|
21
|
+
.map(|(stacktrace, count)| {
|
22
|
+
let new_frames = stacktrace
|
23
|
+
.frames
|
24
|
+
.iter()
|
25
|
+
.map(|frame| {
|
26
|
+
let frame = frame.to_owned();
|
27
|
+
let mut s = frame.filename.unwrap();
|
28
|
+
match s.find(cwd) {
|
29
|
+
Some(i) => {
|
30
|
+
s = s[(i + cwd.len() + 1)..].to_string();
|
31
|
+
}
|
32
|
+
None => match s.find("/gems/") {
|
33
|
+
Some(i) => {
|
34
|
+
s = s[(i + 1)..].to_string();
|
35
|
+
}
|
36
|
+
None => match s.find("/ruby/") {
|
37
|
+
Some(i) => {
|
38
|
+
s = s[(i + 6)..].to_string();
|
39
|
+
match s.find("/") {
|
40
|
+
Some(i) => {
|
41
|
+
s = s[(i + 1)..].to_string();
|
42
|
+
}
|
43
|
+
None => {}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
None => {}
|
47
|
+
},
|
48
|
+
},
|
49
|
+
}
|
50
|
+
|
51
|
+
// something
|
52
|
+
StackFrame::new(
|
53
|
+
frame.module,
|
54
|
+
frame.name,
|
55
|
+
Some(s.to_string()),
|
56
|
+
frame.relative_path,
|
57
|
+
frame.absolute_path,
|
58
|
+
frame.line,
|
59
|
+
)
|
60
|
+
})
|
61
|
+
.collect();
|
62
|
+
|
63
|
+
let mut mystack = stacktrace.to_owned();
|
64
|
+
|
65
|
+
mystack.frames = new_frames;
|
15
66
|
|
16
|
-
|
17
|
-
|
18
|
-
|
67
|
+
(mystack, count.to_owned())
|
68
|
+
})
|
69
|
+
.collect();
|
70
|
+
|
71
|
+
let new_report = Report::new(data).metadata(report.metadata.clone());
|
72
|
+
|
73
|
+
new_report
|
19
74
|
}
|
20
75
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
}
|
31
|
-
|
32
|
-
|
76
|
+
#[no_mangle]
|
77
|
+
pub extern "C" fn initialize_logging(logging_level: u32) -> bool {
|
78
|
+
// Force rustc to display the log messages in the console.
|
79
|
+
match logging_level {
|
80
|
+
50 => {
|
81
|
+
std::env::set_var("RUST_LOG", "error");
|
82
|
+
}
|
83
|
+
40 => {
|
84
|
+
std::env::set_var("RUST_LOG", "warn");
|
85
|
+
}
|
86
|
+
30 => {
|
87
|
+
std::env::set_var("RUST_LOG", "info");
|
88
|
+
}
|
89
|
+
20 => {
|
90
|
+
std::env::set_var("RUST_LOG", "debug");
|
91
|
+
}
|
92
|
+
10 => {
|
93
|
+
std::env::set_var("RUST_LOG", "trace");
|
94
|
+
}
|
95
|
+
_ => {
|
96
|
+
std::env::set_var("RUST_LOG", "debug");
|
97
|
+
}
|
98
|
+
}
|
33
99
|
|
34
|
-
|
100
|
+
// Initialize the logger.
|
101
|
+
pretty_env_logger::init_timed();
|
102
|
+
|
103
|
+
true
|
35
104
|
}
|
36
105
|
|
37
106
|
#[no_mangle]
|
38
107
|
pub extern "C" fn initialize_agent(
|
39
108
|
application_name: *const c_char, server_address: *const c_char, auth_token: *const c_char,
|
40
|
-
sample_rate: u32, detect_subprocesses: bool,
|
41
|
-
report_thread_id: bool, tags: *const c_char,
|
109
|
+
sample_rate: u32, detect_subprocesses: bool, oncpu: bool, report_pid: bool,
|
110
|
+
report_thread_id: bool, tags: *const c_char, compression: *const c_char
|
42
111
|
) -> bool {
|
112
|
+
// Initialize FFIKit
|
113
|
+
let recv = ffikit::initialize_ffi().unwrap();
|
114
|
+
|
43
115
|
let application_name = unsafe { CStr::from_ptr(application_name) }
|
44
116
|
.to_str()
|
45
117
|
.unwrap()
|
@@ -60,46 +132,64 @@ pub extern "C" fn initialize_agent(
|
|
60
132
|
.unwrap()
|
61
133
|
.to_string();
|
62
134
|
|
135
|
+
let compression_string = unsafe { CStr::from_ptr(compression) }
|
136
|
+
.to_str()
|
137
|
+
.unwrap()
|
138
|
+
.to_string();
|
139
|
+
|
140
|
+
let compression = Compression::from_str(&compression_string);
|
141
|
+
|
63
142
|
let pid = std::process::id();
|
64
143
|
|
65
|
-
let
|
144
|
+
let rbspy_config = RbspyConfig::new(pid.try_into().unwrap())
|
145
|
+
.sample_rate(sample_rate)
|
146
|
+
.lock_process(false)
|
147
|
+
.detect_subprocesses(detect_subprocesses)
|
148
|
+
.oncpu(oncpu)
|
149
|
+
.report_pid(report_pid)
|
150
|
+
.report_thread_id(report_thread_id);
|
66
151
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
if auth_token != "" {
|
85
|
-
agent_builder = agent_builder.auth_token(auth_token);
|
86
|
-
}
|
152
|
+
let tags_ref = tags_string.as_str();
|
153
|
+
let tags = string_to_tags(tags_ref);
|
154
|
+
let rbspy = rbspy_backend(rbspy_config);
|
155
|
+
|
156
|
+
let mut agent_builder = PyroscopeAgent::builder(server_address, application_name)
|
157
|
+
.backend(rbspy)
|
158
|
+
.func(transform_report)
|
159
|
+
.tags(tags);
|
160
|
+
|
161
|
+
if auth_token != "" {
|
162
|
+
agent_builder = agent_builder.auth_token(auth_token);
|
163
|
+
}
|
164
|
+
|
165
|
+
if let Ok(compression) = compression {
|
166
|
+
agent_builder = agent_builder.compression(compression);
|
167
|
+
}
|
87
168
|
|
88
|
-
|
169
|
+
let agent = agent_builder.build().unwrap();
|
89
170
|
|
90
|
-
|
171
|
+
let agent_running = agent.start().unwrap();
|
91
172
|
|
92
|
-
|
173
|
+
std::thread::spawn(move || {
|
174
|
+
while let Ok(signal) = recv.recv() {
|
93
175
|
match signal {
|
94
176
|
Signal::Kill => {
|
95
177
|
agent_running.stop().unwrap();
|
96
178
|
break;
|
97
179
|
}
|
98
|
-
Signal::
|
180
|
+
Signal::AddGlobalTag(name, value) => {
|
181
|
+
agent_running.add_global_tag(Tag::new(name, value)).unwrap();
|
182
|
+
}
|
183
|
+
Signal::RemoveGlobalTag(name, value) => {
|
184
|
+
agent_running
|
185
|
+
.remove_global_tag(Tag::new(name, value))
|
186
|
+
.unwrap();
|
187
|
+
}
|
188
|
+
Signal::AddThreadTag(thread_id, key, value) => {
|
99
189
|
let tag = Tag::new(key, value);
|
100
190
|
agent_running.add_thread_tag(thread_id, tag).unwrap();
|
101
191
|
}
|
102
|
-
Signal::
|
192
|
+
Signal::RemoveThreadTag(thread_id, key, value) => {
|
103
193
|
let tag = Tag::new(key, value);
|
104
194
|
agent_running.remove_thread_tag(thread_id, tag).unwrap();
|
105
195
|
}
|
@@ -112,40 +202,73 @@ pub extern "C" fn initialize_agent(
|
|
112
202
|
|
113
203
|
#[no_mangle]
|
114
204
|
pub extern "C" fn drop_agent() -> bool {
|
115
|
-
|
116
|
-
|
205
|
+
// Send Kill signal to the FFI merge channel.
|
206
|
+
ffikit::send(ffikit::Signal::Kill).unwrap();
|
207
|
+
|
117
208
|
true
|
118
209
|
}
|
119
210
|
|
120
211
|
#[no_mangle]
|
121
|
-
pub extern "C" fn
|
122
|
-
let s = signalpass();
|
212
|
+
pub extern "C" fn add_thread_tag(thread_id: u64, key: *const c_char, value: *const c_char) -> bool {
|
123
213
|
let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
|
124
214
|
let value = unsafe { CStr::from_ptr(value) }
|
125
215
|
.to_str()
|
126
216
|
.unwrap()
|
127
217
|
.to_owned();
|
128
|
-
|
129
|
-
|
218
|
+
|
219
|
+
let pid = std::process::id();
|
220
|
+
let mut hasher = DefaultHasher::new();
|
221
|
+
hasher.write_u64(thread_id % pid as u64);
|
222
|
+
let id = hasher.finish();
|
223
|
+
|
224
|
+
ffikit::send(ffikit::Signal::AddThreadTag(id, key, value)).unwrap();
|
225
|
+
|
226
|
+
true
|
227
|
+
}
|
228
|
+
|
229
|
+
#[no_mangle]
|
230
|
+
pub extern "C" fn remove_thread_tag(
|
231
|
+
thread_id: u64, key: *const c_char, value: *const c_char,
|
232
|
+
) -> bool {
|
233
|
+
let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
|
234
|
+
let value = unsafe { CStr::from_ptr(value) }
|
235
|
+
.to_str()
|
130
236
|
.unwrap()
|
131
|
-
.
|
132
|
-
|
237
|
+
.to_owned();
|
238
|
+
|
239
|
+
let pid = std::process::id();
|
240
|
+
let mut hasher = DefaultHasher::new();
|
241
|
+
hasher.write_u64(thread_id % pid as u64);
|
242
|
+
let id = hasher.finish();
|
243
|
+
|
244
|
+
ffikit::send(ffikit::Signal::RemoveThreadTag(id, key, value)).unwrap();
|
245
|
+
|
133
246
|
true
|
134
247
|
}
|
135
248
|
|
136
249
|
#[no_mangle]
|
137
|
-
pub extern "C" fn
|
138
|
-
let s = signalpass();
|
250
|
+
pub extern "C" fn add_global_tag(key: *const c_char, value: *const c_char) -> bool {
|
139
251
|
let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
|
140
252
|
let value = unsafe { CStr::from_ptr(value) }
|
141
253
|
.to_str()
|
142
254
|
.unwrap()
|
143
255
|
.to_owned();
|
144
|
-
|
145
|
-
|
256
|
+
|
257
|
+
ffikit::send(ffikit::Signal::AddGlobalTag(key, value)).unwrap();
|
258
|
+
|
259
|
+
true
|
260
|
+
}
|
261
|
+
|
262
|
+
#[no_mangle]
|
263
|
+
pub extern "C" fn remove_global_tag(key: *const c_char, value: *const c_char) -> bool {
|
264
|
+
let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
|
265
|
+
let value = unsafe { CStr::from_ptr(value) }
|
266
|
+
.to_str()
|
146
267
|
.unwrap()
|
147
|
-
.
|
148
|
-
|
268
|
+
.to_owned();
|
269
|
+
|
270
|
+
ffikit::send(ffikit::Signal::RemoveGlobalTag(key, value)).unwrap();
|
271
|
+
|
149
272
|
true
|
150
273
|
}
|
151
274
|
|
data/lib/pyroscope/version.rb
CHANGED
data/lib/pyroscope.rb
CHANGED
@@ -1,34 +1,42 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
1
4
|
require 'ffi'
|
2
5
|
|
3
|
-
module
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
module Pyroscope
|
7
|
+
module Rust
|
8
|
+
extend FFI::Library
|
9
|
+
ffi_lib File.expand_path(File.dirname(__FILE__)) + "/rbspy/rbspy.#{RbConfig::CONFIG["DLEXT"]}"
|
10
|
+
attach_function :initialize_logging, [:int], :bool
|
11
|
+
attach_function :initialize_agent, [:string, :string, :string, :int, :bool, :bool, :bool, :bool, :string, :string], :bool
|
12
|
+
attach_function :add_thread_tag, [:uint64, :string, :string], :bool
|
13
|
+
attach_function :remove_thread_tag, [:uint64, :string, :string], :bool
|
14
|
+
attach_function :add_global_tag, [:string, :string], :bool
|
15
|
+
attach_function :remove_global_tag, [:string, :string], :bool
|
16
|
+
attach_function :drop_agent, [], :bool
|
17
|
+
end
|
11
18
|
|
12
|
-
module Utils
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
19
|
+
module Utils
|
20
|
+
extend FFI::Library
|
21
|
+
ffi_lib File.expand_path(File.dirname(__FILE__)) + "/thread_id/thread_id.#{RbConfig::CONFIG["DLEXT"]}"
|
22
|
+
attach_function :thread_id, [], :uint64
|
23
|
+
end
|
17
24
|
|
18
|
-
|
19
|
-
Config = Struct.new(:application_name, :app_name, :server_address, :auth_token, :sample_rate, :detect_subprocesses, :on_cpu, :report_pid, :report_thread_id, :log_level, :tags) do
|
25
|
+
Config = Struct.new(:application_name, :app_name, :server_address, :auth_token, :log_level, :sample_rate, :detect_subprocesses, :oncpu, :report_pid, :report_thread_id, :tags, :compression) do
|
20
26
|
def initialize(*)
|
21
27
|
super
|
22
|
-
|
23
|
-
self.
|
24
|
-
self.
|
25
|
-
self.
|
26
|
-
self.
|
27
|
-
self.
|
28
|
-
self.
|
29
|
-
self.
|
30
|
-
self.
|
31
|
-
self.
|
28
|
+
# defaults:
|
29
|
+
self.application_name = ''
|
30
|
+
self.server_address = 'http://localhost:4040'
|
31
|
+
self.auth_token = ''
|
32
|
+
self.sample_rate = 100
|
33
|
+
self.detect_subprocesses = false
|
34
|
+
self.oncpu = true
|
35
|
+
self.report_pid = false
|
36
|
+
self.report_thread_id = false
|
37
|
+
self.log_level = 'error'
|
38
|
+
self.tags = {}
|
39
|
+
self.compression = 'gzip'
|
32
40
|
end
|
33
41
|
end
|
34
42
|
|
@@ -39,16 +47,39 @@ module Pyroscope
|
|
39
47
|
# Pass config to the block
|
40
48
|
yield @config
|
41
49
|
|
50
|
+
# Determine Logging level (kinda like an enum).
|
51
|
+
case @config.log_level
|
52
|
+
when 'trace'
|
53
|
+
@log_level = 10
|
54
|
+
when 'debug'
|
55
|
+
@log_level = 20
|
56
|
+
when 'info'
|
57
|
+
@log_level = 30
|
58
|
+
when 'warn'
|
59
|
+
@log_level = 40
|
60
|
+
when 'error'
|
61
|
+
@log_level = 50
|
62
|
+
else
|
63
|
+
@log_level = 50
|
64
|
+
end
|
65
|
+
|
66
|
+
# Initialize Logging
|
67
|
+
Rust.initialize_logging(@log_level)
|
68
|
+
|
69
|
+
|
70
|
+
# initialize Pyroscope Agent
|
42
71
|
Rust.initialize_agent(
|
43
|
-
|
44
|
-
@config.
|
45
|
-
@config.
|
46
|
-
@config.
|
47
|
-
@config.
|
48
|
-
@config.
|
49
|
-
@config.
|
50
|
-
@config.
|
51
|
-
|
72
|
+
# these are defaults in case user-provided values are nil:
|
73
|
+
@config.app_name || @config.application_name || "",
|
74
|
+
@config.server_address || "",
|
75
|
+
@config.auth_token || "",
|
76
|
+
@config.sample_rate || 100,
|
77
|
+
@config.detect_subprocesses || false,
|
78
|
+
@config.oncpu || false,
|
79
|
+
@config.report_pid || false,
|
80
|
+
@config.report_thread_id || false,
|
81
|
+
tags_to_string(@config.tags || {}),
|
82
|
+
@config.compression || ""
|
52
83
|
)
|
53
84
|
end
|
54
85
|
|
@@ -83,18 +114,18 @@ module Pyroscope
|
|
83
114
|
# add tags
|
84
115
|
def _add_tags(thread_id, tags)
|
85
116
|
tags.each do |tag_name, tag_value|
|
86
|
-
Rust.
|
117
|
+
Rust.add_thread_tag(thread_id, tag_name.to_s, tag_value.to_s)
|
87
118
|
end
|
88
119
|
end
|
89
120
|
|
90
121
|
# remove tags
|
91
122
|
def _remove_tags(thread_id, tags)
|
92
123
|
tags.each do |tag_name, tag_value|
|
93
|
-
Rust.
|
124
|
+
Rust.remove_thread_tag(thread_id, tag_name.to_s, tag_value.to_s)
|
94
125
|
end
|
95
126
|
end
|
96
127
|
|
97
|
-
def
|
128
|
+
def shutdown
|
98
129
|
Rust.drop_agent
|
99
130
|
end
|
100
131
|
end
|
data/lib/rbspy/rbspy.so
CHANGED
Binary file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/thread_id/thread_id.so
CHANGED
Binary file
|
data/pyroscope.gemspec
CHANGED
@@ -1,4 +1,11 @@
|
|
1
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
begin
|
5
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "lib/pyroscope/version"))
|
6
|
+
rescue LoadError
|
7
|
+
puts "WARNING: Could not load Pyroscope::VERSION"
|
8
|
+
end
|
2
9
|
|
3
10
|
Gem::Specification.new do |s|
|
4
11
|
s.name = 'pyroscope'
|
@@ -9,6 +16,13 @@ Gem::Specification.new do |s|
|
|
9
16
|
s.email = ['contact@pyroscope.io']
|
10
17
|
s.homepage = 'https://pyroscope.io'
|
11
18
|
s.license = 'Apache-2.0'
|
19
|
+
s.metadata = {
|
20
|
+
"homepage_uri" => "https://pyroscope.io",
|
21
|
+
"bug_tracker_uri" => "https://github.com/pyroscope-io/pyroscope-rs/issues",
|
22
|
+
"documentation_uri" => "https://pyroscope.io/docs/ruby/",
|
23
|
+
"changelog_uri" => "https://github.com/pyroscope-io/pyroscope-rs/tree/main/pyroscope_ffi/ruby/CHANGELOG.md",
|
24
|
+
"source_code_uri" => "https://github.com/pyroscope-io/pyroscope-rs/tree/main/pyroscope_ffi/ruby",
|
25
|
+
}
|
12
26
|
|
13
27
|
# Specify which files should be added to the gem when it is released.
|
14
28
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -21,7 +35,7 @@ Gem::Specification.new do |s|
|
|
21
35
|
|
22
36
|
s.platform = Gem::Platform::RUBY
|
23
37
|
|
24
|
-
s.required_ruby_version = ">=
|
38
|
+
s.required_ruby_version = ">= 1.9.3"
|
25
39
|
|
26
40
|
s.extensions = ['ext/rbspy/extconf.rb', 'ext/thread_id/extconf.rb']
|
27
41
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "pyroscope"
|
4
|
+
require "pyroscope/version"
|
5
|
+
|
6
|
+
puts Pyroscope::VERSION
|
7
|
+
puts RUBY_VERSION
|
8
|
+
|
9
|
+
Pyroscope.configure do |config|
|
10
|
+
config.application_name = "#{ENV["PYROSCOPE_RUN_ID"]}"
|
11
|
+
config.server_address = "https://ingest.pyroscope.cloud"
|
12
|
+
config.auth_token = ENV["PYROSCOPE_API_TOKEN"]
|
13
|
+
config.detect_subprocesses = ENV["PYROSCOPE_DETECT_SUBPROCESSES"] == "1"
|
14
|
+
config.oncpu = ENV["PYROSCOPE_ONCPU"] == "1"
|
15
|
+
config.log_level = "trace"
|
16
|
+
config.report_pid = true
|
17
|
+
config.report_thread_id = true
|
18
|
+
config.tags = {
|
19
|
+
:region => "us-east",
|
20
|
+
:detect_subprocesses => ENV["PYROSCOPE_DETECT_SUBPROCESSES"],
|
21
|
+
:oncpu => ENV["PYROSCOPE_ONCPU"],
|
22
|
+
:version => ENV["RUBY_VERSION"],
|
23
|
+
:arch => ENV["PYROSCOPE_ARCH"]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def work(n)
|
28
|
+
i = 0
|
29
|
+
while i < n
|
30
|
+
i += 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def fast_function
|
35
|
+
Pyroscope.tag_wrapper({"function": "fast"}) do
|
36
|
+
work(2001002000)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def slow_function
|
41
|
+
work(8001008000)
|
42
|
+
end
|
43
|
+
|
44
|
+
child_pid = fork do
|
45
|
+
puts "This is the child process"
|
46
|
+
Pyroscope.tag_wrapper({"fork": "forked"}) do
|
47
|
+
slow_function()
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
puts "This is the master process."
|
52
|
+
|
53
|
+
Pyroscope.tag_wrapper({"fork": "master"}) do
|
54
|
+
fast_function()
|
55
|
+
end
|
56
|
+
|
57
|
+
puts "The PID of the child process is #{child_pid}"
|
58
|
+
|
59
|
+
Pyroscope.shutdown()
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pyroscope
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: x86_64-linux
|
6
6
|
authors:
|
7
7
|
- Pyroscope Team
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-06
|
11
|
+
date: 2022-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -98,11 +98,17 @@ files:
|
|
98
98
|
- lib/thread_id/thread_id.so
|
99
99
|
- pyroscope.gemspec
|
100
100
|
- scripts/docker.sh
|
101
|
+
- scripts/tests/test.rb
|
101
102
|
homepage: https://pyroscope.io
|
102
103
|
licenses:
|
103
104
|
- Apache-2.0
|
104
|
-
metadata:
|
105
|
-
|
105
|
+
metadata:
|
106
|
+
homepage_uri: https://pyroscope.io
|
107
|
+
bug_tracker_uri: https://github.com/pyroscope-io/pyroscope-rs/issues
|
108
|
+
documentation_uri: https://pyroscope.io/docs/ruby/
|
109
|
+
changelog_uri: https://github.com/pyroscope-io/pyroscope-rs/tree/main/pyroscope_ffi/ruby/CHANGELOG.md
|
110
|
+
source_code_uri: https://github.com/pyroscope-io/pyroscope-rs/tree/main/pyroscope_ffi/ruby
|
111
|
+
post_install_message:
|
106
112
|
rdoc_options: []
|
107
113
|
require_paths:
|
108
114
|
- lib
|
@@ -110,15 +116,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
116
|
requirements:
|
111
117
|
- - ">="
|
112
118
|
- !ruby/object:Gem::Version
|
113
|
-
version:
|
119
|
+
version: 1.9.3
|
114
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
121
|
requirements:
|
116
122
|
- - ">="
|
117
123
|
- !ruby/object:Gem::Version
|
118
124
|
version: '0'
|
119
125
|
requirements: []
|
120
|
-
rubygems_version: 3.3.
|
121
|
-
signing_key:
|
126
|
+
rubygems_version: 3.3.7
|
127
|
+
signing_key:
|
122
128
|
specification_version: 4
|
123
129
|
summary: Pyroscope
|
124
130
|
test_files: []
|