tcell_agent 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f2e3e8eaef2cd61c9cc3effe2b97fa731eeebecf
4
- data.tar.gz: a10e24f2d47029ade958ac9b75ebb7f287abd825
3
+ metadata.gz: 3e9ec10853e07ac321bca036627e9e98a9e8545f
4
+ data.tar.gz: b1dce50c2950629b10397802e5a6f16fa1beabc1
5
5
  SHA512:
6
- metadata.gz: e5f0910986b130a99684b68ed99fe5af1bef89f82a9a555a4dc6f233e4580d7ceeaa2b335fe02e85a79a34407d5f41202c14d5c7f3bb7151215a94e04e22e640
7
- data.tar.gz: 79176adc5b5892cafcc7da924d1f0fcbcea066af31f2615c1744117975e8eae0a2a91b56f6a32b6638c778f60e09531e703d43275558c04a8d533327a69b7dca
6
+ metadata.gz: 1506c43edb7ae723f675b4cb1e8e5d0703505941c00cde7c399d3b7c64810ce3f8f0b53744b9eb61719d79272d8676519b0183c4af124f89702d576793b2f342
7
+ data.tar.gz: fca2c0f960400a55a7f67c7e0d93465174d785b299f703271cc1ce0befc2430093f0556e570469c0a9251ac6da7aff06dba8180499d284b4a6989d0b11ab7980
@@ -124,11 +124,12 @@ module TCellAgent
124
124
  puts " ********* ********* ********* *********"
125
125
  return
126
126
  end
127
- #puts "Starting"
127
+
128
+ TCellAgent.logger.debug("Starting thread agent")
129
+
128
130
  self.ensure_policy_polling_running
129
131
  self.ensure_event_processor_running
130
- #puts "Ending"
131
132
  end
132
133
 
133
134
  end
134
- end
135
+ end
@@ -54,27 +54,14 @@ module TCellAgent
54
54
  if TCellAgent::Agent.is_parent_process? == false
55
55
  return
56
56
  end
57
+
57
58
  @events_send_empties = send_empties
58
59
  Thread.abort_on_exception = true
59
60
  @event_processor_thread = Thread.new do
61
+
60
62
  begin
61
63
  tapi = TCellApi.new
62
- begin
63
- event = TCellAgent::SensorEvents::ServerAgentDetailsSensorEvent.new
64
- TCellAgent.send_event(event)
65
- rescue Exception => te
66
- TCellAgent.logger.error("Exception sending server agent details: #{te.message}")
67
- TCellAgent.logger.debug(te.backtrace)
68
- end
69
64
 
70
- begin
71
- event = TCellAgent::SensorEvents::ServerAgentPackagesSensorEvent.new
72
- TCellAgent.send_event(event)
73
- rescue Exception => te
74
- TCellAgent.logger.error("Exception sending server agent packages: #{te.message}")
75
- TCellAgent.logger.debug(te.backtrace)
76
- end
77
- timeout_flag = false
78
65
  last_run_time = Time.now
79
66
  loop do
80
67
  begin
@@ -82,6 +69,7 @@ module TCellAgent
82
69
  now = Time.now
83
70
  wait_for = @dispatchEventsTimeout - (now - last_run_time).to_i.abs
84
71
  event = @eventQueue.pop([wait_for, 1].max)
72
+
85
73
  if event == nil
86
74
  last_run_time = Time.now
87
75
  # JJJJJJJJ JJJJJJJ JJJJJJJ JJJJJJJJ JJJJJJJJJ
@@ -151,6 +139,7 @@ module TCellAgent
151
139
  @dispatchEvents = []
152
140
  }
153
141
  end
142
+
154
143
  rescue Exception => e
155
144
  last_run_time = Time.now
156
145
  TCellAgent.logger.error("Exception while processing events: #{e.message}")
@@ -164,7 +153,9 @@ module TCellAgent
164
153
  TCellAgent.logger.error("Exception while starting processor: #{xyz.message}")
165
154
  TCellAgent.logger.debug(xyz.backtrace)
166
155
  end
156
+
167
157
  end
158
+
168
159
  end
169
160
 
170
161
  def ensure_fork_event_thread_running
@@ -201,7 +192,7 @@ module TCellAgent
201
192
  rescue Exception => e
202
193
  TCellAgent.logger.error("Exception while running (forked) events: #{e.message}")
203
194
  TCellAgent.logger.debug(e.backtrace)
204
- end
195
+ end
205
196
  end
206
197
  end
207
198
 
@@ -248,7 +239,7 @@ module TCellAgent
248
239
  rescue Exception => e
249
240
  TCellAgent.logger.error("Exception while running (forked) metrics: #{e.message}")
250
241
  TCellAgent.logger.debug(e.backtrace)
251
- end
242
+ end
252
243
  end
253
244
  end
254
245
 
@@ -271,14 +262,17 @@ module TCellAgent
271
262
  self.queue_forked_event(event)
272
263
  return
273
264
  end
265
+
274
266
  begin
275
267
  self.ensure_event_processor_running
276
268
  @event_queue_monitor.synchronize {
277
- @eventQueue.push(event)
269
+ @eventQueue.push(event, 10)
278
270
  }
279
- rescue RuntimeError => te
271
+
272
+ rescue RuntimeError
280
273
  TCellAgent.logger.debug("Dropping event because queue full")
281
274
  end
275
+
282
276
  rescue Exception => queue_exception
283
277
  TCellAgent.logger.debug("Could not add event #{queue_exception.message}")
284
278
  end
@@ -305,6 +299,5 @@ module TCellAgent
305
299
  end
306
300
  end
307
301
 
308
-
309
302
  end
310
- end
303
+ end
@@ -65,6 +65,7 @@ module TCellAgent
65
65
  end
