solarwinds_apm 5.1.8 → 6.0.0.preV1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +0 -1
  3. data/ext/oboe_metal/extconf.rb +19 -23
  4. data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.sha256 +1 -1
  5. data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.sha256 +1 -1
  6. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.sha256 +1 -1
  7. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.sha256 +1 -1
  8. data/ext/oboe_metal/src/VERSION +1 -1
  9. data/ext/oboe_metal/src/oboe_api.cpp +9 -7
  10. data/ext/oboe_metal/src/oboe_api.h +7 -7
  11. data/ext/oboe_metal/src/oboe_debug.h +2 -0
  12. data/ext/oboe_metal/src/oboe_swig_wrap.cc +19 -18
  13. data/lib/oboe_metal.rb +116 -80
  14. data/lib/rails/generators/solarwinds_apm/install_generator.rb +1 -2
  15. data/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb +44 -260
  16. data/lib/solarwinds_apm/api/current_trace_info.rb +148 -0
  17. data/lib/solarwinds_apm/api/tracing.rb +30 -0
  18. data/lib/solarwinds_apm/api/transaction_name.rb +57 -0
  19. data/lib/solarwinds_apm/api.rb +8 -15
  20. data/lib/solarwinds_apm/base.rb +4 -131
  21. data/lib/solarwinds_apm/config.rb +128 -175
  22. data/lib/solarwinds_apm/constants.rb +32 -0
  23. data/lib/solarwinds_apm/logger.rb +1 -1
  24. data/lib/solarwinds_apm/noop/context.rb +2 -5
  25. data/lib/solarwinds_apm/noop/metadata.rb +1 -2
  26. data/lib/solarwinds_apm/noop/profiling.rb +3 -7
  27. data/lib/solarwinds_apm/oboe_init_options.rb +71 -33
  28. data/lib/solarwinds_apm/opentelemetry/solarwinds_exporter.rb +204 -0
  29. data/lib/solarwinds_apm/opentelemetry/solarwinds_processor.rb +163 -0
  30. data/lib/solarwinds_apm/opentelemetry/solarwinds_propagator.rb +92 -0
  31. data/lib/solarwinds_apm/opentelemetry/solarwinds_response_propagator.rb +72 -0
  32. data/lib/solarwinds_apm/opentelemetry/solarwinds_sampler.rb +330 -0
  33. data/lib/solarwinds_apm/opentelemetry.rb +8 -0
  34. data/lib/solarwinds_apm/otel_config.rb +161 -0
  35. data/lib/solarwinds_apm/{inst → support}/logger_formatter.rb +5 -6
  36. data/lib/solarwinds_apm/{inst → support}/logging_log_event.rb +3 -6
  37. data/lib/solarwinds_apm/{inst → support}/lumberjack_formatter.rb +1 -4
  38. data/lib/solarwinds_apm/support/oboe_tracing_mode.rb +27 -0
  39. data/lib/solarwinds_apm/support/swomarginalia/LICENSE +20 -0
  40. data/lib/solarwinds_apm/support/swomarginalia/README.md +41 -0
  41. data/lib/solarwinds_apm/support/swomarginalia/comment.rb +205 -0
  42. data/lib/solarwinds_apm/support/swomarginalia/load_swomarginalia.rb +48 -0
  43. data/lib/solarwinds_apm/support/swomarginalia/railtie.rb +22 -0
  44. data/lib/solarwinds_apm/support/swomarginalia/swomarginalia.rb +86 -0
  45. data/lib/solarwinds_apm/support/transaction_cache.rb +24 -0
  46. data/lib/solarwinds_apm/support/transaction_settings.rb +26 -209
  47. data/lib/solarwinds_apm/support/transformer.rb +56 -0
  48. data/lib/solarwinds_apm/support/txn_name_manager.rb +25 -0
  49. data/lib/solarwinds_apm/support/x_trace_options.rb +42 -26
  50. data/lib/solarwinds_apm/support.rb +33 -10
  51. data/lib/solarwinds_apm/support_report.rb +10 -32
  52. data/lib/solarwinds_apm/thread_local.rb +1 -1
  53. data/lib/solarwinds_apm/version.rb +4 -4
  54. data/lib/solarwinds_apm.rb +31 -26
  55. metadata +76 -121
  56. data/.dockerignore +0 -5
  57. data/.gitignore +0 -58
  58. data/.rubocop.yml +0 -29
  59. data/.whitesource +0 -22
  60. data/.yardopts +0 -7
  61. data/CHANGELOG-appoptics.md +0 -766
  62. data/CHANGELOG.md +0 -72
  63. data/CONFIG.md +0 -31
  64. data/Gemfile +0 -15
  65. data/README.md +0 -385
  66. data/bin/solarwinds_apm_config +0 -15
  67. data/examples/prepend.rb +0 -13
  68. data/examples/sdk_examples.rb +0 -158
  69. data/ext/oboe_metal/README.md +0 -69
  70. data/ext/oboe_metal/extconf_local.rb +0 -75
  71. data/ext/oboe_metal/lib/.keep +0 -0
  72. data/ext/oboe_metal/noop/noop.c +0 -8
  73. data/ext/oboe_metal/src/README.md +0 -6
  74. data/ext/oboe_metal/src/frames.cc +0 -247
  75. data/ext/oboe_metal/src/frames.h +0 -40
  76. data/ext/oboe_metal/src/logging.cc +0 -97
  77. data/ext/oboe_metal/src/logging.h +0 -34
  78. data/ext/oboe_metal/src/profiling.cc +0 -435
  79. data/ext/oboe_metal/src/profiling.h +0 -78
  80. data/ext/oboe_metal/test/CMakeLists.txt +0 -53
  81. data/ext/oboe_metal/test/FindGMock.cmake +0 -43
  82. data/ext/oboe_metal/test/README.md +0 -56
  83. data/ext/oboe_metal/test/frames_test.cc +0 -164
  84. data/ext/oboe_metal/test/profiling_test.cc +0 -93
  85. data/ext/oboe_metal/test/ruby_inc_dir.rb +0 -8
  86. data/ext/oboe_metal/test/ruby_prefix.rb +0 -8
  87. data/ext/oboe_metal/test/ruby_test_helper.rb +0 -67
  88. data/ext/oboe_metal/test/test.h +0 -11
  89. data/ext/oboe_metal/test/test_main.cc +0 -32
  90. data/init.rb +0 -4
  91. data/lib/solarwinds_apm/api/layerinit.rb +0 -41
  92. data/lib/solarwinds_apm/api/logging.rb +0 -356
  93. data/lib/solarwinds_apm/api/memcache.rb +0 -37
  94. data/lib/solarwinds_apm/api/metrics.rb +0 -63
  95. data/lib/solarwinds_apm/api/util.rb +0 -98
  96. data/lib/solarwinds_apm/frameworks/grape.rb +0 -96
  97. data/lib/solarwinds_apm/frameworks/padrino.rb +0 -78
  98. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller.rb +0 -100
  99. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller5.rb +0 -50
  100. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller_api.rb +0 -50
  101. data/lib/solarwinds_apm/frameworks/rails/inst/action_view.rb +0 -88
  102. data/lib/solarwinds_apm/frameworks/rails/inst/active_record.rb +0 -26
  103. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +0 -29
  104. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +0 -22
  105. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +0 -103
  106. data/lib/solarwinds_apm/frameworks/rails/inst/logger_formatters.rb +0 -14
  107. data/lib/solarwinds_apm/frameworks/rails.rb +0 -100
  108. data/lib/solarwinds_apm/frameworks/sinatra.rb +0 -96
  109. data/lib/solarwinds_apm/inst/bunny-client.rb +0 -157
  110. data/lib/solarwinds_apm/inst/bunny-consumer.rb +0 -102
  111. data/lib/solarwinds_apm/inst/curb.rb +0 -289
  112. data/lib/solarwinds_apm/inst/dalli.rb +0 -89
  113. data/lib/solarwinds_apm/inst/delayed_job.rb +0 -100
  114. data/lib/solarwinds_apm/inst/excon.rb +0 -113
  115. data/lib/solarwinds_apm/inst/faraday.rb +0 -96
  116. data/lib/solarwinds_apm/inst/graphql.rb +0 -206
  117. data/lib/solarwinds_apm/inst/grpc_client.rb +0 -147
  118. data/lib/solarwinds_apm/inst/grpc_server.rb +0 -119
  119. data/lib/solarwinds_apm/inst/httpclient.rb +0 -182
  120. data/lib/solarwinds_apm/inst/memcached.rb +0 -86
  121. data/lib/solarwinds_apm/inst/mongo.rb +0 -246
  122. data/lib/solarwinds_apm/inst/mongo2.rb +0 -225
  123. data/lib/solarwinds_apm/inst/moped.rb +0 -466
  124. data/lib/solarwinds_apm/inst/net_http.rb +0 -60
  125. data/lib/solarwinds_apm/inst/rack.rb +0 -223
  126. data/lib/solarwinds_apm/inst/rack_cache.rb +0 -35
  127. data/lib/solarwinds_apm/inst/redis.rb +0 -280
  128. data/lib/solarwinds_apm/inst/redis_v4.rb +0 -273
  129. data/lib/solarwinds_apm/inst/resque.rb +0 -129
  130. data/lib/solarwinds_apm/inst/rest-client.rb +0 -43
  131. data/lib/solarwinds_apm/inst/sequel.rb +0 -241
  132. data/lib/solarwinds_apm/inst/sidekiq-client.rb +0 -63
  133. data/lib/solarwinds_apm/inst/sidekiq-worker.rb +0 -64
  134. data/lib/solarwinds_apm/inst/typhoeus.rb +0 -90
  135. data/lib/solarwinds_apm/instrumentation.rb +0 -22
  136. data/lib/solarwinds_apm/loading.rb +0 -65
  137. data/lib/solarwinds_apm/ruby.rb +0 -35
  138. data/lib/solarwinds_apm/sdk/current_trace_info.rb +0 -123
  139. data/lib/solarwinds_apm/sdk/custom_metrics.rb +0 -94
  140. data/lib/solarwinds_apm/sdk/logging.rb +0 -37
  141. data/lib/solarwinds_apm/sdk/trace_context_headers.rb +0 -69
  142. data/lib/solarwinds_apm/sdk/tracing.rb +0 -432
  143. data/lib/solarwinds_apm/support/profiling.rb +0 -25
  144. data/lib/solarwinds_apm/support/trace_context.rb +0 -53
  145. data/lib/solarwinds_apm/support/trace_state.rb +0 -69
  146. data/lib/solarwinds_apm/support/trace_string.rb +0 -89
  147. data/lib/solarwinds_apm/support/transaction_metrics.rb +0 -67
  148. data/lib/solarwinds_apm/test.rb +0 -165
  149. data/lib/solarwinds_apm/util.rb +0 -426
  150. data/log/.keep +0 -0
  151. data/log/postgresql/.keep +0 -0
  152. data/solarwinds_apm.gemspec +0 -55
  153. data/yardoc_frontpage.md +0 -24
