plain_apm 0.8.3 → 0.8.4

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: d86c0595be8ac7a6b538a81136b6c5c17baa0d32c975cd51866f189d0b19f6ca
4
- data.tar.gz: e28e7b234659abaa0e0659f7b55dc5acdaa561ecafbdddb65b403eb392411363
3
+ metadata.gz: ff5ddab9e3475ec09d7ef20f6bc5c6ae64ffa0e3ffa946d84def56c33eb41cde
4
+ data.tar.gz: '085a3004d655b642bbd63b295ce7c41531d2264709820b8f9ab35e31bdfe987d'
5
5
  SHA512:
6
- metadata.gz: 32422cfac6f7d9bd3fc73c5720be2e6ec0f85c34c5c4a1a6b4b073cd203fc387c472b1c9a17ae217a4fa0046665dcf73835ec0c9ae92a523bab6a162190a48df
7
- data.tar.gz: 30181e92f6df8e2717f6a0265504ccf5db16eb34c0c6d061b7682e437434b4338edf145f9d8dd8a334f6528a13d5fdc175c14c3c1798c42730ca204800b27603
6
+ metadata.gz: 960c5aad1354d5cc97e43d537807afeac46cdb41db125e9a832447912d2d7b0934041c8e39965bd7f8727fe9d7e4b9600250ce9c687559bfb02347afe90205b4
7
+ data.tar.gz: 7985afc06387dbfca63c0a69665516ebb3d54cdf88cd4532fba427d03594ab9e0e65c7a4dab08b9e1c1f63d912fb68afad22c62f7348b87d5f09c38ef146c117
data/README.md CHANGED
@@ -13,11 +13,38 @@ gem 'plain_apm'
13
13
 
14
14
  And then execute:
15
15
 
16
- $ bundle install
16
+ bundle install
17
17
 
18
18
  Or install it yourself as:
19
19
 
20
- $ gem install plain_apm
20
+ gem install plain_apm
21
+
22
+ ### Ractor and TracePoint issues on Ruby 3.0
23
+
24
+ PlainAPM extension to track object allocation on a per-thread basis is
25
+ built on top of Ruby's TracePoint API.
26
+
27
+ However, Rubies 3.0, 3.1, 3.2 and 3.3 as of January 2024 contain bugs
28
+ which, when Tracepoints are used in together with Ractors, can cause
29
+ crashes or inconsistent tracing results.
30
+
31
+ Build process for the native extension contains checks for presence of
32
+ these bugs and disables object allocation tracing accordingly.
33
+
34
+ If you are sure your app is not using Ractors, you can override this by
35
+ installing plain_apm with --enable-object-tracing-override flag:
36
+
37
+ gem install plain_apm -- --enable-object-tracing-override
38
+
39
+ When using bundler, you can configure it to pass this flag to the gem
40
+ install by running:
41
+
42
+ bundle config set --global build.plain_apm --enable-object-tracing-override
43
+
44
+ See also:
45
+
46
+ - https://bugs.ruby-lang.org/issues/18464
47
+ - https://bugs.ruby-lang.org/issues/19112
21
48
 
22
49
  ## Usage
23
50
 
@@ -0,0 +1,8 @@
1
+ exit 0 if !defined?(Ractor)
2
+
3
+ require "objspace"
4
+
5
+ ObjectSpace.trace_object_allocations do
6
+ r = Ractor.new { 10 }
7
+ r.take
8
+ end
@@ -0,0 +1,33 @@
1
+ exit 0 if !defined?(Ractor)
2
+
3
+ # This affects all tracepoints, including internal ones
4
+
5
+ def hello
6
+ "world"
7
+ end
8
+
9
+ traced_calls = 0
10
+
11
+ # Enable tracing
12
+ tracepoint = TracePoint.trace(:call) do |tp|
13
+ traced_calls += 1 if tp.callee_id == :hello
14
+ end
15
+
16
+ 5.times { hello }
17
+
18
+ # Create a ractor and let it be garbage collected
19
+ r = Ractor.new { 10 }
20
+ r.take
21
+ r_id = r.object_id
22
+ r = nil
23
+
24
+ until (ObjectSpace._id2ref(r_id) rescue nil).nil?
25
+ GC.start
26
+ end
27
+
28
+ # Trigger extra calls to be traced, w/ Ractor enabled, they won't be.
29
+ 5.times { hello }
30
+
31
+ tracepoint.disable
32
+
33
+ exit traced_calls == 10 ? 0 : 1
@@ -1,6 +1,84 @@
1
1
  require "mkmf"