66
66
  end
67
67
  end
68
+
68
69
  @@event_pipe_manager = ForkPipeManager.new { |event|
69
70
  begin
70
71
  TCellAgent.send_event(event)
@@ -72,7 +73,7 @@ module TCellAgent
72
73
  TCellAgent.logger.error("Could handle send_event_block")
73
74
  TCellAgent.logger.error(block_exception.message)
74
75
  TCellAgent.logger.debug(block_exception.backtrace)
75
- end
76
+ end
76
77
  }
77
78
  @@metrics_pipe_manager = ForkPipeManager.new { |val|
78
79
  begin
@@ -43,7 +43,7 @@ module TCellAgent
43
43
 
44
44
  def start_policy_polling
45
45
  if TCellAgent.configuration.fetch_policies_from_tcell == true
46
- TCellAgent.logger.debug("starting background polling thread")
46
+ TCellAgent.logger.debug("Starting policy polling thread")
47
47
  @policy_polling_thread = Thread.new do
48
48
  last_poll_time = 0
49
49
  last_run = Time.now
@@ -147,4 +147,4 @@ module TCellAgent
147
147
  end
148
148
 
149
149
  end
150
- end
150
+ end
@@ -29,7 +29,8 @@ module TCellAgent
29
29
  :base_dir,
30
30
  :cache_filename,
31
31
  :js_agent_api_base_url,
32
- :js_agent_url
32
+ :js_agent_url,
33
+ :raise_exceptions
33
34
 
34
35
  attr_accessor :exp_config_settings
35
36
 
@@ -48,6 +49,8 @@ module TCellAgent
48
49
  @event_batch_size_limit = 25
49
50
  @event_time_limit_seconds = 55
50
51
 
52
+ @raise_exceptions = false
53
+
51
54
  read_config_using_env
52
55
  read_config_from_file(filename)
53
56
 
@@ -58,11 +61,11 @@ module TCellAgent
58
61
 
59
62
  begin
60
63
  @host_identifier = (Socket.gethostname() || "localhost")
61
- rescue Exception => e
64
+ rescue Exception
62
65
  @host_identifier = "host_identifier_not_found"
63
66
  end
64
67
  @uuid = SecureRandom.uuid
65
-
68
+
66
69
  FileUtils::mkdir_p File.dirname(@cache_filename)
67
70
  if @logging_options and @logging_options["filename"]
68
71
  FileUtils::mkdir_p File.dirname(@logging_options["filename"])
@@ -70,6 +73,7 @@ module TCellAgent
70
73
  FileUtils::mkdir_p File.dirname(@default_log_filename)
71
74
  end
72
75
  end
76
+
73
77
  def read_config_using_env
74
78
  @app_id = ENV["TCELL_APP_ID"]
75
79
  @api_key = ENV["TCELL_API_KEY"]
@@ -77,11 +81,15 @@ module TCellAgent
77
81
  @tcell_api_url = ENV["TCELL_API_URL"]
78
82
  @tcell_input_url = ENV["TCELL_INPUT_URL"]
79
83
  @demomode = ENV["TCELL_DEMOMODE"] || @demomode
84
+
80
85
  if @demomode
81
86
  @event_batch_size_limit = 2
82
87
  @event_time_limit_seconds = 5
83
88
  end
89
+
90
+ @raise_exceptions = [true, "true", "yes", "1"].include?(ENV["TCELL_RAISE_EXCEPTIONS"])
84
91
  end
92
+
85
93
  def read_config_from_file(filename)
86
94
  if File.file?(filename)
87
95
  #puts "tCell.io: Loading from file"
@@ -95,7 +103,7 @@ module TCellAgent
95
103
  @app_id ||= app_data["app_id"]
96
104
  @app_id ||= app_data["name"]
97
105
  @api_key ||= app_data["api_key"]
98
-
106
+
99
107
  # Optional
100
108
  @enabled = app_data.fetch("enabled", true)
101
109
  @preload_policy_filename = app_data.fetch("preload_policy_filename", nil)
@@ -157,5 +165,7 @@ module TCellAgent
157
165
  end # filename exist
158
166
  end #def read
159
167
  end # class
168
+
160
169
  TCellAgent.configuration ||= TCellAgent::Configuration.new
161
- end
170
+
171
+ end
@@ -35,8 +35,8 @@ module TCellAgent
35
35
  @database_filters = Hash.new{|h,k| h[k] = Set.new}
36
36
  end
37
37
  def add_response_db_filter(term, action_obj, database, schema, table, field)
38
- if (term != nil and term != '')
39
- self.database_filters[term].add([database, schema, table, field, action_obj])
38
+ if (term != nil && term != '' && term.to_s.length >= 5)
39
+ self.database_filters[term.to_s].add([database, schema, table, field, action_obj])
40
40
  end
41
41
  end
42
42
  def filter_body(body)
@@ -164,4 +164,4 @@ module TCellAgent
164
164
  end
165
165
  end
166
166
  end
167
- end
167
+ end
@@ -4,7 +4,9 @@ require 'logger'
4
4
  require 'tcell_agent/configuration'
5
5
 
6
6
  module TCellAgent
7
+
7
8
  @@logger_pid = Process.pid
9
+
8
10
  def self.loggingLevelFromString(levelString)
9
11
  if (levelString == "DEBUG")
10
12
  return Logger::DEBUG
@@ -17,14 +19,18 @@ module TCellAgent
17
19
  elsif (levelString == "FATAL")
18
20
  return Logger::FATAL
19
21
  end
22
+
20
23
  return Logger::ERROR
21
24
  end
25
+
22
26
  def self.logger
23
27
  if defined?(@logger) and @logger_pid == Process.pid
24
- return @logger
28
+ return @logger
25
29
  end
30
+
26
31
  @logger_pid = Process.pid
27
32
  logging_options = TCellAgent.configuration.logging_options
33
+
28
34
  if logging_options && logging_options["enabled"]
29
35
  FileUtils.mkdir_p 'tcell/logs'
30
36
  level = loggingLevelFromString(logging_options["level"])
@@ -35,15 +41,19 @@ module TCellAgent
35
41
  @logger.formatter = proc do |severity, datetime, progname, msg|
36
42
  # ISO 8601 format
37
43
  date_format = datetime.strftime("%Y-%m-%d %H:%M:%S,%L%z")
38
- "[#{date_format}] #{severity}: #{msg}\n"
44
+ "[#{date_format}] #{severity}[#{@logger_pid}]: #{msg}\n"
39
45
  end
46
+
40
47
  return @logger
41
48
  end
49
+
42
50
  logger = Logger.new(TCellAgent.configuration.default_log_filename)
43
51
  logger.level = Logger::ERROR
44
52
  return logger
45
53
  end
54
+
46
55
  def self.logger=(logger)
47
56
  @logger = logger
48
57
  end
58
+
49
59
  end
@@ -1,126 +1,90 @@
1
1
 
2
2
  module TCellAgent
3
3
  ActiveSupport.on_load(:action_controller) do
4
- ActionController::Base.class_eval do
5
- around_filter :tell_around_filter_routes
6
- def tell_around_filter_routes
7
- begin
8
- TCellAgent::Instrumentation.safe_block("Determining Rails Route ID") {
9
- route = Rails.application.routes.router.recognize(request) { |route, _| route }.first
10
- if route
11
- route_path = route[2].path.spec
12
- tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
13
- tcell_context.route_id = TCellAgent::SensorEvents::Util.calculateRouteId(request.method.downcase, route_path)
14
- end
15
- }
16
- yield
4
+
5
+ ActionController::Base.class_eval do
6
+
7
+ around_filter :tell_around_filter_routes
8
+ def tell_around_filter_routes
9
+ begin
10
+ TCellAgent::Instrumentation.safe_block("Determining Rails Route ID") {
11
+ route = Rails.application.routes.router.recognize(request) { |r, _| r }.first
12
+
13
+ if route
14
+ route_path = route[2].path.spec
15
+ tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
16
+ tcell_context.route_id = TCellAgent::SensorEvents::Util.calculateRouteId(request.method.downcase, route_path)
17
17
  end
18
- end
18
+ }
19
+ yield
20
+ end
21
+ end
22
+
19
23
  end
20
24
  end
21
25
  end
22
26
 
23
27
  module TCellAgent
28
+
24
29
  module Instrumentation
30
+
25
31
  module Rails
26
- def self.route_path_from_route(route)
27
- if (::Rails::VERSION::MAJOR == 4)
28
- begin
29
- route_path = "#{route[2].path.spec}"
30
- if (route_path.end_with?("(.:format)"))
31
- route_path = route_path.chomp("(.:format)")
32
- end
33
- return route_path
34
- rescue Exception => inner_excetion
35
- TCellAgent.logger.debug("Could not figure out path #{inner_excetion.message}")
36
- end
37
- end
38
- nil
39
- end
40
- def self.route_from_request(rails_request)
41
- if (rails_request.env["action_dispatch.request_id"] == nil)
42
- return nil
43
- end
44
- if (::Rails::VERSION::MAJOR == 4)
45
- begin
46
- recognized = ::Rails.application.routes.router.recognize(rails_request) { |route, _| route }
47
- if recognized
48
- return recognized.first
49
- end
50
- rescue Exception => inner_excetion
51
- TCellAgent.logger.debug("Could not figure out path #{inner_excetion.message}")
32
+ METHODS = ['GET','POST','PUT','DELETE','HEAD',
33
+ 'PATCH','TRACE','CONNECT','OPTIONS']
34
+
35
+ def self.instrument_route(route)
36
+ if (route.constraints.has_key? :request_method)
37
+ route_path = "#{route.path.spec}"
38
+ if (route_path.end_with?("(.:format)"))
39
+ route_path = route_path.chomp("(.:format)")
52
40
  end
41
+
42
+ route_destination = route.defaults.to_json.to_s
43
+
44
+ route_methods = METHODS.select { |x| route.verb.match(x) }
45
+ route_methods.each { |route_method|
46
+ route_id = TCellAgent::SensorEvents::Util.calculateRouteId(route_method.downcase, route.path.spec)
47
+ TCellAgent.send_event(
48
+ TCellAgent::SensorEvents::AppRoutesSensorEvent.new(
49
+ route_path, route_method, route_id, nil, route_destination
50
+ )
51
+ )
52
+ }
53
53
  end
54
- nil
55
54
  end
56
- def self.route_id_from_request(active_request)
57
- route = route_from_request(active_request)
58
- if route != nil
59
- route_path = route_path_from_route(route)
60
- if route_path != nil
61
- return TCellAgent::SensorEvents::Util.calculateRouteId(active_request.request_method.downcase, route_path)
62
- end
55
+
56
+ def self.instrument_routes
57
+ ::Rails.application.routes.routes.each do |route|
58
+ self.instrument_route(route)
63
59
  end
64
- nil
65
- end
66
- def self.get_routes
67
60
  end
61
+
68
62
  if (::Rails::VERSION::MAJOR == 3)
69
63
  ActionDispatch::Routing::RouteSet.class_eval do
70
64
  alias_method :original_add_route, :add_route
71
65
  def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
72
- methods = ['GET','POST','PUT','DELETE','HEAD',
73
- 'PATCH','TRACE','CONNECT','OPTIONS']
74
66
  route = original_add_route(app, conditions, requirements, defaults, name, anchor)
75
- if (route.constraints.has_key? :request_method)
76
- route_path = "#{route.path.spec}"
77
- if (route_path.end_with?("(.:format)"))
78
- route_path = route_path.chomp("(.:format)")
79
- end
80
- route_destination = route.defaults.to_json.to_s
81
- route_params = route.path.required_names
82
- route_methods = methods.select {|x| route.verb.match(x) }
83
- route_methods.each { |route_method|
84
- route_id = TCellAgent::SensorEvents::Util.calculateRouteId(route_method.downcase, route.path.spec)
85
- TCellAgent.send_event(
86
- TCellAgent::SensorEvents::AppRoutesSensorEvent.new(
87
- route_path, route_method, route_id, nil, route_destination
88
- )
89
- )
90
- }
91
- end
67
+
68
+ TCellAgent::Instrumentation::Rails.instrument_route(route)
69
+
92
70
  route
93
71
  end
94
72
  end
95
73
  end
74
+
96
75
  if (::Rails::VERSION::MAJOR == 4)
97
76
  ActionDispatch::Journey::Routes.class_eval do
98
77
  alias_method :original_add_route, :add_route
99
78
  def add_route(app, path, conditions, defaults, name = nil)
100
- methods = ['GET','POST','PUT','DELETE','HEAD',
101
- 'PATCH','TRACE','CONNECT','OPTIONS']
102
- route = original_add_route(app, path, conditions, defaults, name)
103
- if (route.constraints.has_key? :request_method)
104
- route_path = "#{route.path.spec}"
105
- if (route_path.end_with?("(.:format)"))
106
- route_path = route_path.chomp("(.:format)")
107
- end
108
- route_destination = route.defaults.to_json.to_s
109
- route_params = route.path.required_names
110
- route_methods = methods.select {|x| route.verb.match(x) }
111
- route_methods.each { |route_method|
112
- route_id = TCellAgent::SensorEvents::Util.calculateRouteId(route_method.downcase, route.path.spec)
113
- TCellAgent.send_event(
114
- TCellAgent::SensorEvents::AppRoutesSensorEvent.new(
115
- route_path, route_method, route_id, nil, route_destination
116
- )
117
- )
118
- }
119
- end
79
+ route = original_add_route(app, path, conditions, defaults, name)
80
+
81
+ TCellAgent::Instrumentation::Rails.instrument_route(route)
82
+
120
83
  route
121
84
  end
122
85
  end
123
- end #endif rails version = 4
86
+ end
87
+
124
88
  end
125
89
  end
126
- end
90
+ end
@@ -0,0 +1,59 @@
1
+ unless Puma.cli_config.options[:preload_app]
2
+ # this ensures instrumentation runs for preload_app = false.
3
+ # Instrumentation will run for each worker but there's
4
+ # nothing we can do about that (Unicorn's preload_app behaves the same way)
5
+ Puma::Server.class_eval do
6
+
7
+ alias_method :original_run, :run
8
+ def run(background=true)
9
+ TCellAgent.run_instrumentation("Puma Cluster Mode (Worker)")
10
+
11
+ original_run(background)
12
+ end
13
+
14
+ end
15
+
16
+
17
+ else
18
+
19
+ if Puma.cli_config.options[:workers] == 0
20
+ # Puma is running in single mode, so run both the initial instrumentation and
21
+ # start the agent
22
+ Puma::Runner.class_eval do
23
+
24
+ alias_method :original_start_server, :start_server
25
+ def start_server
26
+ TCellAgent.run_instrumentation("Puma Single Mode")
27
+
28
+ original_start_server
29
+ end
30
+
31
+ end
32
+
33
+ else
34
+
35
+ # Runs initial instrumentation only once on the master process
36
+ puma_server_starting = Proc.new { TCellAgent.run_instrumentation("Puma Cluster Mode") }
37
+ Puma.cli_config.options[:before_fork].push(puma_server_starting)
38
+
39
+ # Each puma worker still needs the agent started but no need to run
40
+ # initial instrumentation again
41
+ Puma::Server.class_eval do
42
+
43
+ alias_method :original_run, :run
44
+ def run(background=true)
45
+ begin
46
+ TCellAgent.logger.debug("Instrumenting: Puma Cluster Mode (Worker)")
47
+ TCellAgent.thread_agent.start
48
+ rescue Exception => e
49
+ TCellAgent.logger.error("Could not start thread agent. #{e.message}")
50
+ end
51
+
52
+ original_run(background)
53
+ end
54
+
55
+ end
56
+ end
57
+
58
+ end
59
+
@@ -0,0 +1,20 @@
1
+ # This file gets included when the web server is launched through
2
+ # `bundle exec rails s` command. The appropriate server will be
3
+ # launched through Rack::Server interface
4
+
5
+ require("tcell_agent/servers/unicorn") if defined?(Unicorn::HttpServer)
6
+ require("tcell_agent/servers/webrick") if defined?(Rack::Handler::WEBrick)
7
+ require("tcell_agent/servers/thin") if defined?(Thin::Server)
8
+
9
+ if defined?(Puma::Server)
10
+ Puma::Server.class_eval do
11
+
12
+ alias_method :original_run, :run
13
+ def run(background=true)
14
+ TCellAgent.run_instrumentation("Puma Single Mode")
15
+
16
+ original_run(background)
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ Thin::Server.class_eval do
2
+
3
+ alias_method :original_start, :start
4
+ def start
5
+ TCellAgent.run_instrumentation("Thin Server")
6
+
7
+ original_start
8
+ end
9
+
10
+ end
@@ -0,0 +1,27 @@
1
+ # this ensures instrumentation runs for both preload_app = true and preload_app = false
2
+ # when preload_app = false, instrumentation will run for each worker but there's
3
+ # nothing we can do about that (Puma's preload_app behaves the same way)
4
+ TCellAgent.run_instrumentation("Unicorn")
5
+
6
+ Unicorn::HttpServer.class_eval do
7
+
8
+ # this only runs when preload_app=true because when preload_app=false
9
+ # the gems aren't loaded early enough for tcell to override
10
+ # the class definitions
11
+ alias original_init_worker_process init_worker_process
12
+ def init_worker_process(work)
13
+ start_process = original_init_worker_process(work)
14
+
15
+ begin
16
+ TCellAgent.thread_agent.policy_polling_worker_mutex = Mutex.new
17
+ TCellAgent.thread_agent.policy_polling_thread = nil
18
+ TCellAgent.thread_agent.start
19
+
20
+ rescue Exception => e
21
+ TCellAgent.logger.error("Could not start thread agent. #{e.message}")
22
+ end
23
+
24
+ start_process
25
+ end
26
+
27
+ end
@@ -0,0 +1,13 @@
1
+ Rack::Handler::WEBrick.class_eval do
2
+
3
+ class << self
4
+ alias_method :original_run, :run
5
+ def run(app, options={})
6
+ TCellAgent.run_instrumentation("WEBrick")
7
+
8
+ original_run(app, options)
9
+ end
10
+ end
11
+
12
+ end
13
+
@@ -6,101 +6,89 @@ require 'tcell_agent/configuration'
6
6
  require 'thread'
7
7
 
8
8
  module TCellAgent
9
- def self.run_instrumentation
10
- TCellAgent.logger.debug("Instrumenting")
9
+
10
+ def self.load_route_instrumentation
11
11
  if (TCellAgent.configuration.enabled && TCellAgent.configuration.instrument_for_events)
12
- require 'tcell_agent/rails' if defined?(Rails)
13
- require 'tcell_agent/sinatra' if defined?(Sinatra)
12
+ require 'tcell_agent/rails' if defined?(Rails)
13
+ require 'tcell_agent/sinatra' if defined?(Sinatra)
14
14
  end
15
15
  end
16
- end
17
16
 
18
- # creates a fork and pipes a string from parent to child
19
- if File.basename($0) != 'rake'
20
- tcell_server = ENV["TCELL_AGENT_SERVER"]
21
- if tcell_server == nil
22
- if (File.basename($0) == 'rails' &&
23
- Rack::Handler.default &&
24
- ((defined?(Thin) && (Rack::Handler.default == Rack::Handler::Thin)) ||
25
- (defined?(WEBrick) && (Rack::Handler.default == Rack::Handler::WEBrick))))
26
- tcell_server = "thin"
27
- elsif defined?(Puma) && defined?(Puma.cli_config) && Puma.cli_config.options[:workers] > 1
28
- tcell_server = "puma"
29
- elsif defined?(Unicorn)
30
- tcell_server = "unicorn"
31
- elsif defined?(Puma)
32
- tcell_server = "thin"
33
- else
34
- puts "[tCell.io] **********************************************************************"
35
- puts "[tCell.io] Server used to launch rails not recognized."
36
- puts "[tCell.io] You can override this with the env variable"
37
- puts "[tCell.io] TCELL_AGENT_SERVER=thin|puma|unicorn"
38
- puts "[tCell.io] **********************************************************************"
17
+ def self.run_instrumentation(server_name)
18
+ self.load_route_instrumentation
19
+
20
+ begin
21
+ TCellAgent.logger.debug("Instrumenting: #{server_name}")
22
+ TCellAgent.thread_agent.start
23
+ rescue Exception => e
24
+ TCellAgent.logger.error("Could not start thread agent. #{e.message}")
39
25
  end
40
- end
41
- if tcell_server != nil
42
- if (tcell_server == "mock")
43
- elsif (tcell_server == "thin" || tcell_server == "webrick")
44
- TCellAgent.run_instrumentation
45
- TCellAgent.logger.debug("Initializing background thread: Thin or webrick")
26
+
27
+ Thread.abort_on_exception = TCellAgent.configuration.raise_exceptions
28
+ Thread.new do
46
29
  begin
47
- TCellAgent.thread_agent.start
48
- rescue Exception => e
49
- TCellAgent.logger.error("Could not start worker.", e.message)
30
+ event = TCellAgent::SensorEvents::ServerAgentDetailsSensorEvent.new
31
+ TCellAgent.send_event(event)
32
+
33
+ rescue Exception => te
34
+ TCellAgent.logger.error("Exception sending server agent details: #{te.message}")
35
+ TCellAgent.logger.debug(te.backtrace)
50
36
  end
51
- elsif (tcell_server == "puma")
52
- TCellAgent.run_instrumentation
53
- TCellAgent.logger.debug("Initializing background thread: Puma Preload")
37
+
54
38
  begin
55
- TCellAgent.thread_agent.start
56
- rescue Exception => e
57
- TCellAgent.logger.error("Could not start worker.", e.message)
39
+ event = TCellAgent::SensorEvents::ServerAgentPackagesSensorEvent.new
40
+ TCellAgent.send_event(event)
41
+ rescue Exception => te
42
+ TCellAgent.logger.error("Exception sending server agent packages: #{te.message}")
43
+ TCellAgent.logger.debug(te.backtrace)
58
44
  end
59
- # preload app
60
- puma_worker_start = Proc.new do
45
+
46
+ if (TCellAgent.configuration.enabled && TCellAgent.configuration.instrument_for_events)
61
47
  begin
62
- TCellAgent.thread_agent.start
48
+ TCellAgent::Instrumentation::Rails.instrument_routes if defined?(Rails)
49
+
63
50
  rescue Exception => e
64
- TCellAgent.logger.error("Could not start worker." + e.message)
65
- end
66
- end
67
- Puma.cli_config.options[:before_worker_boot].push(puma_worker_start)
68
- elsif (tcell_server == "unicorn")
69
- TCellAgent.run_instrumentation
70
- TCellAgent.logger.debug("Initializing background thread: Unicorn")
71
- begin
72
- TCellAgent.thread_agent.start
73
- rescue Exception => e
74
- TCellAgent.logger.error("Could not start worker.", e.message)
75
- end
76
- class Unicorn::HttpServer
77
- alias _tcell_start spawn_missing_workers
78
- def spawn_missing_workers
79
- TCellAgent.logger.debug("Stopping (pre-spawn) agent " + Process.pid.to_s)
80
- return _tcell_start
81
- end
82
- alias old_init_worker_process init_worker_process
83
- def init_worker_process(work)
84
- start_process = old_init_worker_process(work)
85
- begin
86
- TCellAgent.logger.debug("Starting (post-spawn) agent " + Process.pid.to_s)
87
- TCellAgent.thread_agent.policy_polling_worker_mutex = Mutex.new
88
- TCellAgent.thread_agent.policy_polling_thread = nil
89
- TCellAgent.thread_agent.start
90
- rescue Exception => e
91
- TCellAgent.logger.error("Could not start worker.")
92
- end
93
- start_process
51
+ if TCellAgent.configuration.raise_exceptions
52
+ raise e
53
+
54
+ else
55
+ TCellAgent.logger.error("Something went wrong instrumenting the routes")
56
+ TCellAgent.logger.debug(e.inspect)
57
+ TCellAgent.logger.debug(e.backtrace)
58
+ end
94
59
  end
95
60
  end
96
- else
97
- puts "[tCell.io] **********************************************************************"
98
- puts "[tCell.io] Unknown Server for starting rails: #{tcell_server}"
99
- puts "[tCell.io] You can override this with the env variable"
100
- puts "[tCell.io] TCELL_AGENT_SERVER=thin|puma|unicorn"
101
- puts "[tCell.io] **********************************************************************"
102
61
  end
62
+
103
63
  end
64
+
104
65
  end
105
66
 
67
+ tcell_server = ENV["TCELL_AGENT_SERVER"]
68
+
69
+ if (!(tcell_server && tcell_server == "mock"))
70
+
71
+ if (tcell_server && tcell_server == "webrick") || defined?(Rails::Server)
72
+
73
+ require("tcell_agent/servers/rails_server")
74
+
75
+ elsif (tcell_server && tcell_server == "thin") || defined?(Thin)
106
76
 
77
+ require("tcell_agent/servers/thin")
78
+
79
+ elsif (tcell_server && tcell_server == "puma") || defined?(Puma)
80
+
81
+ require("tcell_agent/servers/puma")
82
+
83
+ elsif (tcell_server && tcell_server == "unicorn") || defined?(Unicorn)
84
+
85
+ require("tcell_agent/servers/unicorn")
86
+
87
+ else
88
+ puts "[tCell.io] **********************************************************************"
89
+ puts "[tCell.io] Server used to launch rails not recognized."
90
+ puts "[tCell.io] You can override this with the env variable"
91
+ puts "[tCell.io] TCELL_AGENT_SERVER=thin|puma|unicorn"
92
+ puts "[tCell.io] **********************************************************************"
93
+ end
94
+ end
@@ -5,7 +5,9 @@ require 'thread'
5
5
  require 'logger'
6
6
 
7
7
  module TCellAgent
8
+
8
9
  class BoundedQueue
10
+
9
11
  def initialize(max_size = :infinite)
10
12
  @lock = Mutex.new
11
13
  @items = []
@@ -18,6 +20,7 @@ module TCellAgent
18
20
  timeout_policy ||= -> do
19
21
  raise "Push timed out"
20
22
  end
23
+
21
24
  wait_for_condition(
22
25
  @space_available,
23
26
  ->{!full?},
@@ -35,8 +38,12 @@ module TCellAgent
35
38
  @item_available,
36
39
  ->{@items.any?},
37
40
  timeout,
38
- timeout_policy) do
39
- @items.shift
41
+ timeout_policy) do
42
+
43
+ item = @items.shift
44
+ @space_available.signal
45
+
46
+ item
40
47
  end