@@ -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
File without changes
@@ -1,8 +0,0 @@
1
- #include <ruby.h>
2
-
3
- /* ruby calls this to load the extension */
4
- void Init_oboe_noop(void) {
5
- /* assume we haven't yet defined Hola */
6
- // VALUE klass = rb_define_class("OboeNoop", rb_cObject);
7
- rb_define_class("OboeNoop", rb_cObject);
8
- }
@@ -1,6 +0,0 @@
1
-
2
- oboe_api.h and oboe_api.cpp are copied here from the oboe repo during install
3
-
4
- it is best to edit these file in the oboe codebase and use the OBOE_WIP=true env
5
- var to include the local development version while the changes aren't deployed to s3.
6
-
@@ -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
- }
@@ -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
@@ -1,97 +0,0 @@
1
- // Copyright (c) 2021 SolarWinds, LLC.
2
- // All rights reserved.
3
-
4
- #include "logging.h"
5
-
6
- using namespace std;
7
-
8
- const string Logging::profiling = "profiling";
9
- const string Logging::ruby = "ruby";
10
- const string Logging::entry = "entry";
11
- const string Logging::info = "info";
12
- const string Logging::exit = "exit";
13
-
14
- Event *Logging::createEvent(Metadata &md, string &prof_op_id, bool entry_event) {
15
- // startTrace does not add "Edge", for profiling we need to keep track of edges
16
- // separately from the main trace metadata
17
-
18
- oboe_metadata_t *md_t = md.metadata();
19
- Event *event = Event::startTrace(md_t);
20
-
21
- if (entry_event) {
22
- event->addSpanRef(md_t);
23
- } else {
24
- event->addProfileEdge(prof_op_id);
25
- event->addContextOpId(md_t);
26
- }
27
- prof_op_id.assign(event->opIdString());
28
-
29
- return event;
30
- }
31
-
32
- bool Logging::log_profile_entry(Metadata &md, string &prof_op_id, pid_t tid, long interval) {
33
- Event *event = Logging::createEvent(md, prof_op_id, true);
34
- event->addInfo((char *)"Label", Logging::entry);
35
- event->addInfo((char *)"Language", Logging::ruby);
36
- event->addInfo((char *)"TID", (long)tid);
37
- event->addInfo((char *)"Interval", interval);
38
-
39
- struct timeval tv;
40
- struct timezone *tz = NULL;
41
- gettimeofday(&tv, tz);
42
- event->addInfo((char *)"Timestamp_u", (long)tv.tv_sec * 1000000 + (long)tv.tv_usec);
43
-
44
- return Logging::log_profile_event(event);
45
- }
46
-
47
- bool Logging::log_profile_exit(Metadata &md, string &prof_op_id, pid_t tid,
48
- long *omitted, int num_omitted) {
49
- Event *event = Logging::createEvent(md, prof_op_id);
50
- event->addInfo((char *)"Label", Logging::exit);
51
- event->addInfo((char *)"TID", (long)tid);
52
- event->addInfo((char *)"SnapshotsOmitted", omitted, num_omitted);
53
-
54
- struct timeval tv;
55
- struct timezone *tz = NULL;
56
- gettimeofday(&tv, tz);
57
- event->addInfo((char *)"Timestamp_u", (long)tv.tv_sec * 1000000 + (long)tv.tv_usec);
58
-
59
- return Logging::log_profile_event(event);
60
- }
61
-
62
- bool Logging::log_profile_snapshot(Metadata &md,
63
- string &prof_op_id,
64
- long timestamp,
65
- std::vector<FrameData> const &new_frames,
66
- long exited_frames,
67
- long total_frames,
68
- long *omitted,
69
- int num_omitted,
70
- pid_t tid) {
71
-
72
- Event *event = Logging::createEvent(md, prof_op_id);
73
- event->addInfo((char *)"Timestamp_u", timestamp);
74
- event->addInfo((char *)"Label", Logging::info);
75
-
76
- event->addInfo((char *)"SnapshotsOmitted", omitted, num_omitted);
77
- event->addInfo((char *)"NewFrames", new_frames);
78
- event->addInfo((char *)"FramesExited", exited_frames);
79
- event->addInfo((char *)"FramesCount", total_frames);
80
- event->addInfo((char *)"TID", (long)tid);
81
-
82
- return Logging::log_profile_event(event);
83
- }
84
-
85
- bool Logging::log_profile_event(Event *event) {
86
- event->addInfo((char *)"Spec", Logging::profiling);
87
- event->addHostname();
88
- event->addInfo((char *)"PID", (long)AO_GETPID());
89
- event->addInfo((char *)"X-Trace", event->metadataString());
90
- event->sendProfiling();
91
-
92
- // see comment in oboe_api.cpp:
93
- // "event needs to be deleted, it is managed by swig %newobject"
94
- // !!! It needs to be deleted, I tested it !!!
95
- delete event;
96
- return true;
97
- }
@@ -1,34 +0,0 @@
1
- // Copyright (c) 2021 SolarWinds, LLC.
2
- // All rights reserved.
3
-
4
- #ifndef LOGGING_H
5
- #define LOGGING_H
6
-
7
- #include "oboe_api.h"
8
-
9
- using namespace std;
10
-
11
- // extern "C" int oboe_gettimeofday(struct timeval *tv);
12
-
13
- class Logging {
14
- public:
15
- static const string profiling, ruby, entry, info, exit;
16
- static bool log_profile_entry(Metadata &md, string &prof_op_id, pid_t tid, long interval);
17
- static bool log_profile_exit(Metadata &md, string &prof_op_id, pid_t tid,
18
- long *omitted, int num_omitted);
19
- static bool log_profile_snapshot(Metadata &md,
20
- string &prof_op_id,
21
- long timestamp,
22
- std::vector<FrameData> const &new_frames,
23
- long exited_frames,
24
- long total_frames,
25
- long *omitted,
26
- int num_omitted,
27
- pid_t tid);
28
-
29
- private:
30
- static Event *createEvent(Metadata &md, string &prof_op_id, bool entry_event = false);
31
- static bool log_profile_event(Event *event);
32
- };
33
-
34
- #endif //LOGGING_H