2
2
 
3
- have_header("ruby/ruby.h") or missing("ruby/ruby.h")
4
- have_header("ruby/debug.h") or missing("ruby/debug.h")
3
+ def abort_on_missing_ruby_header(name)
4
+ abort(
5
+ <<-MSG
6
+
7
+ PlainAPM extension needs #{name} Ruby library header to compile.
8
+
9
+ If Ruby is installed from a package on your system, please ensure the
10
+ corresponding Ruby development package is installed as well.
11
+
12
+ E.g. on Debian/Ubuntu, this would be achieved by running
13
+
14
+ sudo apt install ruby-dev
15
+
16
+ on CentOS/Fedora, run
17
+
18
+ sudo yum install ruby-devel
19
+
20
+ etc...
21
+ MSG
22
+ )
23
+ end
24
+
25
+ def warn_on_ruby_ractor_bugs
26
+ warn(
27
+ <<-MSG
28
+
29
+ PlainAPM extension to track object allocation on a per-thread basis is
30
+ built on top of Ruby's TracePoint API.
31
+
32
+ However, the currently running Ruby version contains bugs which,
33
+ when Tracepoints are used in together with Ractors, can cause
34
+ crashes or inconsistent tracing results.
35
+
36
+ Per-thread object allocation tracing will be disabled.
37
+
38
+ If you are sure your app is not using Ractors, you can override this by
39
+ installing plain_apm with --enable-object-tracing-override flag:
40
+
41
+ gem install plain_apm -- --enable-object-tracing-override
42
+
43
+ When using bundler, you can configure it to pass this flag to the gem
44
+ install by running:
45
+
46
+ bundle config set --global build.plain_apm --enable-object-tracing-override
47
+
48
+ See also:
49
+
50
+ https://bugs.ruby-lang.org/issues/18464
51
+ https://bugs.ruby-lang.org/issues/19112
52
+
53
+ MSG
54
+ )
55
+ end
56
+
57
+ def try_ruby(file)
58
+ system("ruby", "-W0", File.join(__dir__, file), [:out, :err] => File::NULL)
59
+ end
60
+
61
+ def enable_object_tracing
62
+ $defs.push("-DOBJECT_TRACING_ENABLED") unless $defs.include? "-DOBJECT_TRACING_ENABLED"
63
+ end
64
+
65
+ %w(
66
+ ruby/ruby.h
67
+ ruby/debug.h
68
+ ).each do |header|
69
+ have_header(header) or abort_on_missing_ruby_header(header)
70
+ end
71
+
72
+ if enable_config("object-tracing-override", false)
73
+ enable_object_tracing
74
+ else
75
+ bugs = %w(bug18464.rb bug19112).count { |f| !try_ruby(f) }
76
+
77
+ if bugs.zero?
78
+ enable_object_tracing
79
+ else
80
+ warn_on_ruby_ractor_bugs
81
+ end
82
+ end
5
83
 
6
84
  create_makefile("object_tracing")
@@ -1,25 +1,56 @@
1
1
  #include <ruby/ruby.h>
2
2
  #include <ruby/debug.h>
3
3
 
4
+ static VALUE rb_mPlainApm = Qnil;
5
+ static VALUE rb_mObjTracing = Qnil;
6
+
4
7
  static __thread uint64_t allocated_objects = 0;
5
8
 
6
- static VALUE rb_mPlainApm;
7
- static VALUE rb_mObjTracing;
8
-
9
- static VALUE total_thread_allocated_objects(VALUE self) {
10
- return ULL2NUM(allocated_objects);
11
- }
9
+ #ifdef OBJECT_TRACING_ENABLED
10
+ static int object_tracing_active = 0;
12
11
 