41
48
  end
42
49
 
@@ -45,43 +52,56 @@ module TCellAgent
45
52
  @max_size <= @items.size
46
53
  end
47
54
 
55
+ def size
56
+ @items.size
57
+ end
58
+
48
59
  private
49
60
 
50
- def wait_for_condition(
51
- cv, condition_predicate, timeout=:never, timeout_policy=->{nil})
61
+ def wait_for_condition(cv, condition_predicate, timeout=:never, timeout_policy=->{nil})
62
+
52
63
  deadline = timeout == :never ? :never : Time.now + timeout
64
+
53
65
  @lock.synchronize do
66
+
54
67
  loop do
55
68
  cv_timeout = timeout == :never ? nil : deadline - Time.now
69
+
56
70
  if !condition_predicate.call && cv_timeout.to_f >= 0
57
- cv.wait(@lock, cv_timeout)
71
+ cv.wait(@lock, cv_timeout)
58
72
  end
73
+
59
74
  if condition_predicate.call
60
75
  return yield
76
+
61
77
  elsif deadline == :never || deadline > Time.now
62
78
  next
79
+
63
80
  else
64
81
  return timeout_policy.call
65
82
  end
66
83
  end
84
+
67
85
  end
68
86
  end
69
87
  end
70
88
 
71
89
  class QueueWithTimeout
