solarwinds_apm 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +5 -0
  3. data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +16 -0
  4. data/.github/workflows/build_and_release_gem.yml +112 -0
  5. data/.github/workflows/build_for_packagecloud.yml +70 -0
  6. data/.github/workflows/docker-images.yml +47 -0
  7. data/.github/workflows/run_cpluplus_tests.yml +73 -0
  8. data/.github/workflows/run_tests.yml +155 -0
  9. data/.github/workflows/scripts/test_install.rb +23 -0
  10. data/.github/workflows/swig/swig-v4.0.2.tar.gz +0 -0
  11. data/.github/workflows/test_on_4_linux.yml +161 -0
  12. data/.gitignore +39 -0
  13. data/.rubocop.yml +29 -0
  14. data/.yardopts +7 -0
  15. data/CHANGELOG.md +769 -0
  16. data/CONFIG.md +31 -0
  17. data/Gemfile +14 -0
  18. data/LICENSE +202 -0
  19. data/README.md +383 -0
  20. data/bin/solarwinds_apm_config +15 -0
  21. data/examples/prepend.rb +13 -0
  22. data/examples/sdk_examples.rb +158 -0
  23. data/ext/oboe_metal/README.md +69 -0
  24. data/ext/oboe_metal/extconf.rb +141 -0
  25. data/ext/oboe_metal/extconf_local.rb +75 -0
  26. data/ext/oboe_metal/lib/.keep +0 -0
  27. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256 +1 -0
  28. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256 +1 -0
  29. data/ext/oboe_metal/noop/noop.c +8 -0
  30. data/ext/oboe_metal/src/README.md +6 -0
  31. data/ext/oboe_metal/src/VERSION +2 -0
  32. data/ext/oboe_metal/src/bson/bson.h +220 -0
  33. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  34. data/ext/oboe_metal/src/frames.cc +247 -0
  35. data/ext/oboe_metal/src/frames.h +40 -0
  36. data/ext/oboe_metal/src/init_solarwinds_apm.cc +21 -0
  37. data/ext/oboe_metal/src/logging.cc +95 -0
  38. data/ext/oboe_metal/src/logging.h +35 -0
  39. data/ext/oboe_metal/src/oboe.h +1169 -0
  40. data/ext/oboe_metal/src/oboe_api.cpp +658 -0
  41. data/ext/oboe_metal/src/oboe_api.hpp +433 -0
  42. data/ext/oboe_metal/src/oboe_debug.h +59 -0
  43. data/ext/oboe_metal/src/oboe_swig_wrap.cc +7562 -0
  44. data/ext/oboe_metal/src/profiling.cc +435 -0
  45. data/ext/oboe_metal/src/profiling.h +78 -0
  46. data/ext/oboe_metal/test/CMakeLists.txt +53 -0
  47. data/ext/oboe_metal/test/FindGMock.cmake +43 -0
  48. data/ext/oboe_metal/test/README.md +56 -0
  49. data/ext/oboe_metal/test/frames_test.cc +164 -0
  50. data/ext/oboe_metal/test/profiling_test.cc +93 -0
  51. data/ext/oboe_metal/test/ruby_inc_dir.rb +8 -0
  52. data/ext/oboe_metal/test/ruby_prefix.rb +8 -0
  53. data/ext/oboe_metal/test/ruby_test_helper.rb +67 -0
  54. data/ext/oboe_metal/test/test.h +11 -0
  55. data/ext/oboe_metal/test/test_main.cc +32 -0
  56. data/init.rb +4 -0
  57. data/lib/oboe.rb +7 -0
  58. data/lib/oboe_metal.rb +172 -0
  59. data/lib/rails/generators/solarwinds_apm/install_generator.rb +47 -0
  60. data/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb +424 -0
  61. data/lib/solarwinds_apm/api/layerinit.rb +41 -0
  62. data/lib/solarwinds_apm/api/logging.rb +356 -0
  63. data/lib/solarwinds_apm/api/memcache.rb +37 -0
  64. data/lib/solarwinds_apm/api/metrics.rb +63 -0
  65. data/lib/solarwinds_apm/api/util.rb +98 -0
  66. data/lib/solarwinds_apm/api.rb +21 -0
  67. data/lib/solarwinds_apm/base.rb +160 -0
  68. data/lib/solarwinds_apm/config.rb +301 -0
  69. data/lib/solarwinds_apm/frameworks/grape.rb +96 -0
  70. data/lib/solarwinds_apm/frameworks/padrino.rb +78 -0
  71. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller.rb +100 -0
  72. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  73. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  74. data/lib/solarwinds_apm/frameworks/rails/inst/action_view.rb +88 -0
  75. data/lib/solarwinds_apm/frameworks/rails/inst/active_record.rb +26 -0
  76. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +29 -0
  77. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +22 -0
  78. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +103 -0
  79. data/lib/solarwinds_apm/frameworks/rails/inst/logger_formatters.rb +14 -0
  80. data/lib/solarwinds_apm/frameworks/rails.rb +100 -0
  81. data/lib/solarwinds_apm/frameworks/sinatra.rb +96 -0
  82. data/lib/solarwinds_apm/inst/bunny-client.rb +157 -0
  83. data/lib/solarwinds_apm/inst/bunny-consumer.rb +102 -0
  84. data/lib/solarwinds_apm/inst/curb.rb +288 -0
  85. data/lib/solarwinds_apm/inst/dalli.rb +89 -0
  86. data/lib/solarwinds_apm/inst/delayed_job.rb +100 -0
  87. data/lib/solarwinds_apm/inst/excon.rb +113 -0
  88. data/lib/solarwinds_apm/inst/faraday.rb +96 -0
  89. data/lib/solarwinds_apm/inst/graphql.rb +206 -0
  90. data/lib/solarwinds_apm/inst/grpc_client.rb +147 -0
  91. data/lib/solarwinds_apm/inst/grpc_server.rb +119 -0
  92. data/lib/solarwinds_apm/inst/httpclient.rb +181 -0
  93. data/lib/solarwinds_apm/inst/logger_formatter.rb +46 -0
  94. data/lib/solarwinds_apm/inst/logging_log_event.rb +24 -0
  95. data/lib/solarwinds_apm/inst/lumberjack_formatter.rb +9 -0
  96. data/lib/solarwinds_apm/inst/memcached.rb +86 -0
  97. data/lib/solarwinds_apm/inst/mongo.rb +246 -0
  98. data/lib/solarwinds_apm/inst/mongo2.rb +225 -0
  99. data/lib/solarwinds_apm/inst/moped.rb +466 -0
  100. data/lib/solarwinds_apm/inst/net_http.rb +60 -0
  101. data/lib/solarwinds_apm/inst/rack.rb +217 -0
  102. data/lib/solarwinds_apm/inst/rack_cache.rb +35 -0
  103. data/lib/solarwinds_apm/inst/redis.rb +273 -0
  104. data/lib/solarwinds_apm/inst/resque.rb +129 -0
  105. data/lib/solarwinds_apm/inst/rest-client.rb +43 -0
  106. data/lib/solarwinds_apm/inst/sequel.rb +241 -0
  107. data/lib/solarwinds_apm/inst/sidekiq-client.rb +63 -0
  108. data/lib/solarwinds_apm/inst/sidekiq-worker.rb +64 -0
  109. data/lib/solarwinds_apm/inst/typhoeus.rb +90 -0
  110. data/lib/solarwinds_apm/instrumentation.rb +22 -0
  111. data/lib/solarwinds_apm/loading.rb +65 -0
  112. data/lib/solarwinds_apm/logger.rb +14 -0
  113. data/lib/solarwinds_apm/noop/README.md +9 -0
  114. data/lib/solarwinds_apm/noop/context.rb +26 -0
  115. data/lib/solarwinds_apm/noop/metadata.rb +25 -0
  116. data/lib/solarwinds_apm/noop/profiling.rb +21 -0
  117. data/lib/solarwinds_apm/oboe_init_options.rb +191 -0
  118. data/lib/solarwinds_apm/ruby.rb +35 -0
  119. data/lib/solarwinds_apm/sdk/current_trace_info.rb +123 -0
  120. data/lib/solarwinds_apm/sdk/custom_metrics.rb +94 -0
  121. data/lib/solarwinds_apm/sdk/logging.rb +37 -0
  122. data/lib/solarwinds_apm/sdk/trace_context_headers.rb +69 -0
  123. data/lib/solarwinds_apm/sdk/tracing.rb +432 -0
  124. data/lib/solarwinds_apm/support/profiling.rb +22 -0
  125. data/lib/solarwinds_apm/support/trace_context.rb +53 -0
  126. data/lib/solarwinds_apm/support/trace_state.rb +69 -0
  127. data/lib/solarwinds_apm/support/trace_string.rb +89 -0
  128. data/lib/solarwinds_apm/support/transaction_metrics.rb +67 -0
  129. data/lib/solarwinds_apm/support/transaction_settings.rb +233 -0
  130. data/lib/solarwinds_apm/support/x_trace_options.rb +113 -0
  131. data/lib/solarwinds_apm/support.rb +12 -0
  132. data/lib/solarwinds_apm/support_report.rb +113 -0
  133. data/lib/solarwinds_apm/test.rb +165 -0
  134. data/lib/solarwinds_apm/thread_local.rb +26 -0
  135. data/lib/solarwinds_apm/util.rb +334 -0
  136. data/lib/solarwinds_apm/version.rb +17 -0
  137. data/lib/solarwinds_apm.rb +72 -0
  138. data/log/.keep +0 -0
  139. data/log/postgresql/.keep +0 -0
  140. data/solarwinds_apm.gemspec +52 -0
  141. data/yardoc_frontpage.md +24 -0
  142. metadata +228 -0
