Skip to content

Commit 2132859

Browse files
committed
Instrument ownership gem
Add an instrumentation for the `ownership` gem. When a transaction is created, if an owner has been set in the gem, use the name of the owner as the namespace for the transaction. Do the same when an owner is set during an active transaction. If more than one owner is set during a transaction, the namespace will be that of the last owner that was set.
1 parent 3179ce8 commit 2132859

File tree

9 files changed

+495
-1
lines changed

9 files changed

+495
-1
lines changed

.github/workflows/ci.yml

Lines changed: 163 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# This is a generated file by the `rake build_matrix:github:generate` task.
33
# See `build_matrix.yml` for the build matrix.
44
# Generate this file with `rake build_matrix:github:generate`.
5-
# Generated job count: 151
5+
# Generated job count: 157
66
---
77
name: Ruby gem CI
88
'on':
@@ -318,6 +318,33 @@ jobs:
318318
JRUBY_OPTS: ''
319319
COV: '1'
320320
BUNDLE_GEMFILE: gemfiles/http5.gemfile
321+
ruby_3-4-1__ownership_ubuntu-latest:
322+
name: Ruby 3.4.1 - ownership
323+
needs: ruby_3-4-1_ubuntu-latest
324+
runs-on: ubuntu-latest
325+
steps:
326+
- name: Check out repository
327+
uses: actions/checkout@v4
328+
- name: Install Ruby
329+
uses: ruby/setup-ruby@v1
330+
with:
331+
ruby-version: 3.4.1
332+
bundler-cache: true
333+
- name: Install gem extension
334+
run: "./script/bundler_wrapper exec rake extension:install"
335+
- name: Print extension install report
336+
run: "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report
337+
file found'"
338+
- name: Print Makefile log file
339+
run: "[ -f ext/mkmf.log ] && cat ext/mkmf.log || echo 'No ext/mkmf.log file
340+
found'"
341+
- name: Run tests
342+
run: "./script/bundler_wrapper exec rake test"
343+
env:
344+
RAILS_ENV: test
345+
JRUBY_OPTS: ''
346+
COV: '1'
347+
BUNDLE_GEMFILE: gemfiles/ownership.gemfile
321348
ruby_3-4-1__padrino_ubuntu-latest:
322349
name: Ruby 3.4.1 - padrino
323350
needs: ruby_3-4-1_ubuntu-latest
@@ -970,6 +997,33 @@ jobs:
970997
JRUBY_OPTS: ''
971998
COV: '1'
972999
BUNDLE_GEMFILE: gemfiles/http5.gemfile
1000+
ruby_3-3-4__ownership_ubuntu-latest:
1001+
name: Ruby 3.3.4 - ownership
1002+
needs: ruby_3-3-4_ubuntu-latest
1003+
runs-on: ubuntu-latest
1004+
steps:
1005+
- name: Check out repository
1006+
uses: actions/checkout@v4
1007+
- name: Install Ruby
1008+
uses: ruby/setup-ruby@v1
1009+
with:
1010+
ruby-version: 3.3.4
1011+
bundler-cache: true
1012+
- name: Install gem extension
1013+
run: "./script/bundler_wrapper exec rake extension:install"
1014+
- name: Print extension install report
1015+
run: "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report
1016+
file found'"
1017+
- name: Print Makefile log file
1018+
run: "[ -f ext/mkmf.log ] && cat ext/mkmf.log || echo 'No ext/mkmf.log file
1019+
found'"
1020+
- name: Run tests
1021+
run: "./script/bundler_wrapper exec rake test"
1022+
env:
1023+
RAILS_ENV: test
1024+
JRUBY_OPTS: ''
1025+
COV: '1'
1026+
BUNDLE_GEMFILE: gemfiles/ownership.gemfile
9731027
ruby_3-3-4__padrino_ubuntu-latest:
9741028
name: Ruby 3.3.4 - padrino
9751029
needs: ruby_3-3-4_ubuntu-latest
@@ -1649,6 +1703,33 @@ jobs:
16491703
JRUBY_OPTS: ''
16501704
COV: '1'
16511705
BUNDLE_GEMFILE: gemfiles/http5.gemfile
1706+
ruby_3-2-5__ownership_ubuntu-latest:
1707+
name: Ruby 3.2.5 - ownership
1708+
needs: ruby_3-2-5_ubuntu-latest
1709+
runs-on: ubuntu-latest
1710+
steps:
1711+
- name: Check out repository
1712+
uses: actions/checkout@v4
1713+
- name: Install Ruby
1714+
uses: ruby/setup-ruby@v1
1715+
with:
1716+
ruby-version: 3.2.5
1717+
bundler-cache: true
1718+
- name: Install gem extension
1719+
run: "./script/bundler_wrapper exec rake extension:install"
1720+
- name: Print extension install report
1721+
run: "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report
1722+
file found'"
1723+
- name: Print Makefile log file
1724+
run: "[ -f ext/mkmf.log ] && cat ext/mkmf.log || echo 'No ext/mkmf.log file
1725+
found'"
1726+
- name: Run tests
1727+
run: "./script/bundler_wrapper exec rake test"
1728+
env:
1729+
RAILS_ENV: test
1730+
JRUBY_OPTS: ''
1731+
COV: '1'
1732+
BUNDLE_GEMFILE: gemfiles/ownership.gemfile
16521733
ruby_3-2-5__padrino_ubuntu-latest:
16531734
name: Ruby 3.2.5 - padrino
16541735
needs: ruby_3-2-5_ubuntu-latest
@@ -2328,6 +2409,33 @@ jobs:
23282409
JRUBY_OPTS: ''
23292410
COV: '1'
23302411
BUNDLE_GEMFILE: gemfiles/http5.gemfile
2412+
ruby_3-1-6__ownership_ubuntu-latest:
2413+
name: Ruby 3.1.6 - ownership
2414+
needs: ruby_3-1-6_ubuntu-latest
2415+
runs-on: ubuntu-latest
2416+
steps:
2417+
- name: Check out repository
2418+
uses: actions/checkout@v4
2419+
- name: Install Ruby
2420+
uses: ruby/setup-ruby@v1
2421+
with:
2422+
ruby-version: 3.1.6
2423+
bundler-cache: true
2424+
- name: Install gem extension
2425+
run: "./script/bundler_wrapper exec rake extension:install"
2426+
- name: Print extension install report
2427+
run: "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report
2428+
file found'"
2429+
- name: Print Makefile log file
2430+
run: "[ -f ext/mkmf.log ] && cat ext/mkmf.log || echo 'No ext/mkmf.log file
2431+
found'"
2432+
- name: Run tests
2433+
run: "./script/bundler_wrapper exec rake test"
2434+
env:
2435+
RAILS_ENV: test
2436+
JRUBY_OPTS: ''
2437+
COV: '1'
2438+
BUNDLE_GEMFILE: gemfiles/ownership.gemfile
23312439
ruby_3-1-6__padrino_ubuntu-latest:
23322440
name: Ruby 3.1.6 - padrino
23332441
needs: ruby_3-1-6_ubuntu-latest
@@ -2953,6 +3061,33 @@ jobs:
29533061
JRUBY_OPTS: ''
29543062
COV: '1'
29553063
BUNDLE_GEMFILE: gemfiles/http5.gemfile
3064+
ruby_3-0-7__ownership_ubuntu-latest:
3065+
name: Ruby 3.0.7 - ownership
3066+
needs: ruby_3-0-7_ubuntu-latest
3067+
runs-on: ubuntu-latest
3068+
steps:
3069+
- name: Check out repository
3070+
uses: actions/checkout@v4
3071+
- name: Install Ruby
3072+
uses: ruby/setup-ruby@v1
3073+
with:
3074+
ruby-version: 3.0.7
3075+
bundler-cache: true
3076+
- name: Install gem extension
3077+
run: "./script/bundler_wrapper exec rake extension:install"
3078+
- name: Print extension install report
3079+
run: "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report
3080+
file found'"
3081+
- name: Print Makefile log file
3082+
run: "[ -f ext/mkmf.log ] && cat ext/mkmf.log || echo 'No ext/mkmf.log file
3083+
found'"
3084+
- name: Run tests
3085+
run: "./script/bundler_wrapper exec rake test"
3086+
env:
3087+
RAILS_ENV: test
3088+
JRUBY_OPTS: ''
3089+
COV: '1'
3090+
BUNDLE_GEMFILE: gemfiles/ownership.gemfile
29563091
ruby_3-0-7__padrino_ubuntu-latest:
29573092
name: Ruby 3.0.7 - padrino
29583093
needs: ruby_3-0-7_ubuntu-latest
@@ -3497,6 +3632,33 @@ jobs:
34973632
JRUBY_OPTS: ''
34983633
COV: '1'
34993634
BUNDLE_GEMFILE: gemfiles/http5.gemfile
3635+
ruby_2-7-8__ownership_ubuntu-latest:
3636+
name: Ruby 2.7.8 - ownership
3637+
needs: ruby_2-7-8_ubuntu-latest
3638+
runs-on: ubuntu-latest
3639+
steps:
3640+
- name: Check out repository
3641+
uses: actions/checkout@v4
3642+
- name: Install Ruby
3643+
uses: ruby/setup-ruby@v1
3644+
with:
3645+
ruby-version: 2.7.8
3646+
bundler-cache: true
3647+
- name: Install gem extension
3648+
run: "./script/bundler_wrapper exec rake extension:install"
3649+
- name: Print extension install report
3650+
run: "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report
3651+
file found'"
3652+
- name: Print Makefile log file
3653+
run: "[ -f ext/mkmf.log ] && cat ext/mkmf.log || echo 'No ext/mkmf.log file
3654+
found'"
3655+
- name: Run tests
3656+
run: "./script/bundler_wrapper exec rake test"
3657+
env:
3658+
RAILS_ENV: test
3659+
JRUBY_OPTS: ''
3660+
COV: '1'
3661+
BUNDLE_GEMFILE: gemfiles/ownership.gemfile
35003662
ruby_2-7-8__padrino_ubuntu-latest:
35013663
name: Ruby 2.7.8 - padrino
35023664
needs: ruby_2-7-8_ubuntu-latest

