pyroscope 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d844d0ba44d32a1201923e772b917ec927b3c95f0e09a051f7d212e33a603d1c
4
- data.tar.gz: ebf2419e55b0fb78cdb8701fce737e274215b8dcec1da30c84c3c91b1cd51643
3
+ metadata.gz: d24a58cc1e931711355e430131e01565c4c15c149ac96d0323826ad03101f22c
4
+ data.tar.gz: 6f86a62f50e924859e404894bb47850a550b99fab146074f8c6cb4ddd6cf3089
5
5
  SHA512:
6
- metadata.gz: 0aa05eaa6246a501c9e41a7843b13dd91fedbb1ec553e79cad75a03760222a3f8d8b292b12a23364b84e066ea8d5114a4d49eff961d78d894de6bc74b86de723
7
- data.tar.gz: ac00d00f2daebcfec6e2cd49665f2406e9ebc238805bef87aa69a3d6a98638aef91f02d765bc7708c605e215dda6eac2176cb18139183587ae269b747d5de2f9
6
+ metadata.gz: 8d65c0d1ef7eeb636caa2b945fb485144f81f934630bf3736ffccb65b966d9b3c66dea974d275f078c6d94613b52f0893f55ec145e066acd430cf55f1c8bfc9f
7
+ data.tar.gz: 22e8e5a0b3a2a43bf11775539dabefa3e5d1d7d4bc6d7a3e40a4c3a80f117693b1a0b139f4e6d86c3db25da63b827b3f616531e385feabdd797cf4a5b3601c36
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,38 +1,11 @@
1
+ use ffikit::Signal;
1
2
  use pyroscope::backend::Tag;
2
3
  use pyroscope::PyroscopeAgent;
3
4
  use pyroscope_rbspy::{rbspy_backend, RbspyConfig};
5
+ use std::collections::hash_map::DefaultHasher;
4
6
  use std::ffi::CStr;
5
- use std::mem::MaybeUninit;
7
+ use std::hash::Hasher;
6
8
  use std::os::raw::c_char;
7
- use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
8
- use std::sync::{Mutex, Once};
9
-
10
- pub enum Signal {
11
- Kill,
12
- AddTag(u64, String, String),
13
- RemoveTag(u64, String, String),
14
- }
15
-
16
- pub struct SignalPass {
17
- inner_sender: Mutex<SyncSender<Signal>>,
18
- inner_receiver: Mutex<Receiver<Signal>>,
19
- }
20
-
21
- fn signalpass() -> &'static SignalPass {
22
- static mut SIGNAL_PASS: MaybeUninit<SignalPass> = MaybeUninit::uninit();
23
- static ONCE: Once = Once::new();
24
-
25
- ONCE.call_once(|| unsafe {
26
- let (sender, receiver) = sync_channel(1);
27
- let singleton = SignalPass {
28
- inner_sender: Mutex::new(sender),
29
- inner_receiver: Mutex::new(receiver),
30
- };
31
- SIGNAL_PASS = MaybeUninit::new(singleton);
32
- });
33
-
34
- unsafe { SIGNAL_PASS.assume_init_ref() }
35
- }
36
9
 
37
10
  #[no_mangle]