90
+
72
91
  def initialize
73
92
  @mutex = Mutex.new
74
93
  @queue = []
75
94
  @response_time_table = {}
76
95
  @recieved = ConditionVariable.new
77
96
  end
78
-
97
+
79
98
  def <<(x)
80
99
  @mutex.synchronize do
81
100
  @queue << x
82
101
  @recieved.signal
83
102
  end
84
103
  end
104
+
85
105
  def add_response_time(route_id, response_time)
86
106
  @mutex.synchronize do
87
107
  if (route_id == nil || route_id == "")
@@ -94,21 +114,25 @@ module TCellAgent
94
114
  @response_time_table[route_id]["t"] = ((@response_time_table[route_id].fetch("t",0)*(@response_time_table[route_id]["c"]-1)) + response_time) / @response_time_table[route_id]["c"]
95
115
  end
96
116
  end
117
+
97
118
  def length
98
119
  return @queue.length
99
120
  end
121
+
100
122
  def get_response_time_table
101
123
  return @response_time_table
102
124
  end
125
+
103
126
  def reset_response_time_table
104
127
  @mutex.synchronize do
105
128
  @response_time_table = {}
106
129
  end
107
130
  end
131
+
108
132
  def pop(non_block = false)
109
133
  pop_with_timeout(non_block ? 0 : nil)
