plain_apm 0.8.3 → 0.8.4

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: 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
  - - ">="