traceview 3.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 (137) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rubocop.yml +5 -0
  4. data/.travis.yml +58 -0
  5. data/Appraisals +10 -0
  6. data/CHANGELOG.md +490 -0
  7. data/CONFIG.md +16 -0
  8. data/Gemfile +95 -0
  9. data/LICENSE +199 -0
  10. data/README.md +380 -0
  11. data/Rakefile +109 -0
  12. data/examples/DNT.md +35 -0
  13. data/examples/carrying_context.rb +225 -0
  14. data/examples/instrumenting_metal_controller.rb +8 -0
  15. data/examples/puma_on_heroku_config.rb +17 -0
  16. data/examples/tracing_async_threads.rb +125 -0
  17. data/examples/tracing_background_jobs.rb +52 -0
  18. data/examples/tracing_forked_processes.rb +100 -0
  19. data/examples/unicorn_on_heroku_config.rb +28 -0
  20. data/ext/oboe_metal/extconf.rb +61 -0
  21. data/ext/oboe_metal/noop/noop.c +7 -0
  22. data/ext/oboe_metal/src/bson/bson.h +221 -0
  23. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  24. data/ext/oboe_metal/src/oboe.h +275 -0
  25. data/ext/oboe_metal/src/oboe.hpp +352 -0
  26. data/ext/oboe_metal/src/oboe_wrap.cxx +3886 -0
  27. data/ext/oboe_metal/tests/test.rb +11 -0
  28. data/gemfiles/mongo.gemfile +33 -0
  29. data/gemfiles/moped.gemfile +33 -0
  30. data/get_version.rb +5 -0
  31. data/init.rb +4 -0
  32. data/lib/joboe_metal.rb +206 -0
  33. data/lib/oboe.rb +7 -0
  34. data/lib/oboe/README +2 -0
  35. data/lib/oboe/backward_compatibility.rb +59 -0
  36. data/lib/oboe/inst/rack.rb +11 -0
  37. data/lib/oboe_metal.rb +151 -0
  38. data/lib/rails/generators/traceview/install_generator.rb +76 -0
  39. data/lib/rails/generators/traceview/templates/traceview_initializer.rb +159 -0
  40. data/lib/traceview.rb +62 -0
  41. data/lib/traceview/api.rb +18 -0
  42. data/lib/traceview/api/layerinit.rb +51 -0
  43. data/lib/traceview/api/logging.rb +209 -0
  44. data/lib/traceview/api/memcache.rb +31 -0
  45. data/lib/traceview/api/profiling.rb +50 -0
  46. data/lib/traceview/api/tracing.rb +135 -0
  47. data/lib/traceview/api/util.rb +121 -0
  48. data/lib/traceview/base.rb +225 -0
  49. data/lib/traceview/config.rb +238 -0
  50. data/lib/traceview/frameworks/grape.rb +97 -0
  51. data/lib/traceview/frameworks/padrino.rb +64 -0
  52. data/lib/traceview/frameworks/padrino/templates.rb +58 -0
  53. data/lib/traceview/frameworks/rails.rb +145 -0
  54. data/lib/traceview/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
  55. data/lib/traceview/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
  56. data/lib/traceview/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
  57. data/lib/traceview/frameworks/rails/inst/action_controller.rb +216 -0
  58. data/lib/traceview/frameworks/rails/inst/action_view.rb +56 -0
  59. data/lib/traceview/frameworks/rails/inst/action_view_2x.rb +54 -0
  60. data/lib/traceview/frameworks/rails/inst/action_view_30.rb +48 -0
  61. data/lib/traceview/frameworks/rails/inst/active_record.rb +24 -0
  62. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  63. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  64. data/lib/traceview/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
  65. data/lib/traceview/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  66. data/lib/traceview/frameworks/rails/inst/connection_adapters/utils.rb +117 -0
  67. data/lib/traceview/frameworks/sinatra.rb +95 -0
  68. data/lib/traceview/frameworks/sinatra/templates.rb +56 -0
  69. data/lib/traceview/inst/cassandra.rb +279 -0
  70. data/lib/traceview/inst/dalli.rb +86 -0
  71. data/lib/traceview/inst/em-http-request.rb +99 -0
  72. data/lib/traceview/inst/excon.rb +111 -0
  73. data/lib/traceview/inst/faraday.rb +73 -0
  74. data/lib/traceview/inst/http.rb +87 -0
  75. data/lib/traceview/inst/httpclient.rb +173 -0
  76. data/lib/traceview/inst/memcache.rb +102 -0
  77. data/lib/traceview/inst/memcached.rb +94 -0
  78. data/lib/traceview/inst/mongo.rb +238 -0
  79. data/lib/traceview/inst/moped.rb +474 -0
  80. data/lib/traceview/inst/rack.rb +122 -0
  81. data/lib/traceview/inst/redis.rb +271 -0
  82. data/lib/traceview/inst/resque.rb +192 -0
  83. data/lib/traceview/inst/rest-client.rb +38 -0
  84. data/lib/traceview/inst/sequel.rb +162 -0
  85. data/lib/traceview/inst/typhoeus.rb +102 -0
  86. data/lib/traceview/instrumentation.rb +21 -0
  87. data/lib/traceview/loading.rb +94 -0
  88. data/lib/traceview/logger.rb +41 -0
  89. data/lib/traceview/method_profiling.rb +84 -0
  90. data/lib/traceview/ruby.rb +36 -0
  91. data/lib/traceview/support.rb +113 -0
  92. data/lib/traceview/thread_local.rb +26 -0
  93. data/lib/traceview/util.rb +250 -0
  94. data/lib/traceview/version.rb +16 -0
  95. data/lib/traceview/xtrace.rb +90 -0
  96. data/test/frameworks/apps/grape_nested.rb +30 -0
  97. data/test/frameworks/apps/grape_simple.rb +24 -0
  98. data/test/frameworks/apps/padrino_simple.rb +45 -0
  99. data/test/frameworks/apps/sinatra_simple.rb +24 -0
  100. data/test/frameworks/grape_test.rb +142 -0
  101. data/test/frameworks/padrino_test.rb +30 -0
  102. data/test/frameworks/sinatra_test.rb +30 -0
  103. data/test/instrumentation/cassandra_test.rb +380 -0
  104. data/test/instrumentation/dalli_test.rb +171 -0
  105. data/test/instrumentation/em_http_request_test.rb +86 -0
  106. data/test/instrumentation/excon_test.rb +207 -0
  107. data/test/instrumentation/faraday_test.rb +235 -0
  108. data/test/instrumentation/http_test.rb +140 -0
  109. data/test/instrumentation/httpclient_test.rb +296 -0
  110. data/test/instrumentation/memcache_test.rb +251 -0
  111. data/test/instrumentation/memcached_test.rb +226 -0
  112. data/test/instrumentation/mongo_test.rb +462 -0
  113. data/test/instrumentation/moped_test.rb +496 -0
  114. data/test/instrumentation/rack_test.rb +116 -0
  115. data/test/instrumentation/redis_hashes_test.rb +265 -0
  116. data/test/instrumentation/redis_keys_test.rb +318 -0
  117. data/test/instrumentation/redis_lists_test.rb +310 -0
  118. data/test/instrumentation/redis_misc_test.rb +160 -0
  119. data/test/instrumentation/redis_sets_test.rb +293 -0
  120. data/test/instrumentation/redis_sortedsets_test.rb +325 -0
  121. data/test/instrumentation/redis_strings_test.rb +333 -0
  122. data/test/instrumentation/resque_test.rb +62 -0
  123. data/test/instrumentation/rest-client_test.rb +294 -0
  124. data/test/instrumentation/sequel_mysql2_test.rb +326 -0
  125. data/test/instrumentation/sequel_mysql_test.rb +326 -0
  126. data/test/instrumentation/sequel_pg_test.rb +330 -0
  127. data/test/instrumentation/typhoeus_test.rb +285 -0
  128. data/test/minitest_helper.rb +187 -0
  129. data/test/profiling/method_test.rb +198 -0
  130. data/test/servers/rackapp_8101.rb +22 -0
  131. data/test/support/backcompat_test.rb +269 -0
  132. data/test/support/config_test.rb +128 -0
  133. data/test/support/dnt_test.rb +73 -0
  134. data/test/support/liboboe_settings_test.rb +104 -0
  135. data/test/support/xtrace_test.rb +35 -0
  136. data/traceview.gemspec +29 -0
  137. metadata +250 -0
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2015 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module RestClientRequest
7
+ def self.included(klass)
8
+ ::TraceView::Util.method_alias(klass, :execute, ::RestClient::Request)
9
+ end
10
+
11
+ ##
12
+ # execute_with_traceview
13
+ #
14
+ # The wrapper method for RestClient::Request.execute
15
+ #
16
+ def execute_with_traceview & block
17
+ kvs = {}
18
+ kvs['Backtrace'] = TraceView::API.backtrace if TraceView::Config[:rest_client][:collect_backtraces]
19
+ TraceView::API.log_entry("rest-client", kvs)
20
+
21
+ # The core rest-client call
22
+ execute_without_traceview(&block)
23
+ rescue => e
24
+ TraceView::API.log_exception('rest-client', e)
25
+ raise e
26
+ ensure
27
+ TraceView::API.log_exit("rest-client")
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ if TraceView::Config[:rest_client][:enabled]
34
+ if defined?(::RestClient)
35
+ TraceView.logger.info '[traceview/loading] Instrumenting rest-client' if TraceView::Config[:verbose]
36
+ ::TraceView::Util.send_include(::RestClient::Request, ::TraceView::Inst::RestClientRequest)
37
+ end
38
+ end
@@ -0,0 +1,162 @@
1
+ # Copyright (c) 2015 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module Sequel
7
+ def extract_trace_details(sql, opts)
8
+ kvs = {}
9
+
10
+ if TraceView::Config[:sanitize_sql]
11
+ # Sanitize SQL and don't report binds
12
+ if sql.is_a?(Symbol)
13
+ kvs[:Query] = sql
14
+ else
15
+ kvs[:Query] = sql.gsub(/('[\s\S][^\']*\'|\d*\.\d*)/, '?')
16
+ end
17
+ else
18
+ # Report raw SQL and any binds if they exist
19
+ kvs[:Query] = sql.to_s
20
+ kvs[:QueryArgs] = opts[:arguments] if opts.is_a?(Hash) and opts.key?(:arguments)
21
+ end
22
+ kvs[:IsPreparedStatement] = true if sql.is_a?(Symbol)
23
+
24
+ kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:sequel][:collect_backtraces]
25
+
26
+ if ::Sequel::VERSION < '3.41.0' && !(self.class.to_s =~ /Dataset$/)
27
+ db_opts = @opts
28
+ elsif @pool
29
+ db_opts = @pool.db.opts
30
+ else
31
+ db_opts = @db.opts
32
+ end
33
+
34
+ kvs[:Database] = db_opts[:database]
35
+ kvs[:RemoteHost] = db_opts[:host]
36
+ kvs[:RemotePort] = db_opts[:port] if db_opts.key?(:port)
37
+ kvs[:Flavor] = db_opts[:adapter]
38
+ rescue => e
39
+ TraceView.logger.debug "[traceview/debug Error capturing Sequel KVs: #{e.message}" if TraceView::Config[:verbose]
40
+ ensure
41
+ return kvs
42
+ end
43
+ end
44
+
45
+ module SequelDatabase
46
+ def self.included(klass)
47
+ ::TraceView::Util.method_alias(klass, :run, ::Sequel::Database)
48
+ ::TraceView::Util.method_alias(klass, :execute_ddl, ::Sequel::Database)
49
+ ::TraceView::Util.method_alias(klass, :execute_dui, ::Sequel::Database)
50
+ ::TraceView::Util.method_alias(klass, :execute_insert, ::Sequel::Database)
51
+ end
52
+
53
+ def run_with_traceview(sql, opts=::Sequel::OPTS)
54
+ kvs = extract_trace_details(sql, opts)
55
+
56
+ TraceView::API.log_entry('sequel', kvs)
57
+
58
+ run_without_traceview(sql, opts)
59
+ rescue => e
60
+ TraceView::API.log_exception('sequel', e)
61
+ raise e
62
+ ensure
63
+ TraceView::API.log_exit('sequel')
64
+ end
65
+
66
+ def exec_with_traceview(method, sql, opts=::Sequel::OPTS, &block)
67
+ kvs = extract_trace_details(sql, opts)
68
+
69
+ TraceView::API.log_entry('sequel', kvs)
70
+
71
+ send(method, sql, opts, &block)
72
+ rescue => e
73
+ TraceView::API.log_exception('sequel', e)
74
+ raise e
75
+ ensure
76
+ TraceView::API.log_exit('sequel')
77
+ end
78
+
79
+ def execute_ddl_with_traceview(sql, opts=::Sequel::OPTS, &block)
80
+ # If we're already tracing a sequel operation, then this call likely came
81
+ # from Sequel::Dataset. In this case, just pass it on.
82
+ return execute_ddl_without_traceview(sql, opts, &block) if TraceView.tracing_layer?('sequel')
83
+
84
+ exec_with_traceview(:execute_ddl_without_traceview, sql, opts, &block)
85
+ end
86
+
87
+ def execute_dui_with_traceview(sql, opts=::Sequel::OPTS, &block)
88
+ # If we're already tracing a sequel operation, then this call likely came
89
+ # from Sequel::Dataset. In this case, just pass it on.
90
+ return execute_dui_without_traceview(sql, opts, &block) if TraceView.tracing_layer?('sequel')
91
+
92
+ exec_with_traceview(:execute_dui_without_traceview, sql, opts, &block)
93
+ end
94
+
95
+ def execute_insert_with_traceview(sql, opts=::Sequel::OPTS, &block)
96
+ # If we're already tracing a sequel operation, then this call likely came
97
+ # from Sequel::Dataset. In this case, just pass it on.
98
+ return execute_insert_without_traceview(sql, opts, &block) if TraceView.tracing_layer?('sequel')
99
+
100
+ exec_with_traceview(:execute_insert_without_traceview, sql, opts, &block)
101
+ end
102
+ end # module SequelDatabase
103
+
104
+ module SequelDataset
105
+
106
+ def self.included(klass)
107
+ ::TraceView::Util.method_alias(klass, :execute, ::Sequel::Dataset)
108
+ ::TraceView::Util.method_alias(klass, :execute_ddl, ::Sequel::Dataset)
109
+ ::TraceView::Util.method_alias(klass, :execute_dui, ::Sequel::Dataset)
110
+ ::TraceView::Util.method_alias(klass, :execute_insert, ::Sequel::Dataset)
111
+ end
112
+
113
+ def exec_with_traceview(method, sql, opts=::Sequel::OPTS, &block)
114
+ kvs = extract_trace_details(sql, opts)
115
+
116
+ TraceView::API.log_entry('sequel', kvs)
117
+
118
+ send(method, sql, opts, &block)
119
+ rescue => e
120
+ TraceView::API.log_exception('sequel', e)
121
+ raise e
122
+ ensure
123
+ TraceView::API.log_exit('sequel')
124
+ end
125
+
126
+ def execute_with_traceview(sql, opts=::Sequel::OPTS, &block)
127
+ exec_with_traceview(:execute_without_traceview, sql, opts, &block)
128
+ end
129
+
130
+ def execute_ddl_with_traceview(sql, opts=::Sequel::OPTS, &block)
131
+ exec_with_traceview(:execute_ddl_without_traceview, sql, opts, &block)
132
+ end
133
+
134
+ def execute_dui_with_traceview(sql, opts=::Sequel::OPTS, &block)
135
+ exec_with_traceview(:execute_dui_without_traceview, sql, opts, &block)
136
+ end
137
+
138
+ def execute_insert_with_traceview(sql, opts=::Sequel::OPTS, &block)
139
+ exec_with_traceview(:execute_insert_without_traceview, sql, opts, &block)
140
+ end
141
+
142
+ end # module SequelDataset
143
+ end # module Inst
144
+ end # module TraceView
145
+
146
+ if TraceView::Config[:sequel][:enabled]
147
+ if defined?(::Sequel) && ::Sequel::VERSION < "4.0.0"
148
+ # For versions before 4.0.0, Sequel::OPTS wasn't defined.
149
+ # Define it as an empty hash for backwards compatibility.
150
+ module ::Sequel
151
+ OPTS = {}
152
+ end
153
+ end
154
+
155
+ if defined?(::Sequel)
156
+ TraceView.logger.info '[traceview/loading] Instrumenting sequel' if TraceView::Config[:verbose]
157
+ ::TraceView::Util.send_include(::Sequel::Database, ::TraceView::Inst::Sequel)
158
+ ::TraceView::Util.send_include(::Sequel::Database, ::TraceView::Inst::SequelDatabase)
159
+ ::TraceView::Util.send_include(::Sequel::Dataset, ::TraceView::Inst::Sequel)
160
+ ::TraceView::Util.send_include(::Sequel::Dataset, ::TraceView::Inst::SequelDataset)
161
+ end
162
+ end
@@ -0,0 +1,102 @@
1
+ # Copyright (c) 2015 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module TyphoeusRequestOps
7
+
8
+ def self.included(klass)
9
+ ::TraceView::Util.method_alias(klass, :run, ::Typhoeus::Request::Operations)
10
+ end
11
+
12
+ def run_with_traceview
13
+ return run_without_traceview unless TraceView.tracing?
14
+
15
+ TraceView::API.log_entry('typhoeus')
16
+
17
+ # Prepare X-Trace header handling
18
+ blacklisted = TraceView::API.blacklisted?(url)
19
+ context = TraceView::Context.toString
20
+ task_id = TraceView::XTrace.task_id(context)
21
+ options[:headers]['X-Trace'] = context unless blacklisted
22
+
23
+ response = run_without_traceview
24
+
25
+ if response.code == 0
26
+ TraceView::API.log('typhoeus', 'error', { :ErrorClass => response.return_code,
27
+ :ErrorMsg => response.return_message })
28
+ end
29
+
30
+ kvs = {}
31
+ kvs['IsService'] = 1
32
+ kvs[:HTTPStatus] = response.code
33
+ kvs['Backtrace'] = TraceView::API.backtrace if TraceView::Config[:typhoeus][:collect_backtraces]
34
+
35
+ uri = URI(response.effective_url)
36
+
37
+ # Conditionally log query params
38
+ if TraceView::Config[:typhoeus][:log_args]
39
+ kvs['RemoteURL'] = uri.to_s
40
+ else
41
+ kvs['RemoteURL'] = uri.to_s.split('?').first
42
+ end
43
+
44
+ kvs['HTTPMethod'] = ::TraceView::Util.upcase(options[:method])
45
+ kvs['Blacklisted'] = true if blacklisted
46
+
47
+ # Re-attach net::http edge unless it's blacklisted or if we don't have a
48
+ # valid X-Trace header
49
+ unless blacklisted
50
+ xtrace = response.headers['X-Trace']
51
+
52
+ if xtrace && TraceView::XTrace.valid?(xtrace) && TraceView.tracing?
53
+
54
+ # Assure that we received back a valid X-Trace with the same task_id
55
+ if task_id == TraceView::XTrace.task_id(xtrace)
56
+ TraceView::Context.fromString(xtrace)
57
+ else
58
+ TraceView.logger.debug "Mismatched returned X-Trace ID: #{xtrace}"
59
+ end
60
+ end
61
+ end
62
+
63
+ TraceView::API.log('typhoeus', 'info', kvs)
64
+ response
65
+ rescue => e
66
+ TraceView::API.log_exception('typhoeus', e)
67
+ raise e
68
+ ensure
69
+ TraceView::API.log_exit('typhoeus')
70
+ end
71
+ end
72
+
73
+ module TyphoeusHydraRunnable
74
+ def self.included(klass)
75
+ ::TraceView::Util.method_alias(klass, :run, ::Typhoeus::Hydra)
76
+ end
77
+
78
+ def run_with_traceview
79
+ kvs = {}
80
+
81
+ kvs[:queued_requests] = queued_requests.count
82
+ kvs[:max_concurrency] = max_concurrency
83
+
84
+ # FIXME: Until we figure out a strategy to deal with libcurl internal
85
+ # threading and Ethon's use of easy handles, here we just do a simple
86
+ # trace of the hydra run.
87
+ TraceView::API.trace("typhoeus_hydra", kvs) do
88
+ run_without_traceview
89
+ end
90
+ end
91
+ end
92
+
93
+ end
94
+ end
95
+
96
+ if TraceView::Config[:typhoeus][:enabled]
97
+ if defined?(::Typhoeus)
98
+ TraceView.logger.info '[traceview/loading] Instrumenting typhoeus' if TraceView::Config[:verbose]
99
+ ::TraceView::Util.send_include(::Typhoeus::Request::Operations, ::TraceView::Inst::TyphoeusRequestOps)
100
+ ::TraceView::Util.send_include(::Typhoeus::Hydra, ::TraceView::Inst::TyphoeusHydraRunnable)
101
+ end
102
+ end
@@ -0,0 +1,21 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ ##
6
+ # The Inst module holds all of the instrumentation extensions for various
7
+ # libraries suchs as Redis, Dalli and Resque.
8
+ module Inst
9
+ def self.load_instrumentation
10
+ # Load the general instrumentation
11
+ pattern = File.join(File.dirname(__FILE__), 'inst', '*.rb')
12
+ Dir.glob(pattern) do |f|
13
+ begin
14
+ require f
15
+ rescue => e
16
+ TraceView.logger.error "[traceview/loading] Error loading instrumentation file '#{f}' : #{e}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,94 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'digest/sha1'
5
+
6
+ module TraceView
7
+ module Util
8
+ ##
9
+ # This module is used solely for RUM ID calculation
10
+ #
11
+ module Base64URL
12
+ module_function
13
+
14
+ def encode(bin)
15
+ c = [bin].pack('m0').gsub(/\=+\Z/, '').tr('+/', '-_').rstrip
16
+ m = c.size % 4
17
+ c += '=' * (4 - m) if m != 0
18
+ c
19
+ end
20
+
21
+ def decode(bin)
22
+ m = bin.size % 4
23
+ bin += '=' * (4 - m) if m != 0
24
+ bin.tr('-_', '+/').unpack('m0').first
25
+ end
26
+ end
27
+ end
28
+
29
+ ##
30
+ # This module houses all of the loading functionality for the traceview gem.
31
+ #
32
+ # Note that this does not necessarily _have_ to include initialization routines
33
+ # (although it can).
34
+ #
35
+ # Actual initialization is often separated out as it can be dependent on on the state
36
+ # of the stack boot process. e.g. code requiring that initializers, frameworks or
37
+ # instrumented libraries are already loaded...
38
+ #
39
+ module Loading
40
+ ##
41
+ # Load the TraceView access key (either from system configuration file
42
+ # or environment variable) and calculate internal RUM ID
43
+ #
44
+ def self.load_access_key
45
+ if ENV.key?('TRACEVIEW_CUUID')
46
+ # Preferably get access key from environment (e.g. Heroku)
47
+ TraceView::Config[:access_key] = ENV['TRACEVIEW_CUUID']
48
+ TraceView::Config[:rum_id] = TraceView::Util::Base64URL.encode(Digest::SHA1.digest('RUM' + TraceView::Config[:access_key]))
49
+ else
50
+ # ..else read from system-wide configuration file
51
+ if TraceView::Config.access_key.empty?
52
+ config_file = '/etc/tracelytics.conf'
53
+ return unless File.exist?(config_file)
54
+
55
+ File.open(config_file).each do |line|
56
+ if line =~ /^tracelyzer.access_key=/ || line =~ /^access_key/
57
+ bits = line.split(/=/)
58
+ TraceView::Config[:access_key] = bits[1].strip
59
+ TraceView::Config[:rum_id] = TraceView::Util::Base64URL.encode(Digest::SHA1.digest('RUM' + TraceView::Config[:access_key]))
60
+ break
61
+ end
62
+ end
63
+ end
64
+ end
65
+ rescue StandardError => e
66
+ TraceView.logger.error "Trouble obtaining access_key and rum_id: #{e.inspect}"
67
+ end
68
+
69
+ ##
70
+ # Load the traceview tracing API
71
+ #
72
+ def self.require_api
73
+ pattern = File.join(File.dirname(__FILE__), 'api', '*.rb')
74
+ Dir.glob(pattern) do |f|
75
+ require f
76
+ end
77
+ require 'traceview/api'
78
+
79
+ begin
80
+ TraceView::API.extend_with_tracing
81
+ rescue LoadError => e
82
+ TraceView.logger.fatal "[traceview/error] Couldn't load api: #{e.message}"
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ TraceView::Loading.require_api
89
+
90
+ # Auto-start the Reporter unless we running Unicorn on Heroku
91
+ # In that case, we start the reporters after fork
92
+ unless TraceView.heroku? && TraceView.forking_webserver?
93
+ TraceView::Reporter.start if TraceView.loaded
94
+ end
@@ -0,0 +1,41 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'logger'
5
+
6
+ module TraceView
7
+ class << self
8
+ attr_accessor :logger
9
+ end
10
+
11
+ class Logger
12
+ # Fatal message
13
+ def fatal(string, exception = nil)
14
+ TraceView.logger.fatal(string) if TraceView.logger
15
+ end
16
+
17
+ # Error message
18
+ def error(msg, exception = nil)
19
+ TraceView.logger.error(string) if TraceView.logger
20
+ end
21
+
22
+ # Warn message
23
+ def warn(msg, exception = nil)
24
+ TraceView.logger.warn(string) if TraceView.logger
25
+ end
26
+
27
+ # Info message
28
+ def info(msg, exception = nil)
29
+ TraceView.logger.info(string) if TraceView.logger
30
+ end
31
+
32
+ # Debug message
33
+ def debug(msg, exception = nil)
34
+ TraceView.logger.debug(string) if TraceView.logger
35
+ end
36
+
37
+ end
38
+ end
39
+
40
+ TraceView.logger = Logger.new(STDERR)
41
+