110
134
  end
111
-
135
+
112
136
  def pop_with_timeout(timeout = nil)
113
137
  @mutex.synchronize do
114
138
  if @queue.empty?
@@ -121,4 +145,4 @@ module TCellAgent
121
145
  end
122
146
  end
123
147
  end
124
- end
148
+ end
@@ -1,5 +1,5 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
2
 
3
3
  module TCellAgent
4
- VERSION = "0.2.5"
4
+ VERSION = "0.2.6"
5
5
  end
@@ -127,6 +127,8 @@ module TCellAgent
127
127
  context.add_response_db_filter("tim123123my", action, "don", "sam", "tim", "fred")
128
128
  context.add_response_db_filter("ti21312mmy", action, "don", "sam", "tim", "fred")
129
129
  context.add_response_db_filter("ti123123mmy", action, "don", "sam", "tim", "fred")
130
+ context.add_response_db_filter(10233234, action, "don", "sam", "tim", "fred")
131
+ context.add_response_db_filter(true, action, "don", "sam", "tim", "fred")
130
132
  body = "this is about timmy1 3123123."
131
133
  TCellAgent.empty_event_queue
132
134
  context.filter_body(body)
@@ -146,6 +148,8 @@ module TCellAgent
146
148
  context.add_response_db_filter("tim123123my", action, "don", "sam", "tim", "fred")
