pyroscope 0.6.7-x86_64-linux → 1.0.1-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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 980a62533a467f99c8413de6900b7824412c4cd5b0def132e36ceebee8a95fc2
4
- data.tar.gz: e71049b60b876d4749928b82502c0656014c4dd71ac0f6d81cc9fd5978094d90
3
+ metadata.gz: 1ade8d1bcc4662a4b114dd9269584efeff4d16748bfe0361617fc4f175148061
4
+ data.tar.gz: 27e9ad8182bee9a23e33cdf92e67df88d1c4c296e8e55756d9a08d1188f37d5e
5
5
  SHA512:
6
- metadata.gz: 5af9c6ad155253dc25dfe00216f7486e0d881a97c23cd3b6302bce1bbfaadf09f0ca5e58e93d8f689b4cdb60a8ec507e27549cd3a426203a806c4e3f8b8d73c0
7
- data.tar.gz: f21744a798340c93a0cd02bf5d287d29c9f180a55796f2f6142348fe449dab4319c52c75245789adde8800627d7bc378bd3e8d261954357995a2a88807ead418
6
+ metadata.gz: bee599d9924951fa2253037cf01bec4dceb1ee767256e6bc5b8a89842c0eacf3ed9809f5b972f46adba48e422c563946b452fb0ca046bb39a240054057417d6f
7
+ data.tar.gz: 165dee3e5880bccd6b8b6561353ebcb7aa10c0b7f23dd657310b20413f54fec36dd0208b6017a52801ffaf114a9d897127a1f18132804b3a3cbcaa4859fe611c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pyroscope (0.6.7)
4
+ pyroscope (1.0.1)
5
5
  ffi
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -37,7 +37,6 @@ require 'pyroscope'
37
37
  Pyroscope.configure do |config|
38
38
  config.application_name = "my.ruby.app" # replace this with some name for your application
39
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
40
  end
