solarwinds_apm 5.1.9 → 6.0.0.preV1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +0 -1
- data/ext/oboe_metal/extconf.rb +19 -23
- data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.sha256 +1 -1
- data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.sha256 +1 -1
- data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.sha256 +1 -1
- data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.sha256 +1 -1
- data/ext/oboe_metal/src/VERSION +1 -1
- data/ext/oboe_metal/src/oboe_debug.h +1 -0
- data/lib/oboe_metal.rb +116 -80
- data/lib/rails/generators/solarwinds_apm/install_generator.rb +1 -2
- data/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb +44 -260
- data/lib/solarwinds_apm/api/current_trace_info.rb +148 -0
- data/lib/solarwinds_apm/api/tracing.rb +30 -0
- data/lib/solarwinds_apm/api/transaction_name.rb +57 -0
- data/lib/solarwinds_apm/api.rb +8 -15
- data/lib/solarwinds_apm/base.rb +4 -131
- data/lib/solarwinds_apm/config.rb +128 -175
- data/lib/solarwinds_apm/constants.rb +32 -0
- data/lib/solarwinds_apm/logger.rb +1 -1
- data/lib/solarwinds_apm/noop/context.rb +2 -5
- data/lib/solarwinds_apm/noop/metadata.rb +1 -2
- data/lib/solarwinds_apm/noop/profiling.rb +3 -7
- data/lib/solarwinds_apm/oboe_init_options.rb +71 -33
- data/lib/solarwinds_apm/opentelemetry/solarwinds_exporter.rb +204 -0
- data/lib/solarwinds_apm/opentelemetry/solarwinds_processor.rb +163 -0
- data/lib/solarwinds_apm/opentelemetry/solarwinds_propagator.rb +92 -0
- data/lib/solarwinds_apm/opentelemetry/solarwinds_response_propagator.rb +72 -0
- data/lib/solarwinds_apm/opentelemetry/solarwinds_sampler.rb +330 -0
- data/lib/solarwinds_apm/opentelemetry.rb +8 -0
- data/lib/solarwinds_apm/otel_config.rb +161 -0
- data/lib/solarwinds_apm/{inst → support}/logger_formatter.rb +5 -6
- data/lib/solarwinds_apm/{inst → support}/logging_log_event.rb +3 -6
- data/lib/solarwinds_apm/{inst → support}/lumberjack_formatter.rb +1 -4
- data/lib/solarwinds_apm/support/oboe_tracing_mode.rb +27 -0
- data/lib/solarwinds_apm/support/swomarginalia/LICENSE +20 -0
- data/lib/solarwinds_apm/support/swomarginalia/README.md +41 -0
- data/lib/solarwinds_apm/support/swomarginalia/comment.rb +205 -0
- data/lib/solarwinds_apm/support/swomarginalia/load_swomarginalia.rb +48 -0
- data/lib/solarwinds_apm/support/swomarginalia/railtie.rb +22 -0
- data/lib/solarwinds_apm/support/swomarginalia/swomarginalia.rb +86 -0
- data/lib/solarwinds_apm/support/transaction_cache.rb +24 -0
- data/lib/solarwinds_apm/support/transaction_settings.rb +26 -209
- data/lib/solarwinds_apm/support/transformer.rb +56 -0
- data/lib/solarwinds_apm/support/txn_name_manager.rb +25 -0
- data/lib/solarwinds_apm/support/x_trace_options.rb +42 -26
- data/lib/solarwinds_apm/support.rb +33 -10
- data/lib/solarwinds_apm/support_report.rb +10 -32
- data/lib/solarwinds_apm/thread_local.rb +1 -1
- data/lib/solarwinds_apm/version.rb +4 -4
- data/lib/solarwinds_apm.rb +31 -26
- metadata +76 -121
- data/.dockerignore +0 -5
- data/.gitignore +0 -58
- data/.rubocop.yml +0 -29
- data/.whitesource +0 -22
- data/.yardopts +0 -7
- data/CHANGELOG-appoptics.md +0 -766
- data/CHANGELOG.md +0 -82
- data/CONFIG.md +0 -31
- data/Gemfile +0 -15
- data/README.md +0 -385
- data/bin/solarwinds_apm_config +0 -15
- data/examples/prepend.rb +0 -13
- data/examples/sdk_examples.rb +0 -158
- data/ext/oboe_metal/README.md +0 -69
- data/ext/oboe_metal/extconf_local.rb +0 -75
- data/ext/oboe_metal/lib/.keep +0 -0
- data/ext/oboe_metal/noop/noop.c +0 -8
- data/ext/oboe_metal/src/README.md +0 -6
- data/ext/oboe_metal/src/frames.cc +0 -247
- data/ext/oboe_metal/src/frames.h +0 -40
- data/ext/oboe_metal/src/logging.cc +0 -97
- data/ext/oboe_metal/src/logging.h +0 -34
- data/ext/oboe_metal/src/profiling.cc +0 -435
- data/ext/oboe_metal/src/profiling.h +0 -78
- data/ext/oboe_metal/test/CMakeLists.txt +0 -53
- data/ext/oboe_metal/test/FindGMock.cmake +0 -43
- data/ext/oboe_metal/test/README.md +0 -56
- data/ext/oboe_metal/test/frames_test.cc +0 -164
- data/ext/oboe_metal/test/profiling_test.cc +0 -93
- data/ext/oboe_metal/test/ruby_inc_dir.rb +0 -8
- data/ext/oboe_metal/test/ruby_prefix.rb +0 -8
- data/ext/oboe_metal/test/ruby_test_helper.rb +0 -67
- data/ext/oboe_metal/test/test.h +0 -11
- data/ext/oboe_metal/test/test_main.cc +0 -32
- data/init.rb +0 -4
- data/lib/solarwinds_apm/api/layerinit.rb +0 -41
- data/lib/solarwinds_apm/api/logging.rb +0 -356
- data/lib/solarwinds_apm/api/memcache.rb +0 -37
- data/lib/solarwinds_apm/api/metrics.rb +0 -63
- data/lib/solarwinds_apm/api/util.rb +0 -98
- data/lib/solarwinds_apm/frameworks/grape.rb +0 -96
- data/lib/solarwinds_apm/frameworks/padrino.rb +0 -78
- data/lib/solarwinds_apm/frameworks/rails/inst/action_controller.rb +0 -100
- data/lib/solarwinds_apm/frameworks/rails/inst/action_controller5.rb +0 -50
- data/lib/solarwinds_apm/frameworks/rails/inst/action_controller_api.rb +0 -50
- data/lib/solarwinds_apm/frameworks/rails/inst/action_view.rb +0 -88
- data/lib/solarwinds_apm/frameworks/rails/inst/active_record.rb +0 -26
- data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +0 -29
- data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +0 -22
- data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +0 -103
- data/lib/solarwinds_apm/frameworks/rails/inst/logger_formatters.rb +0 -14
- data/lib/solarwinds_apm/frameworks/rails.rb +0 -100
- data/lib/solarwinds_apm/frameworks/sinatra.rb +0 -96
- data/lib/solarwinds_apm/inst/bunny-client.rb +0 -157
- data/lib/solarwinds_apm/inst/bunny-consumer.rb +0 -102
- data/lib/solarwinds_apm/inst/curb.rb +0 -289
- data/lib/solarwinds_apm/inst/dalli.rb +0 -89
- data/lib/solarwinds_apm/inst/delayed_job.rb +0 -100
- data/lib/solarwinds_apm/inst/excon.rb +0 -113
- data/lib/solarwinds_apm/inst/faraday.rb +0 -96
- data/lib/solarwinds_apm/inst/graphql.rb +0 -206
- data/lib/solarwinds_apm/inst/grpc_client.rb +0 -147
- data/lib/solarwinds_apm/inst/grpc_server.rb +0 -119
- data/lib/solarwinds_apm/inst/httpclient.rb +0 -182
- data/lib/solarwinds_apm/inst/memcached.rb +0 -86
- data/lib/solarwinds_apm/inst/mongo.rb +0 -246
- data/lib/solarwinds_apm/inst/mongo2.rb +0 -225
- data/lib/solarwinds_apm/inst/moped.rb +0 -466
- data/lib/solarwinds_apm/inst/net_http.rb +0 -60
- data/lib/solarwinds_apm/inst/rack.rb +0 -223
- data/lib/solarwinds_apm/inst/rack_cache.rb +0 -35
- data/lib/solarwinds_apm/inst/redis.rb +0 -280
- data/lib/solarwinds_apm/inst/redis_v4.rb +0 -273
- data/lib/solarwinds_apm/inst/resque.rb +0 -129
- data/lib/solarwinds_apm/inst/rest-client.rb +0 -43
- data/lib/solarwinds_apm/inst/sequel.rb +0 -241
- data/lib/solarwinds_apm/inst/sidekiq-client.rb +0 -63
- data/lib/solarwinds_apm/inst/sidekiq-worker.rb +0 -64
- data/lib/solarwinds_apm/inst/typhoeus.rb +0 -90
- data/lib/solarwinds_apm/instrumentation.rb +0 -22
- data/lib/solarwinds_apm/loading.rb +0 -65
- data/lib/solarwinds_apm/ruby.rb +0 -35
- data/lib/solarwinds_apm/sdk/current_trace_info.rb +0 -123
- data/lib/solarwinds_apm/sdk/custom_metrics.rb +0 -94
- data/lib/solarwinds_apm/sdk/logging.rb +0 -37
- data/lib/solarwinds_apm/sdk/trace_context_headers.rb +0 -69
- data/lib/solarwinds_apm/sdk/tracing.rb +0 -432
- data/lib/solarwinds_apm/support/profiling.rb +0 -25
- data/lib/solarwinds_apm/support/trace_context.rb +0 -53
- data/lib/solarwinds_apm/support/trace_state.rb +0 -69
- data/lib/solarwinds_apm/support/trace_string.rb +0 -89
- data/lib/solarwinds_apm/support/transaction_metrics.rb +0 -67
- data/lib/solarwinds_apm/test.rb +0 -165
- data/lib/solarwinds_apm/util.rb +0 -426
- data/log/.keep +0 -0
- data/log/postgresql/.keep +0 -0
- data/solarwinds_apm.gemspec +0 -55
- data/yardoc_frontpage.md +0 -24
data/examples/sdk_examples.rb
DELETED
@@ -1,158 +0,0 @@
|
|
1
|
-
# Copyright (c) 2020 SolarWinds, LLC.
|
2
|
-
# All rights reserved.
|
3
|
-
|
4
|
-
###############################################################
|
5
|
-
# SDK EXAMPLES
|
6
|
-
###############################################################
|
7
|
-
# The uses cases of the SDK include:
|
8
|
-
# - tracing a piece of your own code
|
9
|
-
# - tracing a method call of a gem that is not auto-instrumented
|
10
|
-
# by solarwinds_apm
|
11
|
-
#
|
12
|
-
# SDK documentation:
|
13
|
-
# https://rubydoc.info/gems/solarwinds_apm/SolarWindsAPM/SDK
|
14
|
-
|
15
|
-
###############################################################
|
16
|
-
# Prerequisits
|
17
|
-
# export SW_APM_SERVICE_KEY=<API token>:<service_name>
|
18
|
-
# `bundle exec ruby sdk_examples.rb`
|
19
|
-
# 5 traced requests will show up in the backend
|
20
|
-
###############################################################
|
21
|
-
|
22
|
-
require 'solarwinds_apm'
|
23
|
-
|
24
|
-
unless SolarWindsAPM::SDK.solarwinds_ready?(10_000)
|
25
|
-
puts "aborting!!! Agent not ready after 10 seconds"
|
26
|
-
exit false
|
27
|
-
end
|
28
|
-
|
29
|
-
###############################################################
|
30
|
-
### ADD A SPAN
|
31
|
-
###############################################################
|
32
|
-
#
|
33
|
-
# SolarWindsAPM::SDK.trace()
|
34
|
-
# This method adds a span to a trace that has been started either
|
35
|
-
# by the auto-instrumentation of the gem handling incoming requests
|
36
|
-
# or the SDK method `start_trace`.
|
37
|
-
# If this method is called outside of the context of a started
|
38
|
-
# trace no spans will be created.
|
39
|
-
#
|
40
|
-
# The argument is the name for the span
|
41
|
-
|
42
|
-
SolarWindsAPM::SDK.trace('span_name') do
|
43
|
-
[9, 6, 12, 2, 7, 1, 9, 3, 4, 14, 5, 8].sort
|
44
|
-
end
|
45
|
-
|
46
|
-
###############################################################
|
47
|
-
# START A TRACE, ADD A SPAN, AND LOG AN INFO EVENT
|
48
|
-
###############################################################
|
49
|
-
#
|
50
|
-
# SolarWindsAPM::SDK.start_trace()
|
51
|
-
# This method starts a trace. It is handy for background jobs,
|
52
|
-
# workers, or scripts, that are not part of a rack application
|
53
|
-
|
54
|
-
SolarWindsAPM::SDK.start_trace('outer_span') do
|
55
|
-
SolarWindsAPM::SDK.trace('first_child_span') do
|
56
|
-
[9, 6, 12, 2, 7, 1, 9, 3, 4, 14, 5, 8].sort
|
57
|
-
SolarWindsAPM::SDK.log_info({ some: :fancy, hash: :to, send: 1 })
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
###############################################################
|
62
|
-
# LOG AN ERROR EVENT
|
63
|
-
###############################################################
|
64
|
-
#
|
65
|
-
# SolarWindsAPM::SDK.log_exception()
|
66
|
-
# This method adds an error event to the trace, which will be
|
67
|
-
# displayed and counted as exception on the solarwinds_apm dashboard.
|
68
|
-
|
69
|
-
def do_raise
|
70
|
-
raise StandardError.new("oops")
|
71
|
-
end
|
72
|
-
|
73
|
-
SolarWindsAPM::SDK.start_trace('with_error') do
|
74
|
-
begin
|
75
|
-
do_raise
|
76
|
-
rescue => e
|
77
|
-
SolarWindsAPM::SDK.log_exception(e)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
###############################################################
|
82
|
-
# TRACE A METHOD
|
83
|
-
###############################################################
|
84
|
-
#
|
85
|
-
# SolarWindsAPM::SDK.trace_method()
|
86
|
-
# This creates a span every time the defined method is run.
|
87
|
-
# The method can be of any (accessible) type (instance,
|
88
|
-
# singleton, private, protected etc.).
|
89
|
-
|
90
|
-
module ExampleModule
|
91
|
-
def self.do_sum(a, b)
|
92
|
-
a + b
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
SolarWindsAPM::SDK.trace_method(ExampleModule,
|
97
|
-
:do_sum,
|
98
|
-
config: { name: 'computation', backtrace: true },
|
99
|
-
kvs: { CustomKey: "some_info" })
|
100
|
-
|
101
|
-
SolarWindsAPM::SDK.start_trace('trace_a_method') do
|
102
|
-
ExampleModule.do_sum(1, 2)
|
103
|
-
ExampleModule.do_sum(3, 4)
|
104
|
-
end
|
105
|
-
|
106
|
-
###############################################################
|
107
|
-
# SET A CUSTOM TRANSACTION NAME
|
108
|
-
###############################################################
|
109
|
-
#
|
110
|
-
# SolarWindsAPM::SDK.set_transaction_name()
|
111
|
-
#
|
112
|
-
# this method can be called anytime after a trace has been started to add a
|
113
|
-
# custom name for the whole transaction.
|
114
|
-
# In case of a controller the trace is usually started in rack.
|
115
|
-
|
116
|
-
class FakeController
|
117
|
-
def create(params)
|
118
|
-
# @fake = fake.new(params.permit(:type, :title))
|
119
|
-
# @fake.save
|
120
|
-
SolarWindsAPM::SDK.set_transaction_name("fake.#{params[:type]}")
|
121
|
-
# redirect_to @fake
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
SolarWindsAPM::SDK.start_trace('set_transaction_name') do
|
126
|
-
FakeController.new.create(type: 'news')
|
127
|
-
end
|
128
|
-
|
129
|
-
###############################################################
|
130
|
-
# LOG INJECTION OF TRACE_ID
|
131
|
-
###############################################################
|
132
|
-
#
|
133
|
-
# SolarWindsAPM::SDK.current_trace_info
|
134
|
-
# This method creates an object with the current trace ID and
|
135
|
-
# helper methods to add the ID to logs for cross-referencing.
|
136
|
-
|
137
|
-
SolarWindsAPM::Config[:log_traceId] = :always
|
138
|
-
|
139
|
-
SolarWindsAPM::SDK.start_trace('log_trace_id') do
|
140
|
-
trace = SolarWindsAPM::SDK.current_trace_info
|
141
|
-
SolarWindsAPM.logger.warn "Some log message #{trace.for_log}"
|
142
|
-
end
|
143
|
-
|
144
|
-
###############################################################
|
145
|
-
# START A TRACE AND PROFILE
|
146
|
-
###############################################################
|
147
|
-
#
|
148
|
-
# SolarWindsAPM::Profiling.run
|
149
|
-
# This method adds profiling for the code executed in the block
|
150
|
-
|
151
|
-
SolarWindsAPM::SDK.start_trace("#{name}_profiling") do
|
152
|
-
SolarWindsAPM::Profiling.run do
|
153
|
-
10.times do
|
154
|
-
[9, 6, 12, 2, 7, 1, 9, 3, 4, 14, 5, 8].sort
|
155
|
-
sleep 0.2
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
data/ext/oboe_metal/README.md
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
# Debug the c-code with gdb
|
2
|
-
|
3
|
-
inspired by: https://dev.to/wataash/how-to-create-and-debug-ruby-gem-with-c-native-extension-3l8b
|
4
|
-
|
5
|
-
|
6
|
-
## install ruby with sources
|
7
|
-
|
8
|
-
rbenv is your friend ;) -k means keep sources
|
9
|
-
|
10
|
-
```
|
11
|
-
rbenv install -k 2.7.5
|
12
|
-
rbenv shell 2.7.5
|
13
|
-
|
14
|
-
# check that ruby is debuggable
|
15
|
-
type ruby # => ruby is /home/wsh/.rbenv/shims/ruby
|
16
|
-
rbenv which ruby # => /home/wsh/.rbenv/versions/2.6.3/bin/ruby
|
17
|
-
```
|
18
|
-
|
19
|
-
|
20
|
-
##
|
21
|
-
## add debug info when compiling solarwinds_apm
|
22
|
-
add this line to extconf.rb to turn off optimization
|
23
|
-
|
24
|
-
```
|
25
|
-
CONFIG["optflags"] = "-O0"
|
26
|
-
```
|
27
|
-
|
28
|
-
|
29
|
-
##
|
30
|
-
## start ruby app with gdb
|
31
|
-
|
32
|
-
This will run ruby and load the app with a breakpoint in the Reporter::startThread
|
33
|
-
c-function.
|
34
|
-
|
35
|
-
`bundle exec gdb -q -ex 'set breakpoint pending on' -ex 'b Reporter::startThread' -ex run --args ruby -e 'require "./app"'`
|
36
|
-
|
37
|
-
If there is a bug in the ruby code or a ruby byebug binding that halts the
|
38
|
-
script, the debugger will hang without showing any output.
|
39
|
-
So, make sure `bundle exec ruby app.rb` runs.
|
40
|
-
|
41
|
-
use the gdb navigation commands to step through the code. If it says:
|
42
|
-
|
43
|
-
```
|
44
|
-
(gdb) n
|
45
|
-
Single stepping until exit from function _ZN8Reporter11startThreadEv@plt,
|
46
|
-
which has no line number information.
|
47
|
-
```
|
48
|
-
|
49
|
-
type `c` and it may end up stopping in the right location.
|
50
|
-
|
51
|
-
##
|
52
|
-
## make ruby .gdbinit macros available
|
53
|
-
|
54
|
-
These macros are pretty elaborate. They are checked in the ruby github
|
55
|
-
repo: https://github.com/ruby/ruby/blob/master/.gdbinit
|
56
|
-
The code is nicely formatted and colorized in github and easiest to read there.
|
57
|
-
|
58
|
-
installation in the user's home dir:
|
59
|
-
```
|
60
|
-
wget https://github.com/ruby/ruby/blob/master/.gdbinit
|
61
|
-
```
|
62
|
-
##
|
63
|
-
## examples
|
64
|
-
|
65
|
-
Some inspiring examples here:
|
66
|
-
|
67
|
-
https://jvns.ca/blog/2016/06/12/a-weird-system-call-process-vm-readv/
|
68
|
-
|
69
|
-
https://medium.com/@zanker/finding-a-ruby-bug-with-gdb-56d6b321bc86
|
@@ -1,75 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Copyright (c) 2016 SolarWinds, LLC.
|
4
|
-
# All rights reserved.
|
5
|
-
|
6
|
-
require 'mkmf'
|
7
|
-
require 'rbconfig'
|
8
|
-
require 'open-uri'
|
9
|
-
require 'no_proxy_fix'
|
10
|
-
|
11
|
-
CONFIG['warnflags'] = CONFIG['warnflags'].gsub(/-Wdeclaration-after-statement/, '')
|
12
|
-
.gsub(/-Wimplicit-function-declaration/, '')
|
13
|
-
.gsub(/-Wimplicit-int/, '')
|
14
|
-
.gsub(/-Wno-tautological-compare/, '')
|
15
|
-
.gsub(/-Wno-self-assign/, '')
|
16
|
-
.gsub(/-Wno-parentheses-equality/, '')
|
17
|
-
.gsub(/-Wno-constant-logical-operand/, '')
|
18
|
-
.gsub(/-Wno-cast-function-type/, '')
|
19
|
-
init_mkmf(CONFIG)
|
20
|
-
|
21
|
-
ext_dir = File.expand_path(File.dirname(__FILE__))
|
22
|
-
|
23
|
-
# Set the mkmf lib paths so we have no issues linking to
|
24
|
-
# the SolarWindsAPM libs.
|
25
|
-
ao_lib_dir = File.join(ext_dir, 'lib')
|
26
|
-
ao_path = '../../../oboe/factory-output'
|
27
|
-
ao_clib = "liboboe-1.0-x86_64.so"
|
28
|
-
ao_item = File.join(ao_path, ao_clib)
|
29
|
-
clib = File.join(ao_lib_dir, ao_clib)
|
30
|
-
|
31
|
-
FileUtils.cp(ao_item, clib)
|
32
|
-
|
33
|
-
# Create relative symlinks for the SolarWindsAPM library
|
34
|
-
Dir.chdir(ao_lib_dir) do
|
35
|
-
File.symlink(ao_clib, 'liboboe.so')
|
36
|
-
File.symlink(ao_clib, 'liboboe-1.0.so.0')
|
37
|
-
end
|
38
|
-
|
39
|
-
dir_config('oboe', 'src', 'lib')
|
40
|
-
|
41
|
-
if have_library('oboe', 'oboe_config_get_revision', 'oboe.h')
|
42
|
-
$libs = append_library($libs, 'oboe')
|
43
|
-
$libs = append_library($libs, 'stdc++')
|
44
|
-
|
45
|
-
$CFLAGS << " #{ENV['CFLAGS']}"
|
46
|
-
# $CPPFLAGS << " #{ENV['CPPFLAGS']} -std=c++11"
|
47
|
-
# TODO for debugging: -pg -gdwarf-2, remove for production
|
48
|
-
# -pg does not work on alpine https://www.openwall.com/lists/musl/2014/11/05/2
|
49
|
-
$CPPFLAGS << " #{ENV['CPPFLAGS']} -std=c++11 -gdwarf-2 -I$$ORIGIN/../ext/oboe_metal/include -I$$ORIGIN/../ext/oboe_metal/src"
|
50
|
-
# $CPPFLAGS << " #{ENV['CPPFLAGS']} -std=c++11 -I$$ORIGIN/../ext/oboe_metal/include"
|
51
|
-
$LIBS << " #{ENV['LIBS']}"
|
52
|
-
|
53
|
-
# use "z,defs" to see what happens during linking
|
54
|
-
# $LDFLAGS << " #{ENV['LDFLAGS']} '-Wl,-rpath=$$ORIGIN/../ext/oboe_metal/lib,-z,defs' -lrt"
|
55
|
-
$LDFLAGS << " #{ENV['LDFLAGS']} '-Wl,-rpath=$$ORIGIN/../ext/oboe_metal/lib' -lrt"
|
56
|
-
$CXXFLAGS += " -std=c++11 "
|
57
|
-
|
58
|
-
# ____ include debug info, comment out when not debugging
|
59
|
-
# ____ -pg -> profiling info for gprof
|
60
|
-
CONFIG["debugflags"] = "-ggdb3 "
|
61
|
-
CONFIG["optflags"] = "-O0"
|
62
|
-
|
63
|
-
create_makefile('libsolarwinds_apm', 'src')
|
64
|
-
else
|
65
|
-
$stderr.puts '== ERROR ========================================================='
|
66
|
-
if have_library('oboe')
|
67
|
-
$stderr.puts "The c-library either needs to be updated or doesn't match the OS."
|
68
|
-
$stderr.puts 'No tracing will occur.'
|
69
|
-
else
|
70
|
-
$stderr.puts 'Could not find a matching c-library. No tracing will occur.'
|
71
|
-
end
|
72
|
-
$stderr.puts 'Contact technicalsupport@solarwinds.com if the problem persists.'
|
73
|
-
$stderr.puts '=================================================================='
|
74
|
-
create_makefile('oboe_noop', 'noop')
|
75
|
-
end
|
data/ext/oboe_metal/lib/.keep
DELETED
File without changes
|
data/ext/oboe_metal/noop/noop.c
DELETED
@@ -1,247 +0,0 @@
|
|
1
|
-
// Copyright (c) 2021 SolarWinds, LLC.
|
2
|
-
// All rights reserved.
|
3
|
-
|
4
|
-
#include "frames.h"
|
5
|
-
|
6
|
-
using namespace std;
|
7
|
-
|
8
|
-
unordered_map<VALUE, FrameData> cached_frames;
|
9
|
-
|
10
|
-
// in theory the mutex is not needed, because Ruby does not context switch
|
11
|
-
// while executing a foreign function, but will this always hold true?
|
12
|
-
mutex cached_frames_mutex;
|
13
|
-
|
14
|
-
void Frames::reserve_cached_frames() {
|
15
|
-
lock_guard<mutex> guard(cached_frames_mutex);
|
16
|
-
// unordered_maps grow automatically, but it starts at 1 and then
|
17
|
-
// doubles when it is full, so lets avoid the warmup
|
18
|
-
cached_frames.reserve(500); // it will round to a prime number: 503
|
19
|
-
}
|
20
|
-
|
21
|
-
void Frames::clear_cached_frames() {
|
22
|
-
lock_guard<mutex> guard(cached_frames_mutex);
|
23
|
-
// unordered_maps grow automatically, but it starts at 1 and then
|
24
|
-
// doubles when it is full, so lets avoid the warmup
|
25
|
-
cached_frames.clear();
|
26
|
-
}
|
27
|
-
|
28
|
-
// this is a private function
|
29
|
-
int Frames::cache_frame(VALUE frame) {
|
30
|
-
VALUE val;
|
31
|
-
FrameData data;
|
32
|
-
|
33
|
-
// only cache it if it does not exist
|
34
|
-
if (cached_frames.count(frame) == 0) {
|
35
|
-
val = rb_profile_frame_label(frame); // returns method or block
|
36
|
-
if (RB_TYPE_P(val, T_STRING))
|
37
|
-
data.method = RSTRING_PTR(val);
|
38
|
-
|
39
|
-
if (data.method.rfind("block ", 0) == 0) {
|
40
|
-
// we don't need more info if it is a block
|
41
|
-
// we ignore block level info because they make things messy
|
42
|
-
lock_guard<mutex> guard(cached_frames_mutex);
|
43
|
-
cached_frames.insert({frame, data});
|
44
|
-
return 0;
|
45
|
-
}
|
46
|
-
|
47
|
-
val = rb_profile_frame_classpath(frame); // returns class or nil
|
48
|
-
if (RB_TYPE_P(val, T_STRING)) data.klass = RSTRING_PTR(val);
|
49
|
-
|
50
|
-
val = rb_profile_frame_absolute_path(frame); // returns file, use rb_profile_frame_path() if nil
|
51
|
-
if (!RB_TYPE_P(val, T_STRING)) val = rb_profile_frame_path(frame);
|
52
|
-
if (RB_TYPE_P(val, T_STRING)) data.file = RSTRING_PTR(val);
|
53
|
-
|
54
|
-
// Ruby 3 reports <cfunc>, but the linenumbers are bogus
|
55
|
-
// the default line number is 0
|
56
|
-
if (!data.file.compare("<cfunc>") == 0) {
|
57
|
-
val = rb_profile_frame_first_lineno(frame); // returns line number
|
58
|
-
if (RB_TYPE_P(val, T_FIXNUM)) {
|
59
|
-
data.lineno = NUM2INT(val);
|
60
|
-
}
|
61
|
-
}
|
62
|
-
lock_guard<mutex> guard(cached_frames_mutex);
|
63
|
-
cached_frames.insert({frame, data});
|
64
|
-
}
|
65
|
-
return 0;
|
66
|
-
}
|
67
|
-
|
68
|
-
// all frames in frames_buffer must be in cached_frames
|
69
|
-
// before calling this function
|
70
|
-
// we are saving the check for better performance
|
71
|
-
int Frames::collect_frame_data(VALUE *frames_buffer, int num, vector<FrameData> &frame_data) {
|
72
|
-
if (num == 1) {
|
73
|
-
if (frames_buffer[0] == PR_IN_GC) {
|
74
|
-
FrameData data;
|
75
|
-
data.method = "GARBAGE COLLECTION";
|
76
|
-
frame_data.push_back(data);
|
77
|
-
return 0;
|
78
|
-
} else if (frames_buffer[0] == PR_OTHER_THREAD) {
|
79
|
-
FrameData data;
|
80
|
-
data.method = "OTHER THREADS";
|
81
|
-
frame_data.push_back(data);
|
82
|
-
return 0;
|
83
|
-
}
|
84
|
-
}
|
85
|
-
|
86
|
-
for (int i = 0; i < num; i++) {
|
87
|
-
VALUE frame = frames_buffer[i];
|
88
|
-
frame_data.push_back(cached_frames[frame]);
|
89
|
-
}
|
90
|
-
return 0;
|
91
|
-
}
|
92
|
-
|
93
|
-
/////
|
94
|
-
// For the sake of efficiency this function filters uninteresting frames and
|
95
|
-
// does the caching of frames at the same time
|
96
|
-
//
|
97
|
-
// in-place removal of
|
98
|
-
// - frames with line number == 0
|
99
|
-
// - all but last of repeated frames
|
100
|
-
// - "block" frames (they are confusing) <- revisit
|
101
|
-
// and cache uncached frames
|
102
|
-
int Frames::remove_garbage(VALUE *frames_buffer, int num) {
|
103
|
-
if (num == 1 && (frames_buffer[0] == PR_OTHER_THREAD || frames_buffer[0] == PR_IN_GC))
|
104
|
-
return 1;
|
105
|
-
|
106
|
-
// TODO decide what to do with <cfunc> frames in Ruby 3
|
107
|
-
// ____ AO-20269
|
108
|
-
|
109
|
-
// 1) ignore top frames where the line number is 0
|
110
|
-
// does that mean there is no line number???
|
111
|
-
bool found = true;
|
112
|
-
|
113
|
-
while (found && num > 0) {
|
114
|
-
if (cached_frames.count(frames_buffer[num - 1]) == 1) {
|
115
|
-
found = (cached_frames[frames_buffer[num - 1]].lineno == 0);
|
116
|
-
if (found) num--;
|
117
|
-
} else {
|
118
|
-
VALUE val = rb_profile_frame_first_lineno(frames_buffer[num - 1]);
|
119
|
-
found = (!RB_TYPE_P(val, T_FIXNUM) || !NUM2INT(val));
|
120
|
-
if (found) {
|
121
|
-
lock_guard<mutex> guard(cached_frames_mutex);
|
122
|
-
cached_frames[frames_buffer[num - 1]].lineno = 0;
|
123
|
-
num--;
|
124
|
-
}
|
125
|
-
}
|
126
|
-
}
|
127
|
-
|
128
|
-
// 2) remove all repeated frames, keep the last one
|
129
|
-
int count = 0;
|
130
|
-
int k = 0;
|
131
|
-
found = false;
|
132
|
-
while (count < num - k) {
|
133
|
-
// is this frame repeated ahead?
|
134
|
-
// if so we will replace it with the next one in line
|
135
|
-
for (int j = count + k + 1; j < num; j++) {
|
136
|
-
if (frames_buffer[count] == frames_buffer[j]) {
|
137
|
-
found = true;
|
138
|
-
break;
|
139
|
-
}
|
140
|
-
}
|
141
|
-
|
142
|
-
if (found) {
|
143
|
-
// if we found this frame again later in the snapshot
|
144
|
-
// we are going to override this one
|
145
|
-
// but not if this is going beyond the boundary
|
146
|
-
k++;
|
147
|
-
if (count + k < num - 1) frames_buffer[count] = frames_buffer[count + k];
|
148
|
-
} else {
|
149
|
-
count++;
|
150
|
-
frames_buffer[count] = frames_buffer[count + k];
|
151
|
-
}
|
152
|
-
found = false;
|
153
|
-
}
|
154
|
-
|
155
|
-
// 3) remove "block" frames, they are reported inconsistently and mess up
|
156
|
-
// the profile in the dashboard
|
157
|
-
// 4) while we are at it we also cache all the frames
|
158
|
-
// these 2 are combined so we don't have to run this loop twice
|
159
|
-
num = count;
|
160
|
-
count = 0, k = 0;
|
161
|
-
string method;
|
162
|
-
|
163
|
-
while (count < num - k) {
|
164
|
-
frames_buffer[count] = frames_buffer[count + k];
|
165
|
-
cache_frame(frames_buffer[count]);
|
166
|
-
method = cached_frames[frames_buffer[count]].method;
|
167
|
-
|
168
|
-
// TODO revisit need to remove block frames, they only appear when the Ruby
|
169
|
-
// ____ script is not started with a method and has blocks outside of the
|
170
|
-
// ____ methods called and sometimes inside of rack
|
171
|
-
if (method.rfind("block ", 0) == 0) {
|
172
|
-
k++;
|
173
|
-
} else {
|
174
|
-
count++;
|
175
|
-
}
|
176
|
-
}
|
177
|
-
return count;
|
178
|
-
}
|
179
|
-
|
180
|
-
// returns the number of the matching frames
|
181
|
-
int Frames::num_matching(VALUE *frames_buffer, int num,
|
182
|
-
VALUE *prev_frames_buffer, int prev_num) {
|
183
|
-
int i;
|
184
|
-
int min = std::min(num, prev_num);
|
185
|
-
|
186
|
-
for (i = 0; i < min; i++) {
|
187
|
-
// we have to start from the "top"
|
188
|
-
if (frames_buffer[num - 1 - i] != prev_frames_buffer[prev_num - 1 - i]) {
|
189
|
-
return i;
|
190
|
-
}
|
191
|
-
}
|
192
|
-
return i;
|
193
|
-
}
|
194
|
-
|
195
|
-
/////////////////////// DEBUGGING HELPER FUNCTIONS /////////////////////////////
|
196
|
-
// helper function to print frame from ruby pointers to frame
|
197
|
-
void Frames::print_raw_frame_info(VALUE frame) {
|
198
|
-
if (frame == PR_IN_GC || frame == PR_OTHER_THREAD) {
|
199
|
-
return;
|
200
|
-
}
|
201
|
-
|
202
|
-
VALUE val;
|
203
|
-
int lineno;
|
204
|
-
string file, klass, method;
|
205
|
-
|
206
|
-
val = rb_profile_frame_first_lineno(frame); // returns line number
|
207
|
-
if (RB_TYPE_P(val, T_FIXNUM)) lineno = NUM2INT(val);
|
208
|
-
|
209
|
-
val = rb_profile_frame_classpath(frame); // returns class or nil
|
210
|
-
if (RB_TYPE_P(val, T_STRING)) klass = RSTRING_PTR(val);
|
211
|
-
|
212
|
-
val = rb_profile_frame_absolute_path(frame); // returns file, use rb_profile_frame_path() if nil
|
213
|
-
if (!RB_TYPE_P(val, T_STRING)) val = rb_profile_frame_path(frame);
|
214
|
-
if (RB_TYPE_P(val, T_STRING)) file = RSTRING_PTR(val);
|
215
|
-
|
216
|
-
val = rb_profile_frame_label(frame); // returns method or block
|
217
|
-
if (RB_TYPE_P(val, T_STRING)) method = RSTRING_PTR(val);
|
218
|
-
|
219
|
-
cout << " " << frame << " "
|
220
|
-
<< "L: " << lineno << " "
|
221
|
-
<< "F: " << file << " "
|
222
|
-
<< "C: " << klass << " "
|
223
|
-
<< "M: " << method << endl;
|
224
|
-
}
|
225
|
-
|
226
|
-
void Frames::print_all_raw_frames(VALUE *frames_buffer, int num) {
|
227
|
-
for (int i = 0; i < num; i++) {
|
228
|
-
print_raw_frame_info(frames_buffer[i]);
|
229
|
-
}
|
230
|
-
}
|
231
|
-
|
232
|
-
// helper function to print frame info
|
233
|
-
void Frames::print_frame_info(VALUE frame) {
|
234
|
-
if (cached_frames.find(frame) != cached_frames.end())
|
235
|
-
std::cout << cached_frames[frame].lineno << " "
|
236
|
-
<< cached_frames[frame].file << " "
|
237
|
-
<< cached_frames[frame].klass << " "
|
238
|
-
<< cached_frames[frame].method << std::endl;
|
239
|
-
}
|
240
|
-
|
241
|
-
// helper function for printing the cached frames
|
242
|
-
void Frames::print_cached_frames() {
|
243
|
-
std::cout << "cached_frames contains:" << endl;
|
244
|
-
for (auto it = cached_frames.cbegin(); it != cached_frames.cend(); ++it)
|
245
|
-
std::cout << " " << it->first << " - " << it->second.method << ":" << it->second.lineno << endl; // cannot modify *it
|
246
|
-
std::cout << std::endl;
|
247
|
-
}
|
data/ext/oboe_metal/src/frames.h
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
// Copyright (c) 2021 SolarWinds, LLC.
|
2
|
-
// All rights reserved.
|
3
|
-
|
4
|
-
#ifndef FRAMES_H
|
5
|
-
#define FRAMES_H
|
6
|
-
|
7
|
-
#include <vector>
|
8
|
-
|
9
|
-
#include <mutex>
|
10
|
-
#include <unordered_map>
|
11
|
-
|
12
|
-
#include <ruby/ruby.h>
|
13
|
-
#include <ruby/debug.h>
|
14
|
-
|
15
|
-
#include "profiling.h"
|
16
|
-
#include "oboe_api.h"
|
17
|
-
|
18
|
-
using namespace std;
|
19
|
-
|
20
|
-
class Frames {
|
21
|
-
public:
|
22
|
-
static void clear_cached_frames();
|
23
|
-
static void reserve_cached_frames();
|
24
|
-
static int collect_frame_data(VALUE *frames_buffer, int num, vector<FrameData> &frame_data);
|
25
|
-
static int remove_garbage(VALUE *frames_buffer, int num);
|
26
|
-
static int num_matching(VALUE *frames_buffer, int num,
|
27
|
-
VALUE *prev_frames_buffer, int prev_num);
|
28
|
-
|
29
|
-
private:
|
30
|
-
static int cache_frame(VALUE frame);
|
31
|
-
|
32
|
-
// Debugging helper functions
|
33
|
-
public:
|
34
|
-
static void print_raw_frame_info(VALUE frame);
|
35
|
-
static void print_all_raw_frames(VALUE *frames_buffer, int num);
|
36
|
-
static void print_frame_info(VALUE frame);
|
37
|
-
static void print_cached_frames();
|
38
|
-
};
|
39
|
-
|
40
|
-
#endif //FRAMES_H
|