147
149
  context.add_response_db_filter("ti21312mmy", action, "don", "sam", "tim", "fred")
148
150
  context.add_response_db_filter("ti123123mmy", action, "don", "sam", "tim", "fred")
151
+ context.add_response_db_filter(10233234, action, "don", "sam", "tim", "fred")
152
+ context.add_response_db_filter(true, action, "don", "sam", "tim", "fred")
149
153
  body = "this is about timmy1 3123123."
150
154
  TCellAgent.empty_event_queue
151
155
  context.filter_body(body)
@@ -167,6 +171,8 @@ module TCellAgent
167
171
  context.add_response_db_filter("tim123123my", action, "don", "sam", "tim", "fred")
168
172
  context.add_response_db_filter("ti21312mmy", action, "don", "sam", "tim", "fred")
169
173
  context.add_response_db_filter("ti123123mmy", action, "don", "sam", "tim", "fred")
174
+ context.add_response_db_filter(10233234, action, "don", "sam", "tim", "fred")
175
+ context.add_response_db_filter(true, action, "don", "sam", "tim", "fred")
170
176
  body = "this is about timmy1 3123123."
171
177
  TCellAgent.empty_event_queue
172
178
  context.filter_log(body)
@@ -186,6 +192,8 @@ module TCellAgent
186
192
  context.add_response_db_filter("tim123123my", action, "don", "sam", "tim", "fred")