38
11
  pub extern "C" fn initialize_agent(
@@ -40,6 +13,9 @@ pub extern "C" fn initialize_agent(
40
13
  sample_rate: u32, detect_subprocesses: bool, on_cpu: bool, report_pid: bool,
41
14
  report_thread_id: bool, tags: *const c_char,
42
15
  ) -> bool {
16
+ // Initialize FFIKit
17
+ let recv = ffikit::initialize_ffi().unwrap();
18
+
43
19
  let application_name = unsafe { CStr::from_ptr(application_name) }
44
20
  .to_str()
45
21
  .unwrap()
@@ -62,44 +38,50 @@ pub extern "C" fn initialize_agent(
62
38
 
63
39
  let pid = std::process::id();
64
40
 
65
- let s = signalpass();
41
+ let rbspy_config = RbspyConfig::new(pid.try_into().unwrap())
42
+ .sample_rate(sample_rate)
43
+ .lock_process(false)
44
+ .with_subprocesses(detect_subprocesses)
45
+ .on_cpu(on_cpu)
46
+ .report_pid(report_pid)
47
+ .report_thread_id(report_thread_id);
66
48
 
67
- std::thread::spawn(move || {
68
- let rbspy_config = RbspyConfig::new(pid.try_into().unwrap())
69
- .sample_rate(sample_rate)
70
- .lock_process(false)
71
- .with_subprocesses(detect_subprocesses)
72
- .on_cpu(on_cpu)
73
- .report_pid(report_pid)
74
- .report_thread_id(report_thread_id);
75
-
76
- let tags_ref = tags_string.as_str();
77
- let tags = string_to_tags(tags_ref);
78
- let rbspy = rbspy_backend(rbspy_config);
79
-
80
- let mut agent_builder = PyroscopeAgent::builder(server_address, application_name)
81
- .backend(rbspy)
82
- .tags(tags);
83
-
84
- if auth_token != "" {
85
- agent_builder = agent_builder.auth_token(auth_token);
86
- }
49
+ let tags_ref = tags_string.as_str();
50
+ let tags = string_to_tags(tags_ref);
51
+ let rbspy = rbspy_backend(rbspy_config);
52
+
53
+ let mut agent_builder = PyroscopeAgent::builder(server_address, application_name)
54
+ .backend(rbspy)
55
+ .tags(tags);
87
56
 
88
- let agent = agent_builder.build().unwrap();
57
+ if auth_token != "" {
58
+ agent_builder = agent_builder.auth_token(auth_token);
59
+ }
60
+
61
+ let agent = agent_builder.build().unwrap();
89
62
 
90
- let agent_running = agent.start().unwrap();
63
+ let agent_running = agent.start().unwrap();
91
64
 
92
- while let Ok(signal) = s.inner_receiver.lock().unwrap().recv() {
65
+ std::thread::spawn(move || {
66
+ while let Ok(signal) = recv.recv() {
93
67
  match signal {
94
68
  Signal::Kill => {
95
69
  agent_running.stop().unwrap();
96
70
  break;
97
71
  }
98
- Signal::AddTag(thread_id, key, value) => {
72
+ Signal::AddGlobalTag(name, value) => {
73
+ agent_running.add_global_tag(Tag::new(name, value)).unwrap();
74
+ }
75
+ Signal::RemoveGlobalTag(name, value) => {
76
+ agent_running
77
+ .remove_global_tag(Tag::new(name, value))
78
+ .unwrap();
79
+ }
80
+ Signal::AddThreadTag(thread_id, key, value) => {
99
81
  let tag = Tag::new(key, value);
100
82
  agent_running.add_thread_tag(thread_id, tag).unwrap();
101
83
  }
102
- Signal::RemoveTag(thread_id, key, value) => {
84
+ Signal::RemoveThreadTag(thread_id, key, value) => {
103
85
  let tag = Tag::new(key, value);
104
86
  agent_running.remove_thread_tag(thread_id, tag).unwrap();
105
87
  }
@@ -112,40 +94,73 @@ pub extern "C" fn initialize_agent(
112
94
 
113
95
  #[no_mangle]
114
96
  pub extern "C" fn drop_agent() -> bool {
115
- let s = signalpass();
116
- s.inner_sender.lock().unwrap().send(Signal::Kill).unwrap();
97
+ // Send Kill signal to the FFI merge channel.
98
+ ffikit::send(ffikit::Signal::Kill).unwrap();
99
+
117
100
  true
118
101
  }
119
102
 
120
103
  #[no_mangle]
121
- pub extern "C" fn add_tag(thread_id: u64, key: *const c_char, value: *const c_char) -> bool {
122
- let s = signalpass();
104
+ pub extern "C" fn add_thread_tag(thread_id: u64, key: *const c_char, value: *const c_char) -> bool {
123
105
  let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
124
106
  let value = unsafe { CStr::from_ptr(value) }
125
107
  .to_str()
126
108
  .unwrap()
127
109
  .to_owned();
128
- s.inner_sender
129
- .lock()
110
+
111
+ let pid = std::process::id();
112
+ let mut hasher = DefaultHasher::new();
113
+ hasher.write_u64(thread_id % pid as u64);
114
+ let id = hasher.finish();
115
+
116
+ ffikit::send(ffikit::Signal::AddThreadTag(id, key, value)).unwrap();
117
+
118
+ true
119
+ }
120
+
121
+ #[no_mangle]
122
+ pub extern "C" fn remove_thread_tag(
123
+ thread_id: u64, key: *const c_char, value: *const c_char,
124
+ ) -> bool {
125
+ let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
126
+ let value = unsafe { CStr::from_ptr(value) }
127
+ .to_str()
130
128
  .unwrap()
131
- .send(Signal::AddTag(thread_id, key, value))
132
- .unwrap();
129
+ .to_owned();
130
+
131
+ let pid = std::process::id();
132
+ let mut hasher = DefaultHasher::new();
133
+ hasher.write_u64(thread_id % pid as u64);
134
+ let id = hasher.finish();
135
+
136
+ ffikit::send(ffikit::Signal::RemoveThreadTag(id, key, value)).unwrap();
137
+
133
138
  true
134
139
  }
135
140
 
136
141
  #[no_mangle]
137
- pub extern "C" fn remove_tag(thread_id: u64, key: *const c_char, value: *const c_char) -> bool {
138
- let s = signalpass();
142
+ pub extern "C" fn add_global_tag(key: *const c_char, value: *const c_char) -> bool {
139
143
  let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
140
144
  let value = unsafe { CStr::from_ptr(value) }
141
145
  .to_str()
142
146
  .unwrap()
143
147
  .to_owned();
144
- s.inner_sender
145
- .lock()
148
+
149
+ ffikit::send(ffikit::Signal::AddGlobalTag(key, value)).unwrap();
150
+
151
+ true
152
+ }
153
+
154
+ #[no_mangle]
155
+ pub extern "C" fn remove_global_tag(key: *const c_char, value: *const c_char) -> bool {
156
+ let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
157
+ let value = unsafe { CStr::from_ptr(value) }
158
+ .to_str()
146
159
  .unwrap()
147
- .send(Signal::RemoveTag(thread_id, key, value))
148
- .unwrap();
160
+ .to_owned();
161
+
162
+ ffikit::send(ffikit::Signal::RemoveGlobalTag(key, value)).unwrap();
163
+
149
164
  true
150
165
  }
151
166
 
@@ -1,3 +1,3 @@
1
1
  module Pyroscope
2
- VERSION = '0.3.0'.freeze
2
+ VERSION = '0.3.1'.freeze
3
3
  end
data/lib/pyroscope.rb CHANGED
@@ -1,34 +1,36 @@
1
1
  require 'ffi'
2
2
 
3
- module Rust
4
- extend FFI::Library
5
- ffi_lib File.expand_path(File.dirname(__FILE__)) + "/rbspy/rbspy.#{RbConfig::CONFIG["DLEXT"]}"
6
- attach_function :initialize_agent, [:string, :string, :string, :int, :bool, :bool, :bool, :bool, :string], :bool
7
- attach_function :add_tag, [:uint64, :string, :string], :bool
8
- attach_function :remove_tag, [:uint64, :string, :string], :bool
9
- attach_function :drop_agent, [], :bool
10
- end
3
+ module Pyroscope
4
+ module Rust
5
+ extend FFI::Library
6
+ ffi_lib File.expand_path(File.dirname(__FILE__)) + "/rbspy/rbspy.#{RbConfig::CONFIG["DLEXT"]}"
7
+ attach_function :initialize_agent, [:string, :string, :string, :int, :bool, :bool, :bool, :bool, :string], :bool
8
+ attach_function :add_thread_tag, [:uint64, :string, :string], :bool
9
+ attach_function :remove_thread_tag, [:uint64, :string, :string], :bool
10
+ attach_function :add_global_tag, [:string, :string], :bool
11
+ attach_function :remove_global_tag, [:string, :string], :bool
12
+ attach_function :drop_agent, [], :bool
13
+ end
11
14
 
12
- module Utils
13
- extend FFI::Library
14
- ffi_lib File.expand_path(File.dirname(__FILE__)) + "/thread_id/thread_id.#{RbConfig::CONFIG["DLEXT"]}"
15
- attach_function :thread_id, [], :uint64
16
- end
15
+ module Utils
16
+ extend FFI::Library
17
+ ffi_lib File.expand_path(File.dirname(__FILE__)) + "/thread_id/thread_id.#{RbConfig::CONFIG["DLEXT"]}"
18
+ attach_function :thread_id, [], :uint64
19
+ end
17
20
 
18
- module Pyroscope
19
21
  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
20
22
  def initialize(*)
23
+ self.application_name = ''
24
+ self.server_address = 'http://localhost:4040'
25
+ self.auth_token = ''
26
+ self.sample_rate = 100
27
+ self.detect_subprocesses = false
28
+ self.on_cpu = true
29
+ self.report_pid = false
30
+ self.report_thread_id = false
31
+ self.log_level = 'info'
32
+ self.tags = {}
21
33
  super
22
- self.application_name ||= ''
23
- self.server_address ||= 'http://localhost:4040'
24
- self.auth_token ||= ''
25
- self.sample_rate ||= 100
26
- self.detect_subprocesses ||= true
27
- self.on_cpu ||= true
28
- self.report_pid ||= false
29
- self.report_thread_id ||= false
30
- self.log_level ||= 'info'
31
- self.tags ||= []
32
34
  end
33
35
  end
34
36
 
@@ -40,15 +42,15 @@ module Pyroscope
40
42
  yield @config
41
43
 
42
44
  Rust.initialize_agent(
43
- @config.app_name || @config.application_name,
44
- @config.server_address,
45
- @config.auth_token,
46
- @config.sample_rate,
47
- @config.detect_subprocesses,
48
- @config.on_cpu,
49
- @config.report_pid,
50
- @config.report_thread_id,
51
- tags_to_string(@config.tags)
45
+ @config.app_name || @config.application_name || "",
46
+ @config.server_address || "",
47
+ @config.auth_token || "",
48
+ @config.sample_rate || 100,
49
+ @config.detect_subprocesses || false,
50
+ @config.on_cpu || false,
51
+ @config.report_pid || false,
52
+ @config.report_thread_id || false,
53
+ tags_to_string(@config.tags || {})
52
54
  )
53
55
  end
54
56
 
@@ -83,14 +85,14 @@ module Pyroscope
83
85
  # add tags
84
86
  def _add_tags(thread_id, tags)
85
87
  tags.each do |tag_name, tag_value|
86
- Rust.add_tag(thread_id, tag_name.to_s, tag_value.to_s)
88
+ Rust.add_thread_tag(thread_id, tag_name.to_s, tag_value.to_s)
87
89
  end
88
90
  end
89
91
 
90
92
  # remove tags
91
93
  def _remove_tags(thread_id, tags)
92
94
  tags.each do |tag_name, tag_value|
93
- Rust.remove_tag(thread_id, tag_name.to_s, tag_value.to_s)
95
+ Rust.remove_thread_tag(thread_id, tag_name.to_s, tag_value.to_s)
94
96
  end
95
97
  end
96
98
 
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.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pyroscope Team
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-30 00:00:00.000000000 Z
11
+ date: 2022-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -93,7 +93,7 @@ homepage: https://pyroscope.io
93
93
  licenses:
94
94
  - Apache-2.0
95
95
  metadata: {}
96
- post_install_message:
96
+ post_install_message:
97
97
  rdoc_options: []
98
98
  require_paths:
99
99
  - lib
@@ -108,8 +108,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  requirements: []
111
- rubygems_version: 3.3.15
112
- signing_key:
111
+ rubygems_version: 3.3.7
112
+ signing_key:
113
113
  specification_version: 4
114
114
  summary: Pyroscope
115
115
  test_files: []