42
41
  ```
43
42
 
data/ext/rbspy/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "ffiruby"
3
- version = "0.1.0"
3
+ version = "0.0.1"
4
4
  edition = "2021"
5
5
  rust-version = "1.64"
6
6
 
@@ -10,12 +10,14 @@ crate-type = ["cdylib"]
10
10
 
11
11
  [dependencies]
12
12
  pyroscope = { path = "../../../../" }
13
- pyroscope_rbspy = { path = "../../../../pyroscope_backends/pyroscope_rbspy" }
14
- ffikit = { path = "../../../ffikit" }
13
+ rbspy = { version="0.42" }
14
+ remoteprocess = "0.5.0"
15
+ anyhow = "1.0"
15
16
  # todo remove this dependency
16
17
  pretty_env_logger = "0.5"
17
18
  log = "0.4"
19
+ libc = "0.2.180"
18
20
 
19
21
  [build-dependencies]
20
- cbindgen = "0.28"
22
+ cbindgen = "0.29"
21
23
 
@@ -1,15 +1,11 @@
1
- # The language to output bindings in
2
1
  language = "C"
3
2
  documentation_style = "C"
4
3
 
5
4
  style = "type"
6
5
 
7
- # An optional name to use as an include guard
8
6
  include_guard = "RBSPY_H_"
9
- # include a comment with the version of cbindgen used to generate the file
10
- include_version = true
7
+ include_version = false
11
8
 
12
- # An optional string of text to output at the beginning of the generated file
13
9
  header = "/* Licensed under Apache-2.0 */"
14
10
  autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
15
11
 
@@ -18,5 +14,4 @@ tab_width = 2
18
14
  line_length = 80
19
15
 
20
16
  [parse]
21
- # Do not parse dependent crates
22
17
  parse_deps = false
@@ -3,8 +3,6 @@
3
3
  #ifndef RBSPY_H_
4
4
  #define RBSPY_H_
5
5
 
6
- /* Generated with cbindgen:0.28.0 */
7
-
8
6
  /* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
9
7
 
10
8
  #include <stdarg.h>
@@ -16,28 +14,20 @@ bool initialize_logging(uint32_t logging_level);
16
14
 
17
15
  bool initialize_agent(const char *application_name,
18
16
  const char *server_address,
19
- const char *auth_token,
20
17
  const char *basic_auth_user,
21
18
  const char *basic_auth_password,
22
19
  uint32_t sample_rate,
23
- bool detect_subprocesses,
24
20
  bool oncpu,
25
21
  bool report_pid,
26
22
  bool report_thread_id,
27
23
  const char *tags,
28
- const char *compression,
29
- const char *_report_encoding,
30
24
  const char *tenant_id,
31
25
  const char *http_headers_json);
32
26
 
33
27
  bool drop_agent(void);
34
28
 
35
- bool add_thread_tag(uint64_t thread_id, const char *key, const char *value);
36
-
37
- bool remove_thread_tag(uint64_t thread_id, const char *key, const char *value);
38
-
39
- bool add_global_tag(const char *key, const char *value);
29
+ bool add_thread_tag(const char *key, const char *value);
40
30
 
41
- bool remove_global_tag(const char *key, const char *value);
31
+ bool remove_thread_tag(const char *key, const char *value);
42
32
 
43
33
  #endif /* RBSPY_H_ */
data/ext/rbspy/src/lib.rs CHANGED
@@ -1,20 +1,19 @@
1
- use std::collections::hash_map::DefaultHasher;
1
+ mod backend;
2
+
3
+ use rbspy::sampler::Sampler;
4
+ use remoteprocess::Pid;
2
5
  use std::env;
3
6
  use std::ffi::CStr;
4
- use std::hash::Hasher;
5
7
  use std::os::raw::c_char;
6
- use std::str::FromStr;
7
-
8
- use ffikit::Signal;
9
- use pyroscope_rbspy::{rbspy_backend, RbspyConfig};
10
8
 
9
+ use crate::backend::Rbspy;
11
10
  use pyroscope;
12
- use pyroscope::{pyroscope::Compression, PyroscopeAgent};
13
- use pyroscope::backend::{Report, StackFrame, Tag};
14
- use pyroscope::pyroscope::ReportEncoding;
11
+ use pyroscope::backend::{BackendConfig, BackendImpl, Report, StackFrame, Tag};
12
+ use pyroscope::pyroscope::PyroscopeAgentBuilder;
15
13
 
16
14
  const LOG_TAG: &str = "Pyroscope::rbspy::ffi";
17
-
15
+ const RBSPY_NAME: &str = "rbspy";
16
+ const RBSPY_VERSION: &str = "1.0.1";
18
17
 
19
18
  pub fn transform_report(report: Report) -> Report {
20
19
  let cwd = env::current_dir().unwrap();
@@ -112,39 +111,22 @@ pub extern "C" fn initialize_logging(logging_level: u32) -> bool {
112
111
  pub extern "C" fn initialize_agent(
113
112
  application_name: *const c_char,
114
113
  server_address: *const c_char,
115
- auth_token: *const c_char,
116
114
  basic_auth_user: *const c_char,
117
115
  basic_auth_password: *const c_char,
118
116
  sample_rate: u32,
119
- detect_subprocesses: bool,
120
117
  oncpu: bool,
121
118
  report_pid: bool,
122
119
  report_thread_id: bool,
123
120
  tags: *const c_char,
124
- compression: *const c_char,
125
- _report_encoding: *const c_char,
126
121
  tenant_id: *const c_char,
127
122
  http_headers_json: *const c_char,
128
123
  ) -> bool {
129
- // Initialize FFIKit
130
- let recv = ffikit::initialize_ffi().unwrap();
131
-
132
124
  let application_name = unsafe { CStr::from_ptr(application_name) }
133
125
  .to_str()
134
126
  .unwrap()
135
127
  .to_string();
136
128
 
137
- let mut server_address = unsafe { CStr::from_ptr(server_address) }
138
- .to_str()
139
- .unwrap()
140
- .to_string();
141
-
142
- let adhoc_server_address = std::env::var("PYROSCOPE_ADHOC_SERVER_ADDRESS");
143
- if let Ok(adhoc_server_address) = adhoc_server_address {
144
- server_address = adhoc_server_address
145
- }
146
-
147
- let auth_token = unsafe { CStr::from_ptr(auth_token) }
129
+ let server_address = unsafe { CStr::from_ptr(server_address) }
148
130
  .to_str()
149
131
  .unwrap()
150
132
  .to_string();
@@ -164,11 +146,6 @@ pub extern "C" fn initialize_agent(
164
146
  .unwrap()
165
147
  .to_string();
166
148
 
167
- let compression_string = unsafe { CStr::from_ptr(compression) }
168
- .to_str()
169
- .unwrap()
170
- .to_string();
171
-
172
149
  let tenant_id = unsafe { CStr::from_ptr(tenant_id) }
173
150
  .to_str()
174
151
  .unwrap()
@@ -179,31 +156,32 @@ pub extern "C" fn initialize_agent(
179
156
  .unwrap()
180
157
  .to_string();
181
158
 
182
- let compression = Compression::from_str(&compression_string);
183
-
184
159
  let pid = std::process::id();
185
160
 
186
- let rbspy_config = RbspyConfig::new(pid.try_into().unwrap())
187
- .sample_rate(sample_rate)
188
- .lock_process(false)
189
- .detect_subprocesses(detect_subprocesses)
190
- .oncpu(oncpu)
191
- .report_pid(report_pid)
192
- .report_thread_id(report_thread_id);
161
+ let backend_config = BackendConfig {
162
+ report_thread_id,
163
+ report_thread_name: false,
164
+ report_pid,
165
+ };
166
+
167
+ let sampler = Sampler::new(pid as Pid, sample_rate, false, None, false, None, oncpu);
193
168
 
194
169
  let tags_ref = tags_string.as_str();
195
170
  let tags = string_to_tags(tags_ref);
196
- let rbspy = rbspy_backend(rbspy_config);
197
-
198
- let mut agent_builder = PyroscopeAgent::builder(server_address, application_name)
199
- .backend(rbspy)
200
- .func(transform_report)
201
- .tags(tags)
202
- .report_encoding(ReportEncoding::PPROF);
203
-
204
- if auth_token != "" {
205
- agent_builder = agent_builder.auth_token(auth_token);
206
- } else if basic_auth_user != "" && basic_auth_password != "" {
171
+ let rbspy = BackendImpl::new(Box::new(Rbspy::new(sampler, sample_rate, backend_config)));
172
+
173
+ let mut agent_builder = PyroscopeAgentBuilder::new(
174
+ server_address,
175
+ application_name,
176
+ sample_rate,
177
+ RBSPY_NAME,
178
+ RBSPY_VERSION,
179
+ rbspy,
180
+ )
181
+ .func(transform_report)
182
+ .tags(tags);
183
+
184
+ if basic_auth_user != "" && basic_auth_password != "" {
207
185
  agent_builder = agent_builder.basic_auth(basic_auth_user, basic_auth_password);
208
186
  }
209
187
 
@@ -216,130 +194,55 @@ pub extern "C" fn initialize_agent(
216
194
  Ok(http_headers) => {
217
195
  agent_builder = agent_builder.http_headers(http_headers);
218
196
  }
219
- Err(e) => {
220
- match e {
221
- pyroscope::PyroscopeError::Json(e) => {
222
- log::error!(target: LOG_TAG, "parse_http_headers_json error {}", e);
223
- }
224
- pyroscope::PyroscopeError::AdHoc(e) => {
225
- log::error!(target: LOG_TAG, "parse_http_headers_json {}", e);
226
- }
227
- _ => {}
197
+ Err(e) => match e {
198
+ pyroscope::PyroscopeError::Json(e) => {
199
+ log::error!(target: LOG_TAG, "parse_http_headers_json error {}", e);
228
200
  }
229
- }
230
- }
231
-
232
- if let Ok(compression) = compression {
233
- agent_builder = agent_builder.compression(compression);
234
- }
235
-
236
- let agent = agent_builder.build().unwrap();
237
-
238
- let agent_running = agent.start().unwrap();
239
-
240
- std::thread::spawn(move || {
241
- while let Ok(signal) = recv.recv() {
242
- match signal {
243
- Signal::Kill => {
244
- agent_running.stop().unwrap();
245
- break;
246
- }
247
- Signal::AddGlobalTag(name, value) => {
248
- agent_running.add_global_tag(Tag::new(name, value)).unwrap();
249
- }
250
- Signal::RemoveGlobalTag(name, value) => {
251
- agent_running
252
- .remove_global_tag(Tag::new(name, value))
253
- .unwrap();
254
- }
255
- Signal::AddThreadTag(thread_id, key, value) => {
256
- let tag = Tag::new(key, value);
257
- agent_running.add_thread_tag(thread_id, tag).unwrap();
258
- }
259
- Signal::RemoveThreadTag(thread_id, key, value) => {
260
- let tag = Tag::new(key, value);
261
- agent_running.remove_thread_tag(thread_id, tag).unwrap();
262
- }
201
+ pyroscope::PyroscopeError::AdHoc(e) => {
202
+ log::error!(target: LOG_TAG, "parse_http_headers_json {}", e);
263
203
  }
264
- }
265
- });
204
+ _ => {}
205
+ },
206
+ }
266
207
 
267
- true
208
+ pyroscope::ffikit::run(agent_builder).is_ok()
268
209
  }
269
210
 
270
211
  #[no_mangle]
271
212
  pub extern "C" fn drop_agent() -> bool {
272
- // Send Kill signal to the FFI merge channel.
273
- ffikit::send(ffikit::Signal::Kill).unwrap();
274
-
275
- true
213
+ pyroscope::ffikit::send(pyroscope::ffikit::Signal::Kill).is_ok()
276
214
  }
277
215
 
278
216
  #[no_mangle]
279
- pub extern "C" fn add_thread_tag(thread_id: u64, key: *const c_char, value: *const c_char) -> bool {
217
+ pub extern "C" fn add_thread_tag(key: *const c_char, value: *const c_char) -> bool {
280
218
  let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
281
219
  let value = unsafe { CStr::from_ptr(value) }
282
220
  .to_str()
283
221
  .unwrap()
284
222
  .to_owned();
285
223
 
286
- let pid = std::process::id();
287
- let mut hasher = DefaultHasher::new();
288
- hasher.write_u64(thread_id % pid as u64);
289
- let id = hasher.finish();
290
-
291
- ffikit::send(ffikit::Signal::AddThreadTag(id, key, value)).unwrap();
292
-
293
- true
224
+ pyroscope::ffikit::send(pyroscope::ffikit::Signal::AddThreadTag(
225
+ backend::self_thread_id(),
226
+ Tag { key, value },
227
+ ))
228
+ .is_ok()
294
229
  }
295
230
 
296
231
  #[no_mangle]
297
- pub extern "C" fn remove_thread_tag(
298
- thread_id: u64, key: *const c_char, value: *const c_char,
299
- ) -> bool {
232
+ pub extern "C" fn remove_thread_tag(key: *const c_char, value: *const c_char) -> bool {
300
233
  let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
301
234
  let value = unsafe { CStr::from_ptr(value) }
302
235
  .to_str()
303
236
  .unwrap()
304
237
  .to_owned();
305
238
 
306
- let pid = std::process::id();
307
- let mut hasher = DefaultHasher::new();
308
- hasher.write_u64(thread_id % pid as u64);
309
- let id = hasher.finish();
310
-
311
- ffikit::send(ffikit::Signal::RemoveThreadTag(id, key, value)).unwrap();
312
-
313
- true
314
- }
315
-
316
- #[no_mangle]
317
- pub extern "C" fn add_global_tag(key: *const c_char, value: *const c_char) -> bool {
318
- let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
319
- let value = unsafe { CStr::from_ptr(value) }
320
- .to_str()
321
- .unwrap()
322
- .to_owned();
323
-
324
- ffikit::send(ffikit::Signal::AddGlobalTag(key, value)).unwrap();
325
-
326
- true
327
- }
328
-
329
- #[no_mangle]
330
- pub extern "C" fn remove_global_tag(key: *const c_char, value: *const c_char) -> bool {
331
- let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
332
- let value = unsafe { CStr::from_ptr(value) }
333
- .to_str()
334
- .unwrap()
335
- .to_owned();
336
-
337
- ffikit::send(ffikit::Signal::RemoveGlobalTag(key, value)).unwrap();
338
-
339
- true
239
+ pyroscope::ffikit::send(pyroscope::ffikit::Signal::RemoveThreadTag(
240
+ backend::self_thread_id(),
241
+ Tag { key, value },
242
+ ))
243
+ .is_ok()
340
244
  }
341
245
 
342
- // Convert a string of tags to a Vec<(&str, &str)>
343
246
  fn string_to_tags<'a>(tags: &'a str) -> Vec<(&'a str, &'a str)> {
344
247
  let mut tags_vec = Vec::new();
345
248
  // check if string is empty
@@ -1,3 +1,3 @@
1
1
  module Pyroscope
2
- VERSION = '0.6.7'.freeze
2
+ VERSION = '1.0.1'.freeze
3
3
  end
data/lib/pyroscope.rb CHANGED
@@ -9,20 +9,12 @@ module Pyroscope
9
9
  extend FFI::Library
10
10
  ffi_lib File.expand_path(File.dirname(__FILE__)) + "/rbspy/rbspy.#{RbConfig::CONFIG["DLEXT"]}"
11
11
  attach_function :initialize_logging, [:int], :bool
12
- attach_function :initialize_agent, [:string, :string, :string, :string, :string, :int, :bool, :bool, :bool, :bool, :string, :string, :string, :string, :string], :bool
13
- attach_function :add_thread_tag, [:uint64, :string, :string], :bool
14
- attach_function :remove_thread_tag, [:uint64, :string, :string], :bool
15
- attach_function :add_global_tag, [:string, :string], :bool
16
- attach_function :remove_global_tag, [:string, :string], :bool
12
+ attach_function :initialize_agent, [:string, :string, :string, :string, :int, :bool, :bool, :bool, :string, :string, :string], :bool
13
+ attach_function :add_thread_tag, [:string, :string], :bool
14
+ attach_function :remove_thread_tag, [:string, :string], :bool
17
15
  attach_function :drop_agent, [], :bool
18
16
  end
19
17
 
20
- module Utils
21
- extend FFI::Library
22
- ffi_lib File.expand_path(File.dirname(__FILE__)) + "/thread_id/thread_id.#{RbConfig::CONFIG["DLEXT"]}"
23
- attach_function :thread_id, [], :uint64
24
- end
25
-
26
18
  if defined?(::Rails::Engine)
27
19
  class Engine < ::Rails::Engine
28
20
  config.after_initialize do
@@ -37,12 +29,10 @@ module Pyroscope
37
29
  :application_name,
38
30
  :app_name,
39
31
  :server_address,
40
- :auth_token,
41
32
  :basic_auth_username,
42
33
  :basic_auth_password,
43
34
  :log_level,
44
35
  :sample_rate,
45
- :detect_subprocesses,
46
36
  :oncpu,
47
37
  :report_pid,
48
38
  :report_thread_id,
@@ -58,11 +48,9 @@ module Pyroscope
58
48
  # defaults:
59
49
  self.application_name = ''
60
50
  self.server_address = 'http://localhost:4040'
61
- self.auth_token = ''
62
51
  self.basic_auth_username = ''
63
52
  self.basic_auth_password = ''
64
53
  self.sample_rate = 100
65
- self.detect_subprocesses = false
66
54
  self.oncpu = true
67
55
  self.report_pid = false
68
56
  self.report_thread_id = false
@@ -109,17 +97,13 @@ module Pyroscope
109
97
  # these are defaults in case user-provided values are nil:
110
98
  @config.app_name || @config.application_name || "",
111
99
  @config.server_address || "",
112
- @config.auth_token || "",
113
100
  @config.basic_auth_username || "",
114
101
  @config.basic_auth_password || "",
115
102
  @config.sample_rate || 100,
116
- @config.detect_subprocesses || false,
117
103
  @config.oncpu || false,
118
104
  @config.report_pid || false,
119
105
  @config.report_thread_id || false,
120
106
  tags_to_string(@config.tags || {}),
121
- @config.compression || "",
122
- @config.report_encoding || "pprof",
123
107
  @config.tenant_id || "",
124
108
  http_headers_to_json(@config.http_headers || {})
125
109
  )
@@ -137,12 +121,11 @@ module Pyroscope
137
121
  end
138
122
 
139
123
  def tag_wrapper(tags)
140
- tid = thread_id
141
- _add_tags(tid, tags)
124
+ _add_tags(tags)
142
125
  begin
143
126
  yield
144
127
  ensure
145
- _remove_tags(tid, tags)
128
+ _remove_tags(tags)
146
129
  end
147
130
  end
148
131
 
@@ -154,19 +137,15 @@ module Pyroscope
154
137
  warn("deprecated. Use `Pyroscope.tag_wrapper` instead.")
155
138
  end
156
139
 
157
- def thread_id
158
- return Utils.thread_id
159
- end
160
-
161
- def _add_tags(thread_id, tags)
140
+ def _add_tags(tags)
162
141
  tags.each do |tag_name, tag_value|
163
- Rust.add_thread_tag(thread_id, tag_name.to_s, tag_value.to_s)
142
+ Rust.add_thread_tag(tag_name.to_s, tag_value.to_s)
164
143
  end
165
144
  end
166
145
 
167
- def _remove_tags(thread_id, tags)
146
+ def _remove_tags(tags)
168
147
  tags.each do |tag_name, tag_value|
169
- Rust.remove_thread_tag(thread_id, tag_name.to_s, tag_value.to_s)
148
+ Rust.remove_thread_tag(tag_name.to_s, tag_value.to_s)
170
149
  end
171
150
  end
172
151
 
data/lib/rbspy/rbspy.so CHANGED
Binary file
data/pyroscope.gemspec CHANGED
@@ -46,13 +46,6 @@ Gem::Specification.new do |s|
46
46
  "ext/rbspy/extconf.rb",
47
47
  "ext/rbspy/include/rbspy.h",
48
48
  "ext/rbspy/src/lib.rs",
49
- "ext/thread_id/Cargo.toml",
50
- "ext/thread_id/Rakefile",
51
- "ext/thread_id/build.rs",
52
- "ext/thread_id/cbindgen.toml",
53
- "ext/thread_id/extconf.rb",
54
- "ext/thread_id/include/thread_id.h",
55
- "ext/thread_id/src/lib.rs",
56
49
  "lib/pyroscope.rb",
57
50
  "lib/pyroscope/version.rb",
58
51
  "pyroscope.gemspec",
@@ -62,7 +55,7 @@ Gem::Specification.new do |s|
62
55
 
63
56
  s.required_ruby_version = ">= 1.9.3"
64
57
 
65
- s.extensions = ['ext/rbspy/extconf.rb', 'ext/thread_id/extconf.rb']
58
+ s.extensions = ['ext/rbspy/extconf.rb']
66
59
 
67
60
  s.add_dependency 'ffi'
68
61
 
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.6.7
4
+ version: 1.0.1
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - Pyroscope Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-09-17 00:00:00.000000000 Z
11
+ date: 2026-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -71,17 +71,9 @@ files:
71
71
  - ext/rbspy/extconf.rb
72
72
  - ext/rbspy/include/rbspy.h
73
73
  - ext/rbspy/src/lib.rs
74
- - ext/thread_id/Cargo.toml
75
- - ext/thread_id/Rakefile
76
- - ext/thread_id/build.rs
77
- - ext/thread_id/cbindgen.toml
78
- - ext/thread_id/extconf.rb
79
- - ext/thread_id/include/thread_id.h
80
- - ext/thread_id/src/lib.rs
81
74
  - lib/pyroscope.rb
82
75
  - lib/pyroscope/version.rb
83
76
  - lib/rbspy/rbspy.so
84
- - lib/thread_id/thread_id.so
85
77
  - pyroscope.gemspec
86
78
  homepage: https://pyroscope.io
87
79
  licenses:
@@ -1,15 +0,0 @@
1
- [package]
2
- name = "thread_id"
3
- version = "0.1.0"
4
- edition = "2021"
5
- rust-version = "1.64"
6
-
7
- [lib]
8
- name = "thread_id"
9
- crate-type = ["cdylib"]
10
-
11
- [dependencies]
12
- libc = "*"
13
-
14
- [build-dependencies]
15
- cbindgen = "0.28.0"
@@ -1,163 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "shellwords"
4
-
5
- class ThreadIdRakeCargoHelper
6
- attr_reader :gemname
7
-
8
- def initialize(gemname=File.basename(__dir__))
9
- @gemname = gemname
10
- end
11
-
12
- def self.command?(name)
13
- exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
14
- ENV["PATH"].split(File::PATH_SEPARATOR).any? do |path|
15
- exts.any? do |ext|
16
- exe = File.join(path, "#{name}#{ext}")
17
- File.executable?(exe) && !File.directory?(exe)
18
- end
19
- end
20
- end
21
-
22
- def self.rust_toolchain
23
- # return env variable if set
24
- target = ENV["RUST_TARGET"]
25
- return target if target
26
-
27
- str = `rustc --version --verbose`
28
- info = str.lines.map {|l| l.chomp.split(/:\s+/, 2)}.drop(1).to_h
29
- info["host"]
30
- end
31
-
32
- def self.cargo_target_dir
33
- return @cargo_target_dir if defined? @cargo_target_dir
34
-
35
- str = `cargo metadata --format-version 1 --offline --no-deps --quiet`
36
- begin
37
- require "json"
38
- dir = JSON.parse(str)["target_directory"]
39
- rescue LoadError # json is usually part of the stdlib, but just in case
40
- /"target_directory"\s*:\s*"(?<dir>[^"]*)"/ =~ str
41
- end
42
- @cargo_target_dir = dir || "target"
43
- end
44
-
45
- def self.flags
46
- cc_flags = Shellwords.split(RbConfig.expand(RbConfig::MAKEFILE_CONFIG["CC"].dup))
47
-
48
- ["-C", "linker=#{cc_flags.shift}",
49
- *cc_flags.flat_map {|a| ["-C", "link-arg=#{a}"] },
50
- "-L", "native=#{RbConfig::CONFIG["libdir"]}",
51
- *dld_flags,
52
- *platform_flags]
53
- end
54
-
55
- def self.dld_flags
56
- Shellwords.split(RbConfig::CONFIG["DLDFLAGS"]).flat_map do |arg|
57
- arg = arg.gsub(/\$\((\w+)\)/) do
58
- $1 == "DEFFILE" ? nil : RbConfig::CONFIG[name]
59
- end.strip
60
- next [] if arg.empty?
61
-
62
- transform_flag(arg)
63
- end
64
- end
65
-
66
- def self.platform_flags
67
- return unless RbConfig::CONFIG["target_os"] =~ /mingw/i
68
-
69
- [*Shellwords.split(RbConfig::CONFIG["LIBRUBYARG"]).flat_map {|arg| transform_flag(arg)},
70
- "-C", "link-arg=-Wl,--dynamicbase",
71
- "-C", "link-arg=-Wl,--disable-auto-image-base",
72
- "-C", "link-arg=-static-libgcc"]
73
- end
74
-
75
- def self.transform_flag(arg)
76
- k, v = arg.split(/(?<=..)/, 2)
77
- case k
78
- when "-L"
79
- [k, "native=#{v}"]
80
- when "-l"
81
- [k, v]
82
- when "-F"
83
- ["-l", "framework=#{v}"]
84
- else
85
- ["-C", "link_arg=#{k}#{v}"]
86
- end
87
- end
88
-
89
- def install_dir
90
- File.expand_path(File.join("..", "..", "lib", gemname), __dir__)
91
- end
92
-
93
- def rust_name
94
- prefix = "lib" unless Gem.win_platform?
95
- suffix = if RbConfig::CONFIG["target_os"] =~ /darwin/i
96
- ".dylib"
97
- elsif Gem.win_platform?
98
- ".dll"
99
- else
100
- ".so"
101
- end
102
- "#{prefix}#{gemname}#{suffix}"
103
- end
104
-
105
- def ruby_name
106
- "#{gemname}.#{RbConfig::CONFIG["DLEXT"]}"
107
- end
108
-
109
- end
110
-
111
- task default: [:thread_id_install, :thread_id_clean]
112
- task thread_id: [:thread_id_install, :thread_id_clean]
113
-
114
- desc "set dev mode for subsequent task, run like `rake dev install`"
115
- task :thread_id_dev do
116
- @dev = true
117
- end
118
-
119
- desc "build gem native extension and copy to lib"
120
- task thread_id_install: [:thread_id_cd, :thread_id_build] do
121
- helper = ThreadIdRakeCargoHelper.new
122
- profile_dir = @dev ? "debug" : "release"
123
- arch_dir = RbspyRakeCargoHelper.rust_toolchain
124
- source = File.join(ThreadIdRakeCargoHelper.cargo_target_dir, arch_dir, profile_dir, helper.rust_name)
125
- dest = File.join(helper.install_dir, helper.ruby_name)
126
- mkdir_p(helper.install_dir)
127
- rm(dest) if File.exist?(dest)
128
- cp(source, dest)
129
- end
130
-
131
- desc "build gem native extension"
132
- task thread_id_build: [:thread_id_cargo, :thread_id_cd] do
133
- sh "cargo", "rustc", *(["--locked", "--release"] unless @dev), "--target=#{RbspyRakeCargoHelper.rust_toolchain}", "--", *RbspyRakeCargoHelper.flags
134
- end
135
-
136
- desc "clean up release build artifacts"
137
- task thread_id_clean: [:thread_id_cargo, :thread_id_cd] do
138
- sh "cargo clean --release"
139
- end
140
-
141
- desc "clean up build artifacts"
142
- task thread_id_clobber: [:thread_id_cargo, :thread_id_cd] do
143
- sh "cargo clean"
144
- end
145
-
146
- desc "check for cargo"
147
- task :thread_id_cargo do
148
- raise <<-MSG unless ThreadIdRakeCargoHelper.command?("cargo")
149
- This gem requires a Rust compiler and the `cargo' build tool to build the
150
- gem's native extension. See https://www.rust-lang.org/tools/install for
151
- how to install Rust. `cargo' is usually part of the Rust installation.
152
- MSG
153
-
154
- raise <<-MSG if Gem.win_platform? && ThreadIdRakeCargoHelper.rust_toolchain !~ /gnu/
155
- Found Rust toolchain `#{ThreadIdRakeCargoHelper.rust_toolchain}' but the gem native
156
- extension requires the gnu toolchain on Windows.
157
- MSG
158
- end
159
-
160
- # ensure task is running in the right dir
161
- task :thread_id_cd do
162
- cd(__dir__) unless __dir__ == pwd
163
- end
@@ -1,12 +0,0 @@
1
- extern crate cbindgen;
2
-
3
- use cbindgen::Config;
4
-
5
- fn main() {
6
- let bindings = {
7
- let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
8
- let config = Config::from_file("cbindgen.toml").unwrap();
9
- cbindgen::generate_with_config(&crate_dir, config).unwrap()
10
- };
11
- bindings.write_to_file("include/thread_id.h");
12
- }
@@ -1,22 +0,0 @@
1
- # The language to output bindings in
2
- language = "C"
3
- documentation_style = "C"
4
-
5
- style = "type"
6
-
7
- # An optional name to use as an include guard
8
- include_guard = "RBSPY_H_"
9
- # include a comment with the version of cbindgen used to generate the file
10
- include_version = true
11
-
12
- # An optional string of text to output at the beginning of the generated file
13
- header = "/* Licensed under Apache-2.0 */"
14
- autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
15
-
16
- braces = "SameLine"
17
- tab_width = 2
18
- line_length = 80
19
-
20
- [parse]
21
- # Do not parse dependent crates
22
- parse_deps = false
@@ -1,11 +0,0 @@
1
- require 'mkmf'
2
- require 'rake'
3
-
4
- create_makefile('thread_id')
5
-
6
- app = Rake.application
7
- app.init
8
- app.add_import 'Rakefile'
9
- app.load_rakefile
10
-
11
- app['default'].invoke
@@ -1,17 +0,0 @@
1
- /* Licensed under Apache-2.0 */
2
-
3
- #ifndef RBSPY_H_
4
- #define RBSPY_H_
5
-
6
- /* Generated with cbindgen:0.28.0 */
7
-
8
- /* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
9
-
10
- #include <stdarg.h>
11
- #include <stdbool.h>
12
- #include <stdint.h>
13
- #include <stdlib.h>
14
-
15
- uint64_t thread_id(void);
16
-
17
- #endif /* RBSPY_H_ */
@@ -1,4 +0,0 @@
1
- #[no_mangle]
2
- pub extern "C" fn thread_id() -> u64 {
3
- unsafe { libc::pthread_self() as u64 }
4
- }
Binary file