187
193
  context.add_response_db_filter("ti21312mmy", action, "don", "sam", "tim", "fred")
188
194
  context.add_response_db_filter("ti123123mmy", action, "don", "sam", "tim", "fred")
195
+ context.add_response_db_filter(10233234, action, "don", "sam", "tim", "fred")
196
+ context.add_response_db_filter(true, action, "don", "sam", "tim", "fred")
189
197
  body = "this is about timmy1 3123123."
190
198
  TCellAgent.empty_event_queue
191
199
  context.filter_log(body)
@@ -195,4 +203,4 @@ module TCellAgent
195
203
  end
196
204
  end
197
205
  end
198
- end
206
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe TCellAgent::BoundedQueue do
4
+
5
+ describe "#full?" do
6
+ it "should be true when the queue is full" do
7
+ queue = TCellAgent::BoundedQueue.new(1)
8
+ queue.push("one")
9
+ expect(queue.full?).to eq(true)
10
+ end
11
+
12
+ it "should return false when the queue is not full" do
13
+ queue = TCellAgent::BoundedQueue.new(1)
14
+ expect(queue.full?).to eq(false)
15
+ end
16
+ end
17
+
18
+ describe "#push" do
19
+ context "pushing to a queue with space available" do
20
+ it "should push the item" do
21
+ queue = TCellAgent::BoundedQueue.new(1)
22
+ queue.push("one")
23
+
24
+ expect(queue.size).to eq(1)
25
+ end
26
+ end
27
+
28
+ context "pushing to a full queue" do
29
+ it "should not be possible to push anymore items" do
30
+ queue = TCellAgent::BoundedQueue.new(1)
31
+ queue.push("one")
32
+
33
+ expect(queue.size).to eq(1)
34
+ expect(queue.full?).to eq(true)
35
+
36
+ expect {
37
+ queue.push("two", 0.1)
38
+ }.to raise_error(RuntimeError)
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ describe "#pop" do
45
+ context "popping from an empty queue" do
46
+ it "should return nil when there are no items" do
47
+ queue = TCellAgent::BoundedQueue.new(1)
48
+ expect(queue.size).to eq(0)
49
+
50
+ expect(queue.pop(0.1)).to eq(nil)
51
+ end
52
+ end
53
+ end
54
+
55
+ end
data/spec/spec_helper.rb CHANGED
@@ -21,4 +21,4 @@ module TCellAgent
21
21
  end
