solarwinds_apm 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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