13
12
  static void track_thread_allocated_objects(VALUE tpval, void *data) {
14
13
  allocated_objects++;
15
14
  }
15
+ #endif
16
+
17
+ static VALUE total_thread_allocated_objects(VALUE self) {
18
+ return ULL2NUM(allocated_objects);
19
+ }
16
20
 
17
21
  void Init_object_tracing(void) {
18
22
  rb_mPlainApm = rb_define_module("PlainApm");
23
+ rb_gc_register_address(&rb_mPlainApm);
24
+
19
25
  rb_mObjTracing = rb_define_module_under(rb_mPlainApm, "ObjectTracing");
26
+ rb_gc_register_address(&rb_mObjTracing);
20
27
 
21
28
  rb_define_singleton_method(rb_mObjTracing, "total_thread_allocated_objects", total_thread_allocated_objects, 0);
22
29
 
30
+ #ifdef OBJECT_TRACING_ENABLED
31
+ /* Ensure the tracepoint is attached only once. */
32
+ if (object_tracing_active) { return; }
33
+
34
+ object_tracing_active = 1;
35
+
36
+ /* Object allocation tracing is impacted by these bugs:
37
+ *
38
+ * https://bugs.ruby-lang.org/issues/19112 in Rubies 3.x.x
39
+ * https://bugs.ruby-lang.org/issues/18464 in Rubies 3.0, 3.1, and 3.2
40
+ *
41
+ * According to
42
+ *
43
+ * https://www.ruby-lang.org/en/downloads/branches/
44
+ *
45
+ * 3.0 goes out of maintenance mid 2024. The latter bug was backported to the
46
+ * other branches.
47
+ *
48
+ * For the former, there's https://github.com/ruby/ruby/pull/7184 open,
49
+ * unmerged as of Dec 2023.
50
+ *
51
+ */
52
+
23
53
  VALUE tpval = rb_tracepoint_new(0, RUBY_INTERNAL_EVENT_NEWOBJ, track_thread_allocated_objects, NULL);
24
54
  rb_tracepoint_enable(tpval);
55
+ #endif
25
56
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PlainApm
4
- VERSION = "0.8.3"
4
+ VERSION = "0.8.4"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plain_apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: 0.8.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - PlainAPM Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-29 00:00:00.000000000 Z
11
+ date: 2024-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -92,6 +92,8 @@ files:
92
92
  - Gemfile
93
93
  - LICENSE.txt
94
94
  - README.md
95
+ - ext/object_tracing/bug18464.rb
96
+ - ext/object_tracing/bug19112.rb
95
97
  - ext/object_tracing/extconf.rb
96
98
  - ext/object_tracing/object_tracing.c
97
99
  - lib/plain_apm.rb
@@ -130,7 +132,11 @@ metadata:
130
132
  source_code_uri: https://github.com/plainapm/plainapm-ruby
131
133
  changelog_uri: https://github.com/plainapm/plainapm-ruby/blob/main/CHANGELOG.md
132
134
  github_repo: git@github.com:plainapm/plainapm-ruby.git
133
- post_install_message:
135
+ post_install_message: "\n PlainAPM object tracing is affected by Ractor related
136
+ bugs,\n so it is not enabled by default on Ruby 3.\n\n If you are sure
137
+ your app does not use Ractors, this can be overridden by\n installing the gem
138
+ with --enable-object-tracing-override flag.\n\n Please see https://github.com/plainapm/plainapm-ruby/#installation
139
+ for\n more details.\n "
134
140
  rdoc_options: []
135
141
  require_paths:
136
142
  - lib
@@ -138,7 +144,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
144
  requirements:
139
145
  - - ">="
140
146
  - !ruby/object:Gem::Version
141
- version: '2.6'
147
+ version: '2.7'
142
148
  required_rubygems_version: !ruby/object:Gem::Requirement
143
149
  requirements:
144
150
  - - ">="