22
22
  end
23
23
 
24
- TCellAgent.run_instrumentation
24
+ TCellAgent.load_route_instrumentation
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tcell_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garrett
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-20 00:00:00.000000000 Z
11
+ date: 2016-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -117,20 +117,24 @@ executables:
117
117
  extensions: []
118
118
  extra_rdoc_files: []
119
119
  files:
120
+ - LICENSE
121
+ - README.md
120
122
  - Rakefile
123
+ - bin/tcell_agent
124
+ - lib/tcell_agent.rb
125
+ - lib/tcell_agent/agent.rb
121
126
  - lib/tcell_agent/agent/event_processor.rb
122
127
  - lib/tcell_agent/agent/fork_pipe_manager.rb
123
128
  - lib/tcell_agent/agent/policy_manager.rb
124
129
  - lib/tcell_agent/agent/policy_types.rb
125
130
  - lib/tcell_agent/agent/route_manager.rb
126
131
  - lib/tcell_agent/agent/static_agent.rb
127
- - lib/tcell_agent/agent.rb
128
132
  - lib/tcell_agent/api.rb
133
+ - lib/tcell_agent/appsensor.rb
129
134
  - lib/tcell_agent/appsensor/cmdi.rb
130
135
  - lib/tcell_agent/appsensor/path_traversal.rb
131
136
  - lib/tcell_agent/appsensor/sqli.rb
132
137
  - lib/tcell_agent/appsensor/xss.rb
133
- - lib/tcell_agent/appsensor.rb
134
138
  - lib/tcell_agent/authlogic.rb
135
139
  - lib/tcell_agent/configuration.rb
136
140
  - lib/tcell_agent/devise.rb
@@ -145,6 +149,7 @@ files:
145
149
  - lib/tcell_agent/policies/http_tx_policy.rb
146
150
  - lib/tcell_agent/policies/login_fraud_policy.rb
147
151
  - lib/tcell_agent/policies/secure_headers_policy.rb
152
+ - lib/tcell_agent/rails.rb
148
153
  - lib/tcell_agent/rails/auth/authlogic.rb
149
154
  - lib/tcell_agent/rails/auth/devise.rb
150
155
  - lib/tcell_agent/rails/dlp.rb
@@ -154,7 +159,6 @@ files:
154
159
  - lib/tcell_agent/rails/middleware/headers_middleware.rb
155
160
  - lib/tcell_agent/rails/routes.rb
156
161
  - lib/tcell_agent/rails/settings_reporter.rb
157
- - lib/tcell_agent/rails.rb
158
162
  - lib/tcell_agent/routes/table.rb
159
163
  - lib/tcell_agent/sensor_events/app_config.rb
160
164
  - lib/tcell_agent/sensor_events/app_sensor.rb
@@ -168,12 +172,16 @@ files:
168
172
  - lib/tcell_agent/sensor_events/util/redirect_utils.rb
169
173
  - lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb
170
174
  - lib/tcell_agent/sensor_events/util/utils.rb
175
+ - lib/tcell_agent/servers/puma.rb
176
+ - lib/tcell_agent/servers/rails_server.rb
177
+ - lib/tcell_agent/servers/thin.rb
178
+ - lib/tcell_agent/servers/unicorn.rb
179
+ - lib/tcell_agent/servers/webrick.rb
171
180
  - lib/tcell_agent/sinatra.rb
172
181
  - lib/tcell_agent/start_background_thread.rb
173
182
  - lib/tcell_agent/userinfo.rb
174
183
  - lib/tcell_agent/utils/queue_with_timeout.rb
175
184
  - lib/tcell_agent/version.rb
176
- - lib/tcell_agent.rb
177
185
  - spec/controllers/application_controller.rb
178
186
  - spec/lib/tcell_agent/api/api_spec.rb
179
187
  - spec/lib/tcell_agent/appsensor_spec.rb
@@ -192,13 +200,11 @@ files:
192
200
  - spec/lib/tcell_agent/sensor_events/dlp_spec.rb
193
201
  - spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb
194
202
  - spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb
203
+ - spec/lib/tcell_agent/utils/bounded_queue_spec.rb
195
204
  - spec/lib/tcell_agent_spec.rb
196
205
  - spec/resources/normal_config.json
197
206
  - spec/spec_helper.rb
198
- - README.md
199
- - LICENSE
200
207
  - tcell_agent.gemspec
201
- - bin/tcell_agent
202
208
  homepage: https://www.tcell.io
203
209
  licenses:
204
210
  - Copyright (c) 2015 tCell.io (see LICENSE file)
@@ -221,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
227
  version: '0'
222
228
  requirements: []
223
229
  rubyforge_project:
224
- rubygems_version: 2.0.14
230
+ rubygems_version: 2.4.8
225
231
  signing_key:
226
232
  specification_version: 4
227
233
  summary: tCell.io Agent for Rails & Sinatra
@@ -244,6 +250,7 @@ test_files:
244
250
  - spec/lib/tcell_agent/sensor_events/dlp_spec.rb
245
251
  - spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb
246
252
  - spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb
253
+ - spec/lib/tcell_agent/utils/bounded_queue_spec.rb
247
254
  - spec/lib/tcell_agent_spec.rb
248
255
  - spec/resources/normal_config.json
249
256
  - spec/spec_helper.rb