build_matrix.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ matrix:
133133
- "3.2.5"
134134
- "3.1.6"
135135
- gem: "http5"
136+
- gem: "ownership"
136137
- gem: "padrino"
137138
- gem: "psych-3"
138139
only:

gemfiles/ownership.gemfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
source 'https://rubygems.org'
2+
3+
gem 'ownership'
4+
5+
gemspec :path => '../'

lib/appsignal/hooks.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ def truncate(text)
8484
require "appsignal/hooks/http"
8585
require "appsignal/hooks/mri"
8686
require "appsignal/hooks/net_http"
87+
require "appsignal/hooks/ownership"
8788
require "appsignal/hooks/passenger"
8889
require "appsignal/hooks/puma"
8990
require "appsignal/hooks/rake"

lib/appsignal/hooks/ownership.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# frozen_string_literal: true
2+
3+
module Appsignal
4+
class Hooks
5+
# @api private
6+
class OwnershipHook < Appsignal::Hooks::Hook
7+
register :ownership
8+
9+
def dependencies_present?
10+
defined?(::Ownership) &&
11+
Gem::Version.new(::Ownership::VERSION) >= Gem::Version.new("0.2.0") &&
12+
Appsignal.config &&
13+
Appsignal.config[:instrument_ownership]
14+
end
15+
16+
def install
17+
require "appsignal/integrations/ownership"
18+
19+
# If a transaction is created in a code context that has an owner,
20+
# set the namespace of the transaction to the owner.
21+
Appsignal::Transaction.after_create <<
22+
Appsignal::Integrations::OwnershipIntegrationHelper.method(:after_create)
23+
24+
# Ensure the method is only added once.
25+
Appsignal::Transaction.after_create.uniq!
26+
27+
# If an error was reported in a code context that has an owner,
28+
# set the namespace of the transaction to the owner.
29+
# In some circumstances, this will be more accurate than the last owner
30+
# that was set for the transaction, which is what would otherwise be
31+
# reported.
32+
Appsignal::Transaction.before_complete <<
33+
Appsignal::Integrations::OwnershipIntegrationHelper.method(:before_complete)
34+
35+
# Ensure the method is only added once.
36+
Appsignal::Transaction.before_complete.uniq!
37+
38+
# If an owner is set in a code context that has an active transaction,
39+
# set the namespace of the transaction to the owner.
40+
unless ::Ownership.singleton_class.included_modules.include?(
41+
Appsignal::Integrations::OwnershipIntegration
42+
)
43+
::Ownership.singleton_class.prepend Appsignal::Integrations::OwnershipIntegration
44+
end
45+
46+
Appsignal::Environment.report_enabled("ownership")
47+
end
48+
end
49+
end
50+
end
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# frozen_string_literal: true
2+
3+
module Appsignal
4+
module Integrations
5+
# @api private
6+
module OwnershipIntegration
7+
# Implement the `around_change` logic by monkey-patching the reader,
8+
# instead of by using the `around_change=` writer. This allows customers
9+
# to use the `around_change=` writer in their own code without
10+
# accidentally overriding AppSignal's instrumentation.
11+
def around_change
12+
proc do |owner, block|
13+
OwnershipIntegrationHelper.set(Appsignal::Transaction.current, owner)
14+
15+
original = super
16+
17+
if original
18+
original.call(owner, block)
19+
else
20+
block.call
21+
end
22+
end
23+
end
24+
end
25+
26+
module OwnershipIntegrationHelper
27+
class << self
28+
def set(transaction, owner)
29+
transaction.set_namespace(owner) unless owner.nil?
30+
end
31+
32+
def after_create(transaction)
33+
set(transaction, ::Ownership.owner)
34+
end
35+
36+
def before_complete(transaction, error)
37+
set(transaction, error.owner) if error.respond_to?(:owner)
38+
end
39+
end
40+
end
41+
end
42+
end

0 commit comments

Comments
 (0)