@@ -0,0 +1,164 @@
1
+
2
+
3
+ #include <string.h>
4
+
5
+ #include <algorithm>
6
+
7
+ #include "../src/profiling.h"
8
+ #include "../src/frames.h"
9
+ #include "gtest/gtest.h"
10
+ #include "ruby/debug.h"
11
+ #include "ruby/ruby.h"
12
+ #include "test.h"
13
+
14
+ extern unordered_map<VALUE, FrameData> cached_frames;
15
+
16
+ static VALUE test_frames[BUF_SIZE];
17
+ static int test_lines[BUF_SIZE];
18
+ int test_num;
19
+
20
+ static int ruby_version;
21
+
22
+ VALUE RubyCallsFrames::c_get_frames() {
23
+ test_num = rb_profile_frames(1, sizeof(test_frames) / sizeof(VALUE), test_frames, test_lines);
24
+ return Qnil;
25
+ }
26
+
27
+ void Init_RubyCallsFrames() {
28
+ static VALUE cTest = rb_define_module("RubyCalls");
29
+ rb_define_singleton_method(cTest, "get_frames", reinterpret_cast<VALUE (*)(...)>(RubyCallsFrames::c_get_frames), 0);
30
+
31
+ VALUE result;
32
+ result = rb_eval_string("RUBY_VERSION[0].to_i");
33
+ ruby_version = NUM2INT(result);
34
+ };
35
+
36
+ TEST(Frames, reserve_cached_frames) {
37
+ // it should only reserve once used during init
38
+ // unordered_map grows automatically
39
+ cached_frames.clear();
40
+
41
+ Frames::reserve_cached_frames();
42
+ int bucket_count = cached_frames.bucket_count();
43
+
44
+ Frames::reserve_cached_frames();
45
+ EXPECT_EQ(bucket_count, cached_frames.bucket_count());
46
+ }
47
+
48
+ TEST(Frames, collect_frame_data) {
49
+ rb_eval_string("TestMe::Snapshot::all_kinds");
50
+
51
+ int num = Frames::remove_garbage(test_frames, test_num);
52
+
53
+ vector<FrameData> data;
54
+ // Ruby 3 reports a <cfunc>, before the "take_snapshot" method
55
+ // we have to adjust the index of the trace we are checking
56
+ int i = ruby_version == 2 ? 0 : 1;
57
+ Frames::collect_frame_data(test_frames, i + 1, data);
58
+
59
+ EXPECT_EQ("take_snapshot", data[i].method) << "method name incorrect";
60
+ EXPECT_EQ("TestMe::Snapshot", data[i].klass) << "klass name incorrect";
61
+ std::size_t found = data[i].file.find("ext/oboe_metal/test/ruby_test_helper.rb");
62
+ EXPECT_EQ(data[i].file.length() - 39, found)
63
+ << "filename incorrect " << found << " " << data[i].file.length();
64
+ EXPECT_EQ(7, data[i].lineno) << "line number incorrect";
65
+ }
66
+
67
+ TEST(Frames, remove_garbage) {
68
+ // run some Ruby code and get a snapshot
69
+ rb_eval_string("TestMe::Snapshot::all_kinds");
70
+
71
+ int num = Frames::remove_garbage(test_frames, test_num);
72
+
73
+ int expected = (ruby_version == 2) ? 7 : 9;
74
+ EXPECT_EQ(expected, num)
75
+ << "wrong number of expected frames after remove_garbage";
76
+ // check no lineno 0 frame at top
77
+ VALUE val;
78
+ int i = (ruby_version == 2) ? 0 : 1;
79
+ val = rb_profile_frame_first_lineno(test_frames[i]); // returns line number
80
+ if (RB_TYPE_P(val, T_FIXNUM)) {
81
+ EXPECT_NE(0, NUM2INT(val))
82
+ << "the frame with linenumber 0 was not removed";
83
+ } else {
84
+ EXPECT_TRUE(false) << " ************ line number not an int **********";
85
+ }
86
+ // check no repeated frames
87
+ for (i = 0; i < num; i++)
88
+ for (int j = i + 1; j < num; j++)
89
+ EXPECT_NE(test_frames[i], test_frames[j])
90
+ << "not all repeated frames were removed";
91
+ }
92
+
93
+ TEST(Frames, num_matching) {
94
+ VALUE a[BUF_SIZE];
95
+ VALUE b[BUF_SIZE];
96
+
97
+ int a_num = 0;
98
+ int b_num = 0;
99
+ EXPECT_EQ(0, Frames::num_matching(a, a_num, b, b_num))
100
+ << "* empty frames array should have 0 matches";
101
+
102
+ a[0] = (VALUE)11;
103
+ a[1] = (VALUE)12;
104
+ a[2] = (VALUE)13;
105
+ b[0] = (VALUE)11;
106
+ b[1] = (VALUE)12;
107
+ b[2] = (VALUE)13;
108
+ a_num = 3;
109
+ b_num = 3;
110
+ EXPECT_EQ(3, Frames::num_matching(a, a_num, b, b_num))
111
+ << "* equal frames array should have matched";
112
+
113
+ b[1] = (VALUE)222;
114
+ EXPECT_EQ(1, Frames::num_matching(a, a_num, b, b_num))
115
+ << "* only one should match for same length but different content";
116
+
117
+ b[1] = (VALUE)12;
118
+ a[3] = 14;
119
+ a_num = 4;
120
+ EXPECT_EQ(0, Frames::num_matching(a, a_num, b, b_num))
121
+ << "* different length, frames NOT matching from the end";
122
+
123
+ a[0] = 10;
124
+ a[1] = 11;
125
+ a[2] = 12;
126
+ a[3] = 13;
127
+ EXPECT_EQ(3, Frames::num_matching(a, a_num, b, b_num))
128
+ << "* different length, frames matching from the end";
129
+
130
+ b[0] = (VALUE)18;
131
+ b[1] = (VALUE)19;
132
+ b[2] = (VALUE)11;
133
+ b[3] = (VALUE)12;
134
+ b[4] = (VALUE)13;
135
+ b_num = 5;
136
+
137
+ EXPECT_EQ(3, Frames::num_matching(a, a_num, b, b_num))
138
+ << "* different length, frames matching from the end";
139
+ }
140
+
141
+ TEST(Frames, cached_frames) {
142
+ cached_frames.clear();
143
+ // run some Ruby code and get a snapshot
144
+ rb_eval_string("TestMe::Snapshot::all_kinds");
145
+
146
+ Frames::remove_garbage(test_frames, test_num);
147
+
148
+ // Check the expected size
149
+ int expected = (ruby_version == 2) ? 8 : 10;
150
+ EXPECT_EQ(expected, cached_frames.size());
151
+
152
+ // check that each frame is cached
153
+ for (int i = 0; i < test_num; i++)
154
+ EXPECT_EQ(1, cached_frames.count(test_frames[i]));
155
+
156
+ // repeat
157
+ rb_eval_string("TestMe::Snapshot::all_kinds");
158
+ Frames::remove_garbage(test_frames, test_num);
159
+
160
+ expected = (ruby_version == 2) ? 9 : 11;
161
+ EXPECT_EQ(expected, cached_frames.size()); // +1 for an extra main frame
162
+ for (int i = 0; i < test_num; i++)
163
+ EXPECT_EQ(1, cached_frames.count(test_frames[i]));
164
+ }
@@ -0,0 +1,93 @@
1
+
2
+ #include "../src/frames.h"
3
+
4
+ #include <string.h>
5
+
6
+ #include <algorithm>
7
+ #include <thread>
8
+ #include <array>
9
+
10
+ #include "../src/profiling.h"
11
+ #include "gtest/gtest.h"
12
+ #include "ruby/debug.h"
13
+ #include "ruby/ruby.h"
14
+ #include "test.h"
15
+
16
+ extern atomic_bool profiling_shut_down;
17
+ // extern oboe_reporter_t *cur_reporter;
18
+
19
+ // FIXME how can I access profiling_shut_down ?
20
+ TEST(Profiling, try_catch_shutdown) {
21
+ EXPECT_FALSE(profiling_shut_down);
22
+
23
+ int result;
24
+ result = Profiling::try_catch_shutdown([] {
25
+ // provoke exception
26
+ std::string ().replace (100, 1, 1, 'c');
27
+ return 0;
28
+ }, "Profiling::try_catch()");
29
+
30
+ EXPECT_NE(0, result);
31
+ EXPECT_TRUE(profiling_shut_down);
32
+
33
+ // reset global var
34
+ profiling_shut_down = false;
35
+ }
36
+
37
+ TEST(Profiling, oboe_0_profiling) {
38
+ atomic_bool atomic_a1{true};
39
+ atomic_bool atomic_a2{false};
40
+
41
+ atomic_bool running;
42
+
43
+ cout << running << endl;
44
+ cout << running.exchange(true) << endl;
45
+ cout << running.exchange(true) << endl;
46
+
47
+ // cout << "prev val " << atomic_a2.exchange(false) << endl;
48
+ // cout << atomic_a2 << endl;
49
+ // cout << "prev val " << atomic_a2.exchange(true) << endl;
50
+ // cout << atomic_a2 << endl;
51
+ // cout << "prev val " << atomic_a2.exchange(true) << endl;
52
+ // cout << atomic_a2 << endl;
53
+ // cout << "prev val " << atomic_a2.exchange(false) << endl;
54
+ // cout << atomic_a2 << endl;
55
+
56
+
57
+
58
+ // static bool b1{true};
59
+ // static bool b2{false};
60
+
61
+ // array<thread, 4> threads;
62
+
63
+ // for (auto& t : threads) {
64
+ // t = thread([] { Profiling::profiler_signal_handler(0, NULL, NULL); });
65
+ // }
66
+
67
+ // cout << "waiting..." << endl;
68
+
69
+ // for (auto& t : threads) {
70
+ // t.join();
71
+ // }
72
+
73
+ // cout << "Done." << endl;
74
+
75
+
76
+ // cout << atomic_a1 << ", " << b1 << endl;
77
+ // cout << atomic_a1 << ", " << b1 << ", " << atomic_a1.compare_exchange_weak(b1, false) << endl;
78
+ // cout << atomic_a1 << ", " << b1 << endl;
79
+ // cout << atomic_a2 << ", " << b2 << endl;
80
+ // cout << atomic_a2 << ", " << b2 << ", " << atomic_a2.compare_exchange_weak(b2, true) << endl;
81
+ // cout << atomic_a2 << ", " << b2 << endl;
82
+ // cout << endl;
83
+
84
+ // cout << atomic_a1 << ", " << b1 << endl;
85
+ // cout << atomic_a1 << ", " << b1 << ", " << atomic_a1.compare_exchange_weak(b1, false) << endl;
86
+ // cout << atomic_a1 << ", " << b1 << endl;
87
+ // cout << atomic_a2 << ", " << b2 << endl;
88
+ // cout << atomic_a2 << ", " << b2 << ", " << atomic_a2.compare_exchange_weak(b2, true) << endl;
89
+ // cout << atomic_a2 << ", " << b2 << endl;
90
+ // cout << endl;
91
+
92
+
93
+ }
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2021 SolarWinds, LLC.
4
+ # All rights reserved.
5
+
6
+ require 'mkmf'
7
+ puts $topdir
8
+
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2021 SolarWinds, LLC.
4
+ # All rights reserved.
5
+
6
+ require 'mkmf'
7
+ puts CONFIG["prefix"]
8
+
@@ -0,0 +1,67 @@
1
+ class TestMe
2
+ class Snapshot
3
+
4
+ class << self
5
+ # !!! do not shift the definition of take_snapshot from line 7 !!!
6
+ # the line number is used to verify a test in frames_test.cc
7
+ def take_snapshot
8
+ # puts "getting frames ...."
9
+ begin
10
+ ::RubyCalls::get_frames
11
+ rescue => e
12
+ puts "oops, getting frames didn't work"
13
+ puts e
14
+ end
15
+ end
16
+
17
+ def all_kinds
18
+ begin
19
+ Teddy.new.sing do
20
+ take_snapshot
21
+ end
22
+ rescue => e
23
+ puts "Ruby call did not work"
24
+ puts e
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ class Teddy
31
+
32
+ attr_accessor :name
33
+
34
+ def sing
35
+ 3.times do
36
+ yodel do
37
+ html_wrap("title", "Hello") { |_html| yield }
38
+ end
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def yodel
45
+ a_proc = -> (x) { x * x; yield }
46
+ in_block(&a_proc)
47
+ end
48
+
49
+ def in_block(&block)
50
+ begin
51
+ yield 7
52
+ # puts "block called!"
53
+ rescue => e
54
+ puts "no, this should never happen"
55
+ puts e
56
+ end
57
+ end
58
+
59
+ def html_wrap(tag, text)
60
+ html = "<#{tag}>#{text}</#{tag}>"
61
+ yield html
62
+ end
63
+
64
+ end
65
+ end
66
+
67
+
@@ -0,0 +1,11 @@
1
+ #ifndef TEST_H
2
+ #define TEST_H
3
+
4
+ class RubyCallsFrames {
5
+ public:
6
+ static VALUE c_get_frames();
7
+ };
8
+
9
+ void Init_RubyCallsFrames();
10
+
11
+ #endif //TEST_H
@@ -0,0 +1,32 @@
1
+ #include "gtest/gtest.h"
2
+ // #include "gmock/gmock.h"
3
+ #include <ruby/ruby.h>
4
+ #include "../src/profiling.h"
5
+ #include "../src/frames.h"
6
+ #include "test.h"
7
+
8
+ #ifndef FRAMES_BUFFER
9
+ #define FRAMES_BUFFER
10
+
11
+ using namespace std;
12
+
13
+ int main(int argc, char **argv) {
14
+ int state = -1;
15
+
16
+ // order important! init ruby before adding functions!
17
+ ruby_init();
18
+ Init_RubyCallsFrames();
19
+
20
+ // !!! if the require path is wrong, cmake will segfault !!!
21
+ string path(std::getenv("TEST_DIR"));
22
+ string cmd("require '" + path + "/" + "ruby_test_helper.rb" + "'");
23
+ rb_eval_string(cmd.c_str());
24
+
25
+ ::testing::InitGoogleTest(&argc, argv);
26
+
27
+ state = RUN_ALL_TESTS();
28
+
29
+ ruby_cleanup(0);
30
+ return state;
31
+ }
32
+ #endif //FRAMES_BUFFER
data/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'solarwinds_apm'
data/lib/oboe.rb ADDED
@@ -0,0 +1,7 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ # This module is provided for backward compatibility.
5
+ # It simply redirects to the solarwinds_apm module which will
6
+ # also load backward compatibility support.
7
+ require 'solarwinds_apm'
data/lib/oboe_metal.rb ADDED
@@ -0,0 +1,172 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'thread'
5
+
6
+ # Disable docs and Camelcase warns since we're implementing
7
+ # an interface here. See OboeBase for details.
8
+ # rubocop:disable Style/Documentation, Naming/MethodName
9
+ module SolarWindsAPM
10
+ extend SolarWindsAPMBase
11
+ include Oboe_metal
12
+
13
+ class Reporter
14
+ class << self
15
+ ##
16
+ # start
17
+ #
18
+ # Start the SolarWindsAPM Reporter
19
+ #
20
+ def start
21
+ SolarWindsAPM.loaded = false unless SolarWindsAPM::OboeInitOptions.instance.service_key_ok?
22
+ return unless SolarWindsAPM.loaded
23
+
24
+ begin
25
+ options = SolarWindsAPM::OboeInitOptions.instance.array_for_oboe # creates an array with the options in the right order
26
+
27
+ SolarWindsAPM.reporter = Oboe_metal::Reporter.new(*options)
28
+
29
+ # Only report __Init from here if we are not instrumenting a framework.
30
+ # Otherwise, frameworks will handle reporting __Init after full initialization
31
+ unless defined?(::Rails) || defined?(::Sinatra) || defined?(::Padrino) || defined?(::Grape)
32
+ SolarWindsAPM::API.report_init
33
+ end
34
+
35
+ rescue => e
36
+ $stderr.puts e.message
37
+ raise
38
+ end
39
+ end
40
+ alias :restart :start
41
+
42
+ ##
43
+ # sendReport
44
+ #
45
+ # Send the report for the given event
46
+ #
47
+ def sendReport(evt)
48
+ SolarWindsAPM.reporter.sendReport(evt)
49
+ end
50
+
51
+ ##
52
+ # sendStatus
53
+ #
54
+ # Send the report for the given event
55
+ #
56
+ def sendStatus(evt, context = nil)
57
+ SolarWindsAPM.reporter.sendStatus(evt, context)
58
+ end
59
+
60
+ ##
61
+ # clear_all_traces
62
+ #
63
+ # Truncates the trace output file to zero
64
+ #
65
+ def clear_all_traces
66
+ File.truncate(SolarWindsAPM::OboeInitOptions.instance.host, 0)
67
+ end
68
+
69
+ ##
70
+ # get_all_traces
71
+ #
72
+ # Retrieves all traces written to the trace file
73
+ #
74
+ def get_all_traces
75
+ io = File.open(SolarWindsAPM::OboeInitOptions.instance.host, 'r')
76
+ contents = io.readlines(nil)
77
+ io.close
78
+
79
+ return contents if contents.empty?
80
+
81
+ traces = []
82
+
83
+ # We use Gem.loaded_spec because older versions of the bson
84
+ # gem didn't even have a version embedded in the gem. If the
85
+ # gem isn't in the bundle, it should rightfully error out
86
+ # anyways.
87
+ #
88
+ if Gem.loaded_specs['bson'] && Gem.loaded_specs['bson'].version.to_s < '4.0'
89
+ s = StringIO.new(contents[0])
90
+
91
+ until s.eof?
92
+ traces << if ::BSON.respond_to? :read_bson_document
93
+ BSON.read_bson_document(s)
94
+ else
95
+ BSON::Document.from_bson(s)
96
+ end
97
+ end
98
+ else
99
+ bbb = ::BSON::ByteBuffer.new(contents[0])
100
+ until bbb.length == 0
101
+ traces << Hash.from_bson(bbb)
102
+ end
103
+ end
104
+
105
+ traces
106
+ end
107
+ end
108
+ end
109
+
110
+ module EventUtil
111
+ def self.metadataString(evt)
112
+ evt.metadataString
113
+ end
114
+ end
115
+
116
+ class << self
117
+ # def sample?(opts = {})
118
+ # # Return false if no-op mode
119
+ # return false unless SolarWindsAPM.loaded
120
+ #
121
+ # # Assure defaults since SWIG enforces Strings
122
+ # xtrace = opts[:xtrace] ? opts[:xtrace].to_s.strip : SW_APM_STR_BLANK
123
+ #
124
+ # # the first arg has changed to be the service name, blank means to use the default (from the service key)
125
+ # rv = SolarWindsAPM::Context.sampleRequest(SW_APM_STR_BLANK, xtrace)
126
+ #
127
+ # if rv == 0
128
+ # SolarWindsAPM.sample_rate = -1
129
+ # SolarWindsAPM.sample_source = -1
130
+ # false
131
+ # else
132
+ # # liboboe version > 1.3.1 returning a bit masked integer with SampleRate and
133
+ # # source embedded
134
+ # SolarWindsAPM.sample_rate = (rv & SAMPLE_RATE_MASK)
135
+ # SolarWindsAPM.sample_source = (rv & SAMPLE_SOURCE_MASK) >> 24
136
+ # true
137
+ # end
138
+ # rescue StandardError => e
139
+ # SolarWindsAPM.logger.debug "[oboe/error] sample? error: #{e.inspect}"
140
+ # false
141
+ # end
142
+
143
+ # def set_tracing_mode(mode)
144
+ # return unless SolarWindsAPM.loaded
145
+ #
146
+ # value = mode.to_sym
147
+ #
148
+ # case value
149
+ # when :disabled, :never
150
+ # SolarWindsAPM::Context.setTracingMode(SW_APM_TRACE_DISABLED)
151
+ #
152
+ # when :enabled, :always
153
+ # SolarWindsAPM::Context.setTracingMode(SW_APM_TRACE_ENABLED)
154
+ #
155
+ # else
156
+ # SolarWindsAPM.logger.fatal "[oboe/error] Invalid tracing mode set: #{mode}"
157
+ # SolarWindsAPM::Context.setTracingMode(SW_APM_TRACE_DISABLED)
158
+ # end
159
+ # end
160
+
161
+ def set_sample_rate(rate)
162
+ return unless SolarWindsAPM.loaded
163
+
164
+ # Update liboboe with the new SampleRate value
165
+ SolarWindsAPM::Context.setDefaultSampleRate(rate.to_i)
166
+ end
167
+ end
168
+ end
169
+ # rubocop:enable Style/Documentation
170
+
171
+ SolarWindsAPM.loaded = true
172
+ SolarWindsAPM.config_lock = Mutex.new
@@ -0,0 +1,47 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module SolarWindsAPM
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ source_root File.join(File.dirname(__FILE__), 'templates')
7
+ desc "Copies a SolarWindsAPM gem initializer file to your application."
8
+
9
+ @namespace = "solarwinds_apm:install"
10
+
11
+ def copy_initializer
12
+ # Set defaults
13
+ @verbose = 'false'
14
+
15
+ print_header
16
+ print_footer
17
+
18
+ template "solarwinds_apm_initializer.rb", "config/initializers/solarwinds_apm.rb"
19
+ end
20
+
21
+ private
22
+
23
+ # rubocop:disable Metrics/MethodLength
24
+ def print_header
25
+ say ""
26
+ say shell.set_color "Welcome to the SolarWindsAPM Ruby instrumentation setup.", :green, :bold
27
+ say ""
28
+ say shell.set_color "Documentation Links", :magenta
29
+ say "-------------------"
30
+ say ""
31
+ say "SolarWindsAPM Installation Overview:"
32
+ say "https://documentation.solarwinds.com/en/success_center/swaas/"
33
+ say ""
34
+ say "More information on instrumenting Ruby applications can be found here:"
35
+ say "https://documentation.solarwinds.com/en/success_center/swaas/default.htm#cshid=app-add-ruby-agent"
36
+ end
37
+ # rubocop:enable Metrics/MethodLength
38
+
39
+ def print_footer
40
+ say ""
41
+ say "You can change configuration values in the future by modifying config/initializers/solarwinds_apm.rb"
42
+ say ""
43
+ say "Thanks! Creating the SolarWindsAPM initializer..."
44
+ say ""
45
+ end
46
+ end
47
+ end