pyroscope 0.6.7 → 1.0.2
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/Gemfile.lock +5 -4
- data/README.md +7 -54
- data/lib/pyroscope/version.rb +1 -1
- data/lib/pyroscope.rb +9 -30
- data/pyroscope.gemspec +8 -32
- metadata +8 -27
- data/ext/rbspy/Cargo.toml +0 -21
- data/ext/rbspy/Rakefile +0 -164
- data/ext/rbspy/build.rs +0 -12
- data/ext/rbspy/cbindgen.toml +0 -22
- data/ext/rbspy/include/rbspy.h +0 -43
- data/ext/rbspy/src/lib.rs +0 -358
- data/ext/thread_id/Cargo.toml +0 -15
- data/ext/thread_id/Rakefile +0 -163
- data/ext/thread_id/build.rs +0 -12
- data/ext/thread_id/cbindgen.toml +0 -22
- data/ext/thread_id/extconf.rb +0 -11
- data/ext/thread_id/include/thread_id.h +0 -17
- data/ext/thread_id/src/lib.rs +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 56905d725cb3ba8a3cf0b4a1342b16d66f02a878d5d7d231a66e58230d356a29
|
|
4
|
+
data.tar.gz: 53679ec8008bc732fc3dbbaf7a7f571ee15f8d6d90a81c5999b4139cb314dff3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 66e3661210271621c7e9d2bc58b920c00eed6f74ca25d74ca09c0866948954822f5a4e85e05729372d1a940b47a31d570cf53466c25c84b1c50a67b40f520839
|
|
7
|
+
data.tar.gz: fd206c4e0e95870a58f84bd16a23b64f8d8566f323cd61870593e44a6e87a822e8a17ba60ed1220dc0e4bf60d61bacb96beed9c528d7f2e980c14165a258eb2c
|
data/Gemfile.lock
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
pyroscope (0.
|
|
4
|
+
pyroscope (1.0.2)
|
|
5
5
|
ffi
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
ffi (1.
|
|
11
|
-
|
|
10
|
+
ffi (1.17.4)
|
|
11
|
+
ffi (1.17.4-x86_64-linux-gnu)
|
|
12
|
+
rake (13.3.1)
|
|
12
13
|
|
|
13
14
|
PLATFORMS
|
|
14
15
|
ruby
|
|
@@ -20,4 +21,4 @@ DEPENDENCIES
|
|
|
20
21
|
rake (~> 13.0)
|
|
21
22
|
|
|
22
23
|
BUNDLED WITH
|
|
23
|
-
|
|
24
|
+
4.0.9
|
data/README.md
CHANGED
|
@@ -1,71 +1,24 @@
|
|
|
1
1
|
# Pyroscope Ruby Gem
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Ruby integration for [Pyroscope](https://grafana.com/oss/pyroscope/) continuous profiling platform.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-

|
|
7
|
-

|
|
8
|
-
[](https://badge.fury.io/rb/pyroscope)
|
|
5
|
+
## Installation
|
|
9
6
|
|
|
10
|
-
---
|
|
11
|
-
|
|
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.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
### Supported platforms
|
|
17
|
-
|
|
18
|
-
| Linux | macOS | Windows | Docker |
|
|
19
|
-
|:-----:|:-----:|:-------:|:------:|
|
|
20
|
-
| ✅ | ✅ | | ✅ |
|
|
21
|
-
|
|
22
|
-
### Profiling Ruby applications
|
|
23
|
-
|
|
24
|
-
Add the `pyroscope` gem to your Gemfile:
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
bundle add pyroscope
|
|
28
7
|
```
|
|
29
|
-
|
|
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
|
-
|
|
34
|
-
```ruby
|
|
35
|
-
require 'pyroscope'
|
|
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
|
|
8
|
+
gem install pyroscope
|
|
42
9
|
```
|
|
43
10
|
|
|
44
|
-
|
|
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:
|
|
11
|
+
## Usage
|
|
47
12
|
|
|
48
13
|
```ruby
|
|
49
14
|
require 'pyroscope'
|
|
50
15
|
|
|
51
16
|
Pyroscope.configure do |config|
|
|
52
17
|
config.application_name = "my.ruby.app"
|
|
53
|
-
config.server_address
|
|
54
|
-
|
|
55
|
-
config.tags = {
|
|
56
|
-
"hostname" => ENV["HOSTNAME"],
|
|
57
|
-
}
|
|
58
|
-
end
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
or you can dynamically tag certain parts of your code:
|
|
62
|
-
|
|
63
|
-
```ruby
|
|
64
|
-
Pyroscope.tag_wrapper({ "controller": "slow_controller_i_want_to_profile" }) do
|
|
65
|
-
slow_code
|
|
18
|
+
config.server_address = "http://localhost:4040"
|
|
66
19
|
end
|
|
67
20
|
```
|
|
68
21
|
|
|
69
|
-
|
|
22
|
+
## License
|
|
70
23
|
|
|
71
|
-
|
|
24
|
+
Apache-2.0
|
data/lib/pyroscope/version.rb
CHANGED
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, :
|
|
13
|
-
attach_function :add_thread_tag, [:
|
|
14
|
-
attach_function :remove_thread_tag, [:
|
|
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
|
-
|
|
141
|
-
_add_tags(tid, tags)
|
|
124
|
+
_add_tags(tags)
|
|
142
125
|
begin
|
|
143
126
|
yield
|
|
144
127
|
ensure
|
|
145
|
-
_remove_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
|
|
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(
|
|
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(
|
|
146
|
+
def _remove_tags(tags)
|
|
168
147
|
tags.each do |tag_name, tag_value|
|
|
169
|
-
Rust.remove_thread_tag(
|
|
148
|
+
Rust.remove_thread_tag(tag_name.to_s, tag_value.to_s)
|
|
170
149
|
end
|
|
171
150
|
end
|
|
172
151
|
|
data/pyroscope.gemspec
CHANGED
|
@@ -14,55 +14,31 @@ Gem::Specification.new do |s|
|
|
|
14
14
|
s.description = 'Pyroscope FFI Integration for Ruby'
|
|
15
15
|
s.authors = ['Pyroscope Team']
|
|
16
16
|
s.email = ['contact@pyroscope.io']
|
|
17
|
-
s.homepage = 'https://pyroscope
|
|
17
|
+
s.homepage = 'https://grafana.com/oss/pyroscope/'
|
|
18
18
|
s.license = 'Apache-2.0'
|
|
19
19
|
s.metadata = {
|
|
20
|
-
"homepage_uri" => "https://pyroscope
|
|
21
|
-
"bug_tracker_uri" => "https://github.com/
|
|
22
|
-
"documentation_uri" => "https://
|
|
23
|
-
"
|
|
24
|
-
"source_code_uri" => "https://github.com/pyroscope-io/pyroscope-rs/tree/main/pyroscope_ffi/ruby",
|
|
20
|
+
"homepage_uri" => "https://grafana.com/oss/pyroscope/",
|
|
21
|
+
"bug_tracker_uri" => "https://github.com/grafana/pyroscope-ruby/issues",
|
|
22
|
+
"documentation_uri" => "https://grafana.com/docs/pyroscope/latest/configure-client/language-sdks/ruby/",
|
|
23
|
+
"source_code_uri" => "https://github.com/grafana/pyroscope-ruby",
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#s.files = Dir.chdir(__dir__) do
|
|
30
|
-
#`git ls-files -z`.split("\x0").reject do |f|
|
|
31
|
-
#(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
32
|
-
#end
|
|
33
|
-
#end
|
|
34
|
-
# s.files = `git ls-files -z`.split("\0").reject { |f| f =~ /^(\.|G|spec|Rakefile)/ }
|
|
26
|
+
# TODO: s.files is incomplete — ext/rbspy/ sources are missing, so building
|
|
27
|
+
# the gem from source does not work. See https://github.com/grafana/pyroscope-ruby/issues/2
|
|
35
28
|
s.files = [
|
|
36
29
|
"Gemfile",
|
|
37
30
|
"Gemfile.lock",
|
|
38
31
|
"LICENSE",
|
|
39
|
-
# "Makefile",
|
|
40
32
|
"README.md",
|
|
41
|
-
# "Rakefile",
|
|
42
|
-
"ext/rbspy/Cargo.toml",
|
|
43
|
-
"ext/rbspy/Rakefile",
|
|
44
|
-
"ext/rbspy/build.rs",
|
|
45
|
-
"ext/rbspy/cbindgen.toml",
|
|
46
|
-
"ext/rbspy/extconf.rb",
|
|
47
|
-
"ext/rbspy/include/rbspy.h",
|
|
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
33
|
"lib/pyroscope.rb",
|
|
57
34
|
"lib/pyroscope/version.rb",
|
|
58
35
|
"pyroscope.gemspec",
|
|
59
|
-
# "scripts/tests/test.rb",
|
|
60
36
|
]
|
|
61
37
|
s.platform = Gem::Platform::RUBY
|
|
62
38
|
|
|
63
39
|
s.required_ruby_version = ">= 1.9.3"
|
|
64
40
|
|
|
65
|
-
s.extensions = ['ext/rbspy/extconf.rb'
|
|
41
|
+
s.extensions = ['ext/rbspy/extconf.rb']
|
|
66
42
|
|
|
67
43
|
s.add_dependency 'ffi'
|
|
68
44
|
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pyroscope
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pyroscope Team
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: ffi
|
|
@@ -24,7 +23,6 @@ dependencies:
|
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
25
|
version: '0'
|
|
27
|
-
force_ruby_platform: false
|
|
28
26
|
- !ruby/object:Gem::Dependency
|
|
29
27
|
name: bundler
|
|
30
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -59,40 +57,24 @@ email:
|
|
|
59
57
|
executables: []
|
|
60
58
|
extensions:
|
|
61
59
|
- ext/rbspy/extconf.rb
|
|
62
|
-
- ext/thread_id/extconf.rb
|
|
63
60
|
extra_rdoc_files: []
|
|
64
61
|
files:
|
|
65
62
|
- Gemfile
|
|
66
63
|
- Gemfile.lock
|
|
67
64
|
- LICENSE
|
|
68
65
|
- README.md
|
|
69
|
-
- ext/rbspy/Cargo.toml
|
|
70
|
-
- ext/rbspy/Rakefile
|
|
71
|
-
- ext/rbspy/build.rs
|
|
72
|
-
- ext/rbspy/cbindgen.toml
|
|
73
66
|
- ext/rbspy/extconf.rb
|
|
74
|
-
- ext/rbspy/include/rbspy.h
|
|
75
|
-
- ext/rbspy/src/lib.rs
|
|
76
|
-
- ext/thread_id/Cargo.toml
|
|
77
|
-
- ext/thread_id/Rakefile
|
|
78
|
-
- ext/thread_id/build.rs
|
|
79
|
-
- ext/thread_id/cbindgen.toml
|
|
80
|
-
- ext/thread_id/extconf.rb
|
|
81
|
-
- ext/thread_id/include/thread_id.h
|
|
82
|
-
- ext/thread_id/src/lib.rs
|
|
83
67
|
- lib/pyroscope.rb
|
|
84
68
|
- lib/pyroscope/version.rb
|
|
85
69
|
- pyroscope.gemspec
|
|
86
|
-
homepage: https://pyroscope
|
|
70
|
+
homepage: https://grafana.com/oss/pyroscope/
|
|
87
71
|
licenses:
|
|
88
72
|
- Apache-2.0
|
|
89
73
|
metadata:
|
|
90
|
-
homepage_uri: https://pyroscope
|
|
91
|
-
bug_tracker_uri: https://github.com/
|
|
92
|
-
documentation_uri: https://
|
|
93
|
-
|
|
94
|
-
source_code_uri: https://github.com/pyroscope-io/pyroscope-rs/tree/main/pyroscope_ffi/ruby
|
|
95
|
-
post_install_message:
|
|
74
|
+
homepage_uri: https://grafana.com/oss/pyroscope/
|
|
75
|
+
bug_tracker_uri: https://github.com/grafana/pyroscope-ruby/issues
|
|
76
|
+
documentation_uri: https://grafana.com/docs/pyroscope/latest/configure-client/language-sdks/ruby/
|
|
77
|
+
source_code_uri: https://github.com/grafana/pyroscope-ruby
|
|
96
78
|
rdoc_options: []
|
|
97
79
|
require_paths:
|
|
98
80
|
- lib
|
|
@@ -107,8 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
107
89
|
- !ruby/object:Gem::Version
|
|
108
90
|
version: '0'
|
|
109
91
|
requirements: []
|
|
110
|
-
rubygems_version:
|
|
111
|
-
signing_key:
|
|
92
|
+
rubygems_version: 4.0.6
|
|
112
93
|
specification_version: 4
|
|
113
94
|
summary: Pyroscope
|
|
114
95
|
test_files: []
|
data/ext/rbspy/Cargo.toml
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
[package]
|
|
2
|
-
name = "ffiruby"
|
|
3
|
-
version = "0.1.0"
|
|
4
|
-
edition = "2021"
|
|
5
|
-
rust-version = "1.64"
|
|
6
|
-
|
|
7
|
-
[lib]
|
|
8
|
-
name = "rbspy"
|
|
9
|
-
crate-type = ["cdylib"]
|
|
10
|
-
|
|
11
|
-
[dependencies]
|
|
12
|
-
pyroscope = { path = "../../../../" }
|
|
13
|
-
pyroscope_rbspy = { path = "../../../../pyroscope_backends/pyroscope_rbspy" }
|
|
14
|
-
ffikit = { path = "../../../ffikit" }
|
|
15
|
-
# todo remove this dependency
|
|
16
|
-
pretty_env_logger = "0.5"
|
|
17
|
-
log = "0.4"
|
|
18
|
-
|
|
19
|
-
[build-dependencies]
|
|
20
|
-
cbindgen = "0.28"
|
|
21
|
-
|
data/ext/rbspy/Rakefile
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
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
|
data/ext/rbspy/build.rs
DELETED
|
@@ -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/rbspy.h");
|
|
12
|
-
}
|
data/ext/rbspy/cbindgen.toml
DELETED
|
@@ -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
|
data/ext/rbspy/include/rbspy.h
DELETED
|
@@ -1,43 +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
|
-
bool initialize_logging(uint32_t logging_level);
|
|
16
|
-
|
|
17
|
-
bool initialize_agent(const char *application_name,
|
|
18
|
-
const char *server_address,
|
|
19
|
-
const char *auth_token,
|
|
20
|
-
const char *basic_auth_user,
|
|
21
|
-
const char *basic_auth_password,
|
|
22
|
-
uint32_t sample_rate,
|
|
23
|
-
bool detect_subprocesses,
|
|
24
|
-
bool oncpu,
|
|
25
|
-
bool report_pid,
|
|
26
|
-
bool report_thread_id,
|
|
27
|
-
const char *tags,
|
|
28
|
-
const char *compression,
|
|
29
|
-
const char *_report_encoding,
|
|
30
|
-
const char *tenant_id,
|
|
31
|
-
const char *http_headers_json);
|
|
32
|
-
|
|
33
|
-
bool drop_agent(void);
|
|
34
|
-
|
|
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);
|
|
40
|
-
|
|
41
|
-
bool remove_global_tag(const char *key, const char *value);
|
|
42
|
-
|
|
43
|
-
#endif /* RBSPY_H_ */
|
data/ext/rbspy/src/lib.rs
DELETED
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
use std::collections::hash_map::DefaultHasher;
|
|
2
|
-
use std::env;
|
|
3
|
-
use std::ffi::CStr;
|
|
4
|
-
use std::hash::Hasher;
|
|
5
|
-
use std::os::raw::c_char;
|
|
6
|
-
use std::str::FromStr;
|
|
7
|
-
|
|
8
|
-
use ffikit::Signal;
|
|
9
|
-
use pyroscope_rbspy::{rbspy_backend, RbspyConfig};
|
|
10
|
-
|
|
11
|
-
use pyroscope;
|
|
12
|
-
use pyroscope::{pyroscope::Compression, PyroscopeAgent};
|
|
13
|
-
use pyroscope::backend::{Report, StackFrame, Tag};
|
|
14
|
-
use pyroscope::pyroscope::ReportEncoding;
|
|
15
|
-
|
|
16
|
-
const LOG_TAG: &str = "Pyroscope::rbspy::ffi";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
pub fn transform_report(report: Report) -> Report {
|
|
20
|
-
let cwd = env::current_dir().unwrap();
|
|
21
|
-
let cwd = cwd.to_str().unwrap_or("");
|
|
22
|
-
|
|
23
|
-
let data = report
|
|
24
|
-
.data
|
|
25
|
-
.iter()
|
|
26
|
-
.map(|(stacktrace, count)| {
|
|
27
|
-
let new_frames = stacktrace
|
|
28
|
-
.frames
|
|
29
|
-
.iter()
|
|
30
|
-
.map(|frame| {
|
|
31
|
-
let frame = frame.to_owned();
|
|
32
|
-
let mut s = frame.filename.unwrap();
|
|
33
|
-
match s.find(cwd) {
|
|
34
|
-
Some(i) => {
|
|
35
|
-
s = s[(i + cwd.len() + 1)..].to_string();
|
|
36
|
-
}
|
|
37
|
-
None => match s.find("/gems/") {
|
|
38
|
-
Some(i) => {
|
|
39
|
-
s = s[(i + 1)..].to_string();
|
|
40
|
-
}
|
|
41
|
-
None => match s.find("/ruby/") {
|
|
42
|
-
Some(i) => {
|
|
43
|
-
s = s[(i + 6)..].to_string();
|
|
44
|
-
match s.find("/") {
|
|
45
|
-
Some(i) => {
|
|
46
|
-
s = s[(i + 1)..].to_string();
|
|
47
|
-
}
|
|
48
|
-
None => {}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
None => {}
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// something
|
|
57
|
-
StackFrame::new(
|
|
58
|
-
frame.module,
|
|
59
|
-
frame.name,
|
|
60
|
-
Some(s.to_string()),
|
|
61
|
-
frame.relative_path,
|
|
62
|
-
frame.absolute_path,
|
|
63
|
-
frame.line,
|
|
64
|
-
)
|
|
65
|
-
})
|
|
66
|
-
.collect();
|
|
67
|
-
|
|
68
|
-
let mut mystack = stacktrace.to_owned();
|
|
69
|
-
|
|
70
|
-
mystack.frames = new_frames;
|
|
71
|
-
|
|
72
|
-
(mystack, count.to_owned())
|
|
73
|
-
})
|
|
74
|
-
.collect();
|
|
75
|
-
|
|
76
|
-
let new_report = Report::new(data).metadata(report.metadata.clone());
|
|
77
|
-
|
|
78
|
-
new_report
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
#[no_mangle]
|
|
82
|
-
pub extern "C" fn initialize_logging(logging_level: u32) -> bool {
|
|
83
|
-
// Force rustc to display the log messages in the console.
|
|
84
|
-
match logging_level {
|
|
85
|
-
50 => {
|
|
86
|
-
std::env::set_var("RUST_LOG", "error");
|
|
87
|
-
}
|
|
88
|
-
40 => {
|
|
89
|
-
std::env::set_var("RUST_LOG", "warn");
|
|
90
|
-
}
|
|
91
|
-
30 => {
|
|
92
|
-
std::env::set_var("RUST_LOG", "info");
|
|
93
|
-
}
|
|
94
|
-
20 => {
|
|
95
|
-
std::env::set_var("RUST_LOG", "debug");
|
|
96
|
-
}
|
|
97
|
-
10 => {
|
|
98
|
-
std::env::set_var("RUST_LOG", "trace");
|
|
99
|
-
}
|
|
100
|
-
_ => {
|
|
101
|
-
std::env::set_var("RUST_LOG", "debug");
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Initialize the logger.
|
|
106
|
-
pretty_env_logger::init_timed();
|
|
107
|
-
|
|
108
|
-
true
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
#[no_mangle]
|
|
112
|
-
pub extern "C" fn initialize_agent(
|
|
113
|
-
application_name: *const c_char,
|
|
114
|
-
server_address: *const c_char,
|
|
115
|
-
auth_token: *const c_char,
|
|
116
|
-
basic_auth_user: *const c_char,
|
|
117
|
-
basic_auth_password: *const c_char,
|
|
118
|
-
sample_rate: u32,
|
|
119
|
-
detect_subprocesses: bool,
|
|
120
|
-
oncpu: bool,
|
|
121
|
-
report_pid: bool,
|
|
122
|
-
report_thread_id: bool,
|
|
123
|
-
tags: *const c_char,
|
|
124
|
-
compression: *const c_char,
|
|
125
|
-
_report_encoding: *const c_char,
|
|
126
|
-
tenant_id: *const c_char,
|
|
127
|
-
http_headers_json: *const c_char,
|
|
128
|
-
) -> bool {
|
|
129
|
-
// Initialize FFIKit
|
|
130
|
-
let recv = ffikit::initialize_ffi().unwrap();
|
|
131
|
-
|
|
132
|
-
let application_name = unsafe { CStr::from_ptr(application_name) }
|
|
133
|
-
.to_str()
|
|
134
|
-
.unwrap()
|
|
135
|
-
.to_string();
|
|
136
|
-
|
|
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) }
|
|
148
|
-
.to_str()
|
|
149
|
-
.unwrap()
|
|
150
|
-
.to_string();
|
|
151
|
-
|
|
152
|
-
let basic_auth_user = unsafe { CStr::from_ptr(basic_auth_user) }
|
|
153
|
-
.to_str()
|
|
154
|
-
.unwrap()
|
|
155
|
-
.to_string();
|
|
156
|
-
|
|
157
|
-
let basic_auth_password = unsafe { CStr::from_ptr(basic_auth_password) }
|
|
158
|
-
.to_str()
|
|
159
|
-
.unwrap()
|
|
160
|
-
.to_string();
|
|
161
|
-
|
|
162
|
-
let tags_string = unsafe { CStr::from_ptr(tags) }
|
|
163
|
-
.to_str()
|
|
164
|
-
.unwrap()
|
|
165
|
-
.to_string();
|
|
166
|
-
|
|
167
|
-
let compression_string = unsafe { CStr::from_ptr(compression) }
|
|
168
|
-
.to_str()
|
|
169
|
-
.unwrap()
|
|
170
|
-
.to_string();
|
|
171
|
-
|
|
172
|
-
let tenant_id = unsafe { CStr::from_ptr(tenant_id) }
|
|
173
|
-
.to_str()
|
|
174
|
-
.unwrap()
|
|
175
|
-
.to_string();
|
|
176
|
-
|
|
177
|
-
let http_headers_json = unsafe { CStr::from_ptr(http_headers_json) }
|
|
178
|
-
.to_str()
|
|
179
|
-
.unwrap()
|
|
180
|
-
.to_string();
|
|
181
|
-
|
|
182
|
-
let compression = Compression::from_str(&compression_string);
|
|
183
|
-
|
|
184
|
-
let pid = std::process::id();
|
|
185
|
-
|
|
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);
|
|
193
|
-
|
|
194
|
-
let tags_ref = tags_string.as_str();
|
|
195
|
-
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 != "" {
|
|
207
|
-
agent_builder = agent_builder.basic_auth(basic_auth_user, basic_auth_password);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if tenant_id != "" {
|
|
211
|
-
agent_builder = agent_builder.tenant_id(tenant_id);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
let http_headers = pyroscope::pyroscope::parse_http_headers_json(http_headers_json);
|
|
215
|
-
match http_headers {
|
|
216
|
-
Ok(http_headers) => {
|
|
217
|
-
agent_builder = agent_builder.http_headers(http_headers);
|
|
218
|
-
}
|
|
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
|
-
_ => {}
|
|
228
|
-
}
|
|
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
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
true
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
#[no_mangle]
|
|
271
|
-
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
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
#[no_mangle]
|
|
279
|
-
pub extern "C" fn add_thread_tag(thread_id: u64, key: *const c_char, value: *const c_char) -> bool {
|
|
280
|
-
let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
|
|
281
|
-
let value = unsafe { CStr::from_ptr(value) }
|
|
282
|
-
.to_str()
|
|
283
|
-
.unwrap()
|
|
284
|
-
.to_owned();
|
|
285
|
-
|
|
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
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
#[no_mangle]
|
|
297
|
-
pub extern "C" fn remove_thread_tag(
|
|
298
|
-
thread_id: u64, key: *const c_char, value: *const c_char,
|
|
299
|
-
) -> bool {
|
|
300
|
-
let key = unsafe { CStr::from_ptr(key) }.to_str().unwrap().to_owned();
|
|
301
|
-
let value = unsafe { CStr::from_ptr(value) }
|
|
302
|
-
.to_str()
|
|
303
|
-
.unwrap()
|
|
304
|
-
.to_owned();
|
|
305
|
-
|
|
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
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Convert a string of tags to a Vec<(&str, &str)>
|
|
343
|
-
fn string_to_tags<'a>(tags: &'a str) -> Vec<(&'a str, &'a str)> {
|
|
344
|
-
let mut tags_vec = Vec::new();
|
|
345
|
-
// check if string is empty
|
|
346
|
-
if tags.is_empty() {
|
|
347
|
-
return tags_vec;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
for tag in tags.split(',') {
|
|
351
|
-
let mut tag_split = tag.split('=');
|
|
352
|
-
let key = tag_split.next().unwrap();
|
|
353
|
-
let value = tag_split.next().unwrap();
|
|
354
|
-
tags_vec.push((key, value));
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
tags_vec
|
|
358
|
-
}
|
data/ext/thread_id/Cargo.toml
DELETED
data/ext/thread_id/Rakefile
DELETED
|
@@ -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
|
data/ext/thread_id/build.rs
DELETED
|
@@ -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
|
-
}
|
data/ext/thread_id/cbindgen.toml
DELETED
|
@@ -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
|
data/ext/thread_id/extconf.rb
DELETED
|
@@ -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_ */
|
data/ext/thread_id/src/lib.rs
DELETED