pyroscope_beta 0.0.2-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.
@@ -0,0 +1,14 @@
1
+ [package]
2
+ name = "rbspy"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+
6
+ [lib]
7
+ name = "rbspy"
8
+ crate-type = ["cdylib"]
9
+
10
+ [dependencies]
11
+ #pyroscope = {version = "0.5.2" }
12
+ #pyroscope_rbspy = { version = "0.2" }
13
+ pyroscope = { path = "../../../../", version = "0.5.2" }
14
+ pyroscope_rbspy = { path = "../../../../pyroscope_backends/pyroscope_rbspy", version = "0.2" }
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shellwords"
4
+
5
+ class RbspyRakeCargoHelper
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
+ ]
54
+ end
55
+
56
+ def self.dld_flags
57
+ Shellwords.split(RbConfig::CONFIG["DLDFLAGS"]).flat_map do |arg|
58
+ arg = arg.gsub(/\$\((\w+)\)/) do
59
+ $1 == "DEFFILE" ? nil : RbConfig::CONFIG[name]
60
+ end.strip
61
+ next [] if arg.empty?
62
+
63
+ transform_flag(arg)
64
+ end
65
+ end
66
+
67
+ def self.platform_flags
68
+ return unless RbConfig::CONFIG["target_os"] =~ /mingw/i
69
+
70
+ [*Shellwords.split(RbConfig::CONFIG["LIBRUBYARG"]).flat_map {|arg| transform_flag(arg)},
71
+ "-C", "link-arg=-Wl,--dynamicbase",
72
+ "-C", "link-arg=-Wl,--disable-auto-image-base",
73
+ "-C", "link-arg=-static-libgcc"]
74
+ end
75
+
76
+ def self.transform_flag(arg)
77
+ k, v = arg.split(/(?<=..)/, 2)
78
+ case k
79
+ when "-L"
80
+ [k, "native=#{v}"]
81
+ when "-l"
82
+ [k, v]
83
+ when "-F"
84
+ ["-l", "framework=#{v}"]
85
+ else
86
+ ["-C", "link_arg=#{k}#{v}"]
87
+ end
88
+ end
89
+
90
+ def install_dir
91
+ File.expand_path(File.join("..", "..", "lib", gemname), __dir__)
92
+ end
93
+
94
+ def rust_name
95
+ prefix = "lib" unless Gem.win_platform?
96
+ suffix = if RbConfig::CONFIG["target_os"] =~ /darwin/i
97
+ ".dylib"
98
+ elsif Gem.win_platform?
99
+ ".dll"
100
+ else
101
+ ".so"
102
+ end
103
+ "#{prefix}#{gemname}#{suffix}"
104
+ end
105
+
106
+ def ruby_name
107
+ "#{gemname}.#{RbConfig::CONFIG["DLEXT"]}"
108
+ end
109
+
110
+ end
111
+
112
+ task default: [:rbspy_install, :rbspy_clean]
113
+ task rbspy: [:rbspy_install, :rbspy_clean]
114
+
115
+ desc "set dev mode for subsequent task, run like `rake dev install`"
116
+ task :rbspy_dev do
117
+ @dev = true
118
+ end
119
+
120
+ desc "build gem native extension and copy to lib"
121
+ task rbspy_install: [:rbspy_cd, :rbspy_build] do
122
+ helper = RbspyRakeCargoHelper.new
123
+ profile_dir = @dev ? "debug" : "release"
124
+ arch_dir = RbspyRakeCargoHelper.rust_toolchain
125
+ source = File.join(RbspyRakeCargoHelper.cargo_target_dir, arch_dir, profile_dir, helper.rust_name)
126
+ dest = File.join(helper.install_dir, helper.ruby_name)
127
+ mkdir_p(helper.install_dir)
128
+ rm(dest) if File.exist?(dest)
129
+ cp(source, dest)
130
+ end
131
+
132
+ desc "build gem native extension"
133
+ task rbspy_build: [:rbspy_cargo, :rbspy_cd] do
134
+ sh "cargo", "rustc", *(["--locked", "--release"] unless @dev), "--target=#{RbspyRakeCargoHelper.rust_toolchain}", "--", *RbspyRakeCargoHelper.flags
135
+ end
136
+
137
+ desc "clean up release build artifacts"
138
+ task rbspy_clean: [:rbspy_cargo, :rbspy_cd] do
139
+ sh "cargo clean --release"
140
+ end
141
+
142
+ desc "clean up build artifacts"
143
+ task rbspy_clobber: [:rbspy_cargo, :rbspy_cd] do
144
+ sh "cargo clean"
145
+ end
146
+
147
+ desc "check for cargo"
148
+ task :rbspy_cargo do
149
+ raise <<-MSG unless RbspyRakeCargoHelper.command?("cargo")
150
+ This gem requires a Rust compiler and the `cargo' build tool to build the
151
+ gem's native extension. See https://www.rust-lang.org/tools/install for
152
+ how to install Rust. `cargo' is usually part of the Rust installation.
153
+ MSG
154
+
155
+ raise <<-MSG if Gem.win_platform? && RbspyRakeCargoHelper.rust_toolchain !~ /gnu/
156
+ Found Rust toolchain `#{RbspyRakeCargoHelper.rust_toolchain}' but the gem native
157
+ extension requires the gnu toolchain on Windows.
158
+ MSG
159
+ end
160
+
161
+ # ensure task is running in the right dir
162
+ task :rbspy_cd do
163
+ cd(__dir__) unless __dir__ == pwd
164
+ end
@@ -0,0 +1,11 @@
1
+ require 'mkmf'
2
+ require 'rake'
3
+
4
+ create_makefile('rbspy')
5
+
6
+ app = Rake.application
7
+ app.init
8
+ app.add_import 'Rakefile'
9
+ app.load_rakefile
10
+
11
+ app['default'].invoke
@@ -0,0 +1,152 @@
1
+ use pyroscope::backend::Tag;
2
+ use pyroscope::PyroscopeAgent;
3
+ use pyroscope_rbspy::{rbspy_backend, RbspyConfig};
4
+ use std::ffi::CStr;
5
+ use std::mem::MaybeUninit;
6
+ 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
+
37
+ #[no_mangle]
38
+ pub extern "C" fn initialize_agent(
39
+ application_name: *const c_char, server_address: *const c_char, sample_rate: u32,
40
+ detect_subprocesses: bool, tags: *const c_char,
41
+ ) -> bool {
42
+ let application_name = unsafe { CStr::from_ptr(application_name) }
43
+ .to_str()
44
+ .unwrap()
45
+ .to_string();
46
+ let server_address = unsafe { CStr::from_ptr(server_address) }
47
+ .to_str()
48
+ .unwrap()
49
+ .to_string();
50
+ let tags_string = unsafe { CStr::from_ptr(tags) }
51
+ .to_str()
52
+ .unwrap()
53
+ .to_string();
54
+
55
+ let pid = std::process::id();
56
+
57
+ let s = signalpass();
58
+
59
+ std::thread::spawn(move || {
60
+ let rbspy_config = RbspyConfig::new(pid.try_into().unwrap())
61
+ .sample_rate(sample_rate)
62
+ .lock_process(false)
63
+ .with_subprocesses(detect_subprocesses);
64
+
65
+ let tags_ref = tags_string.as_str();
66
+ let tags = string_to_tags(tags_ref);
67
+ let rbspy = rbspy_backend(rbspy_config);
68
+ let agent = PyroscopeAgent::builder(server_address, application_name)
69
+ .backend(rbspy)
70
+ .tags(tags)
71
+ .build()
72
+ .unwrap();
73
+
74
+ let agent_running = agent.start().unwrap();
75
+
76
+ while let Ok(signal) = s.inner_receiver.lock().unwrap().recv() {
77
+ match signal {
78
+ Signal::Kill => {
79
+ agent_running.stop().unwrap();
80
+ break;
81
+ }
82
+ Signal::AddTag(thread_id, key, value) => {
83
+ let tag = Tag::new(key, value);
84
+ agent_running.add_thread_tag(thread_id, tag).unwrap();
85
+ }
86
+ Signal::RemoveTag(thread_id, key, value) => {
87
+ let tag = Tag::new(key, value);
88
+ agent_running.remove_thread_tag(thread_id, tag).unwrap();
89
+ }
90
+ }
91
+ }
92
+ });
93
+
94
+ true
95
+ }
96
+
97
+ #[no_mangle]
98
+ pub extern "C" fn drop_agent() -> bool {
99
+ let s = signalpass();
100
+ s.inner_sender.lock().unwrap().send(Signal::Kill).unwrap();
101
+ true
102
+ }
103
+
104
+ #[no_mangle]
105
+ pub extern "C" fn add_tag(thread_id: u64, key: *const c_char, value: *const c_char) -> bool {
106
+ let s = signalpass();
107
+ let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
108
+ let value = unsafe { CStr::from_ptr(value) }
109
+ .to_str()
110
+ .unwrap()
111
+ .to_owned();
112
+ s.inner_sender
113
+ .lock()
114
+ .unwrap()
115
+ .send(Signal::AddTag(thread_id, key, value))
116
+ .unwrap();
117
+ true
118
+ }
119
+
120
+ #[no_mangle]
121
+ pub extern "C" fn remove_tag(thread_id: u64, key: *const c_char, value: *const c_char) -> bool {
122
+ let s = signalpass();
123
+ let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
124
+ let value = unsafe { CStr::from_ptr(value) }
125
+ .to_str()
126
+ .unwrap()
127
+ .to_owned();
128
+ s.inner_sender
129
+ .lock()
130
+ .unwrap()
131
+ .send(Signal::RemoveTag(thread_id, key, value))
132
+ .unwrap();
133
+ true
134
+ }
135
+
136
+ // Convert a string of tags to a Vec<(&str, &str)>
137
+ fn string_to_tags<'a>(tags: &'a str) -> Vec<(&'a str, &'a str)> {
138
+ let mut tags_vec = Vec::new();
139
+ // check if string is empty
140
+ if tags.is_empty() {
141
+ return tags_vec;
142
+ }
143
+
144
+ for tag in tags.split(',') {
145
+ let mut tag_split = tag.split('=');
146
+ let key = tag_split.next().unwrap();
147
+ let value = tag_split.next().unwrap();
148
+ tags_vec.push((key, value));
149
+ }
150
+
151
+ tags_vec
152
+ }
@@ -0,0 +1,16 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 3
4
+
5
+ [[package]]
6
+ name = "libc"
7
+ version = "0.2.126"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
10
+
11
+ [[package]]
12
+ name = "thread_id"
13
+ version = "0.1.0"
14
+ dependencies = [
15
+ "libc",
16
+ ]
@@ -0,0 +1,11 @@
1
+ [package]
2
+ name = "thread_id"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+
6
+ [lib]
7
+ name = "thread_id"
8
+ crate-type = ["cdylib"]
9
+
10
+ [dependencies]
11
+ libc = "*"
@@ -0,0 +1,163 @@
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
@@ -0,0 +1,11 @@
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
@@ -0,0 +1,4 @@
1
+ #[no_mangle]
2
+ pub extern "C" fn thread_id() -> u64 {
3
+ unsafe { libc::pthread_self() as u64 }
4
+ }
@@ -0,0 +1,3 @@
1
+ module Pyroscope
2
+ VERSION = '0.0.2'.freeze
3
+ end
@@ -0,0 +1,87 @@
1
+ require 'ffi'
2
+ require 'fiddle'
3
+
4
+ $libm = Fiddle.dlopen(File.expand_path(File.dirname(__FILE__)) + "/thread_id/thread_id.#{RbConfig::CONFIG["DLEXT"]}")
5
+
6
+
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_agent, [:string, :string, :int, :bool, :string], :bool
11
+ attach_function :add_tag, [:uint64, :string, :string], :bool
12
+ attach_function :remove_tag, [:uint64, :string, :string], :bool
13
+ attach_function :drop_agent, [], :bool
14
+ end
15
+
16
+ module Pyroscope
17
+ Config = Struct.new(:application_name, :server_address, :sample_rate, :detect_subprocesses, :log_level, :tags) do
18
+ def initialize(*)
19
+ super
20
+ self.application_name ||= ''
21
+ self.server_address ||= 'http://localhost:4040'
22
+ self.sample_rate ||= 100
23
+ self.detect_subprocesses ||= true
24
+ self.log_level ||= 'info'
25
+ self.tags ||= []
26
+ end
27
+ end
28
+
29
+ class << self
30
+ def configure
31
+ @config = Config.new
32
+
33
+ # Pass config to the block
34
+ yield @config
35
+
36
+ Rust.initialize_agent(
37
+ @config.application_name,
38
+ @config.server_address,
39
+ @config.sample_rate,
40
+ @config.detect_subprocesses,
41
+ tags_to_string(@config.tags)
42
+ )
43
+
44
+ puts @config
45
+ end
46
+
47
+ def tag_wrapper(tags)
48
+ add_tags(tags)
49
+ begin
50
+ yield
51
+ ensure
52
+ remove_tags(tags)
53
+ end
54
+ end
55
+
56
+ def drop
57
+ Rust.drop_agent
58
+ end
59
+ end
60
+ end
61
+
62
+ # convert tags object to string
63
+ def tags_to_string(tags)
64
+ tags.map { |k, v| "#{k}=#{v}" }.join(',')
65
+ end
66
+
67
+ # get thread id
68
+ def thread_id
69
+ thread_id = Fiddle::Function.new($libm['thread_id'], [], Fiddle::TYPE_INT64_T)
70
+ thread_id.call
71
+ end
72
+
73
+ # add tags
74
+ def add_tags(tags)
75
+ tags.each do |tag_name, tag_value|
76
+ thread_id = thread_id()
77
+ Rust.add_tag(thread_id, tag_name.to_s, tag_value.to_s)
78
+ end
79
+ end
80
+
81
+ # remove tags
82
+ def remove_tags(tags)
83
+ tags.each do |tag_name, tag_value|
84
+ thread_id = thread_id()
85
+ Rust.remove_tag(thread_id, tag_name.to_s, tag_value.to_s)
86
+ end
87
+ end
Binary file
Binary file
data/pyroscope.gemspec ADDED
@@ -0,0 +1,43 @@
1
+ require_relative "lib/pyroscope/version"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'pyroscope_beta'
5
+ s.version = Pyroscope::VERSION
6
+ s.summary = 'Pyroscope Beta'
7
+ s.description = 'Pyroscope FFI Integration for Ruby'
8
+ s.authors = ['Pyroscope Team']
9
+ s.email = ['contact@pyroscope.io']
10
+ s.homepage = 'https://pyroscope.io'
11
+ s.license = 'Apache-2.0'
12
+
13
+ # Specify which files should be added to the gem when it is released.
14
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
15
+ #s.files = Dir.chdir(__dir__) do
16
+ #`git ls-files -z`.split("\x0").reject do |f|
17
+ #(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
18
+ #end
19
+ #end
20
+ s.files = `git ls-files -z`.split("\0").reject { |f| f =~ /^(\.|G|spec|Rakefile)/ }
21
+
22
+ s.platform = Gem::Platform::RUBY
23
+
24
+ s.required_ruby_version = ">= 2.7.0"
25
+
26
+ s.extensions = ['ext/rbspy/extconf.rb', 'ext/thread_id/extconf.rb']
27
+
28
+ s.add_dependency 'ffi', '~> 1.9'
29
+ s.add_dependency 'fiddle', '~> 1.1'
30
+
31
+ s.add_development_dependency 'bundler'
32
+ s.add_development_dependency 'github-release'
33
+ s.add_development_dependency 'guard-rspec'
34
+ s.add_development_dependency 'rake', '~> 13.0'
35
+ s.add_development_dependency 'rake-compiler', '~> 1.2'
36
+ s.add_development_dependency 'rake-compiler-dock', '~> 1.2'
37
+ s.add_development_dependency 'rb-inotify', '~> 0.9'
38
+ s.add_development_dependency 'rb_sys', '~> 0.1'
39
+ s.add_development_dependency 'redcarpet'
40
+ s.add_development_dependency 'rspec'
41
+ s.add_development_dependency 'simplecov'
42
+ s.add_development_dependency 'yard'
43
+ end