logjam_agent 0.30.0 → 0.31.0

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
  SHA256:
3
- metadata.gz: b351167b038a91fd392f94501012260ee84319fb6035b9bf5e35811d50c885b1
4
- data.tar.gz: 838094a8022bf451422bb66219924737c5d32684c7a6194c979554f101b9071e
3
+ metadata.gz: 6b543de9e4f7a8d5ae896a7c2fa4524a8b220a1dad8a6b4e1be6b5eee4c8110e
4
+ data.tar.gz: 62f2aee617a120107307e625b2ba2df8fb461f53ba9fa3baff0ce0187fc1325f
5
5
  SHA512:
6
- metadata.gz: 78a136746231e26e873fcddf04740c0d748c29823e9db6fc9eabb43e9fd26cb10ec92f59eb687b70854f20a8fe918476287c171b3eca48f5006226c712ef0fb2
7
- data.tar.gz: 84f8e23f8fbbc07e319e8cb928945a1c4f3198502d45a8e9a22e8dc4c9f9184f9283811c24ef40587c41d25badb6bfa3eceea7ca43b2468d3b15c1d49cb24393
6
+ metadata.gz: ec3578d040a1033e06029caf81256e6524a66a7c8c24493e986e467a603564e53b22cc05eadf243a3310ccfb8b3b065c012759e5d21d2acd9e64b597e4fb6710
7
+ data.tar.gz: ed17803ea6301229c58b82e2886cf82bb36fa88554567f5864e0d38df653a2b2a07fe76160b49de55ef03619b745608e95648364532f3f7e465021a558ae7ae1
data/README.md CHANGED
@@ -5,9 +5,14 @@ Client side library for logjam.
5
5
  Hooks into Rails, collects log lines, performance metrics, error/exception infomation and Rack
6
6
  environment information and sends this data to [Logjam](https://github.com/skaes/logjam_app).
7
7
 
8
+ Has experimental support for Sinatra.
9
+
8
10
  Currently only one mechanism is available for data transport:
9
11
  ZeroMQ. Support for AMQP has been dropped.
10
12
 
13
+ [![Travis](https://travis-ci.org/skaes/logjam_agent.svg?branch=master)](https://travis-ci.org/github/skaes/logjam_agent)
14
+
15
+
11
16
  ## Usage
12
17
 
13
18
  For ZeroMQ, add
@@ -110,10 +115,8 @@ end
110
115
 
111
116
  ### Generating unique request ids
112
117
 
113
- The agent generates unique request ids for all request handled. It
114
- will use [uuid4r](https://github.com/skaes/uuid4r) if this is
115
- available in the application. Otherwise it will fall back to use the
116
- standard `SecureRandom` class shipped with Ruby.
118
+ The agent generates unique request ids for all request handled using standard
119
+ `SecureRandom` class shipped with Ruby.
117
120
 
118
121
  ### Generating JSON
119
122
 
@@ -121,38 +124,56 @@ The agent will try to use the [Oj](https://github.com/ohler55/oj) to
121
124
  generate JSON. If this is not available in your application, it will
122
125
  fall back to the `to_json` method.
123
126
 
124
- ## Troubleshooting
125
127
 
126
- If the agent experiences problems when sending data, it will log information to a file named
127
- `logjam_agent_error.log` which you can find under `Rails.root/log`.
128
- If you set the `RAILS_LOG_TO_STDOUT` environment variable, those logs will be available through `stderr`.
128
+ ### Sinatra
129
129
 
130
- This behavior is customizable via a module level call back method:
130
+ Supports both classic and modular Sinatra applications. Since Sinatra doesn't have built
131
+ in action names like Rails, you'll have to declare them in your handlers, or in a before
132
+ filter. Example:
131
133
 
132
134
  ```ruby
133
- LogjamAgent.error_handler = lambda {|exception| ... }
135
+ require 'logjam_agent/sinatra'
136
+
137
+ use LogjamAgent::Sinatra::Middleware
138
+
139
+ class SinatraTestApp < Sinatra::Base
140
+ register LogjamAgent::Sinatra
141
+
142
+ configure do
143
+ set :loglevel, :debug
144
+ setup_logjam_logger
145
+
146
+ LogjamAgent.application_name = "myapp"
147
+ LogjamAgent.add_forwarder(:zmq, :host => "my-logjam-broker")
148
+ LogjamAgent.parameter_filters << :password
149
+ end
150
+
151
+ before '/index' do
152
+ action_name "Simple#index"
153
+ end
154
+
155
+ get '/index' do
156
+ logger.info 'Hello World!'
157
+ 'Hello World!'
158
+ end
159
+ end
134
160
  ```
135
161
 
136
- # License
162
+ The environment name is picked up from either the environment variable `LOGJAM_ENV`, or
163
+ Sinatra's environment setting.
137
164
 
138
- The MIT License
165
+ Set the environment variable `APP_LOG_TO_STDOUT` if you want to log to `STDOUT`.
166
+ Otherwise, logs will appear in the subdirectory `log` of your application's root.
139
167
 
140
- Copyright (c) 2013 - 2019 Stefan Kaes
141
168
 
142
- Permission is hereby granted, free of charge, to any person obtaining a copy
143
- of this software and associated documentation files (the "Software"), to deal
144
- in the Software without restriction, including without limitation the rights
145
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
146
- copies of the Software, and to permit persons to whom the Software is
147
- furnished to do so, subject to the following conditions:
169
+ ## Troubleshooting
170
+
171
+ If the agent experiences problems when sending data, it will log information to a file named
172
+ `logjam_agent_error.log` which you can find under `Rails.root/log`.
173
+ If you set the `RAILS_LOG_TO_STDOUT` environment variable, those logs will be available through `stderr`.
148
174
 
149
- The above copyright notice and this permission notice shall be included in
150
- all copies or substantial portions of the Software.
175
+ This behavior is customizable via a module level call back method:
151
176
 
152
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
153
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
154
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
155
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
156
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
157
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
158
- THE SOFTWARE.
177
+ ```ruby
178
+ LogjamAgent.error_handler = lambda {|exception| ... }
179
+ ```
data/Rakefile CHANGED
@@ -7,8 +7,13 @@ Rake::TestTask.new do |t|
7
7
  t.libs << "test"
8
8
  t.test_files = FileList['test/**/*_test.rb']
9
9
  t.verbose = true
10
+ t.ruby_opts = %w(-W1)
10
11
  end
11
12
 
12
13
  task :default do
13
14
  Rake::Task[:test].invoke
14
15
  end
16
+
17
+ task :integration do
18
+ sh "cd railsapp && rake"
19
+ end
@@ -36,9 +36,7 @@ require "logjam_agent/request"
36
36
  require "logjam_agent/buffered_logger"
37
37
  require "logjam_agent/syslog_like_formatter"
38
38
 
39
- if defined?(Rails) && Rails::VERSION::STRING >= "3.0"
40
- require "logjam_agent/railtie"
41
- end
39
+ require "logjam_agent/railtie" if defined?(Rails::Railtie)
42
40
 
43
41
  # monkey patch log levels to include NONE
44
42
  require 'logger'
@@ -74,6 +72,9 @@ module LogjamAgent
74
72
  mattr_accessor :action_name_proc
75
73
  self.action_name_proc = lambda{|name| name}
76
74
 
75
+ mattr_accessor :parameter_filters
76
+ self.parameter_filters = []
77
+
77
78
  def self.get_hostname
78
79
  n = Socket.gethostname
79
80
  if n.split('.').size > 1
@@ -97,6 +98,9 @@ module LogjamAgent
97
98
  mattr_accessor :disabled
98
99
  self.disabled = false
99
100
 
101
+ mattr_accessor :ensure_ping_at_exit
102
+ self.ensure_ping_at_exit = true
103
+
100
104
  mattr_accessor :obfuscate_ips
101
105
  self.obfuscate_ips = false
102
106
 
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ # Removes and returns the elements for which the block returns a true value.
5
+ # If no block is given, an Enumerator is returned instead.
6
+ #
7
+ # numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8
+ # odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
9
+ # numbers # => [0, 2, 4, 6, 8]
10
+ def extract!
11
+ return to_enum(:extract!) { size } unless block_given?
12
+
13
+ extracted_elements = []
14
+
15
+ reject! do |element|
16
+ extracted_elements << element if yield(element)
17
+ end
18
+
19
+ extracted_elements
20
+ end
21
+ end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/duplicable"
4
+ require_relative "core_ext/array/extract"
5
+
6
+ module ActiveSupport
7
+ # +ParameterFilter+ allows you to specify keys for sensitive data from
8
+ # hash-like object and replace corresponding value. Filtering only certain
9
+ # sub-keys from a hash is possible by using the dot notation:
10
+ # 'credit_card.number'. If a proc is given, each key and value of a hash and
11
+ # all sub-hashes are passed to it, where the value or the key can be replaced
12
+ # using String#replace or similar methods.
13
+ #
14
+ # ActiveSupport::ParameterFilter.new([:password])
15
+ # => replaces the value to all keys matching /password/i with "[FILTERED]"
16
+ #
17
+ # ActiveSupport::ParameterFilter.new([:foo, "bar"])
18
+ # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
19
+ #
20
+ # ActiveSupport::ParameterFilter.new(["credit_card.code"])
21
+ # => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
22
+ # change { file: { code: "xxxx"} }
23
+ #
24
+ # ActiveSupport::ParameterFilter.new([-> (k, v) do
25
+ # v.reverse! if k =~ /secret/i
26
+ # end])
27
+ # => reverses the value to all keys matching /secret/i
28
+ class ParameterFilter
29
+ FILTERED = "[FILTERED]" # :nodoc:
30
+
31
+ # Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+.
32
+ # Other types of filters are treated as +String+ using +to_s+.
33
+ # For +Proc+ filters, key, value, and optional original hash is passed to block arguments.
34
+ #
35
+ # ==== Options
36
+ #
37
+ # * <tt>:mask</tt> - A replaced object when filtered. Defaults to +"[FILTERED]"+
38
+ def initialize(filters = [], mask: FILTERED)
39
+ @filters = filters
40
+ @mask = mask
41
+ end
42
+
43
+ # Mask value of +params+ if key matches one of filters.
44
+ def filter(params)
45
+ compiled_filter.call(params)
46
+ end
47
+
48
+ # Returns filtered value for given key. For +Proc+ filters, third block argument is not populated.
49
+ def filter_param(key, value)
50
+ @filters.empty? ? value : compiled_filter.value_for_key(key, value)
51
+ end
52
+
53
+ private
54
+ def compiled_filter
55
+ @compiled_filter ||= CompiledFilter.compile(@filters, mask: @mask)
56
+ end
57
+
58
+ class CompiledFilter # :nodoc:
59
+ def self.compile(filters, mask:)
60
+ return lambda { |params| params.dup } if filters.empty?
61
+
62
+ strings, regexps, blocks = [], [], []
63
+
64
+ filters.each do |item|
65
+ case item
66
+ when Proc
67
+ blocks << item
68
+ when Regexp
69
+ regexps << item
70
+ else
71
+ strings << Regexp.escape(item.to_s)
72
+ end
73
+ end
74
+
75
+ deep_regexps = regexps.extract! { |r| r.to_s.include?("\\.") }
76
+ deep_strings = strings.extract! { |s| s.include?("\\.") }
77
+
78
+ regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
79
+ deep_regexps << Regexp.new(deep_strings.join("|"), true) unless deep_strings.empty?
80
+
81
+ new regexps, deep_regexps, blocks, mask: mask
82
+ end
83
+
84
+ attr_reader :regexps, :deep_regexps, :blocks
85
+
86
+ def initialize(regexps, deep_regexps, blocks, mask:)
87
+ @regexps = regexps
88
+ @deep_regexps = deep_regexps.any? ? deep_regexps : nil
89
+ @blocks = blocks
90
+ @mask = mask
91
+ end
92
+
93
+ def call(params, parents = [], original_params = params)
94
+ filtered_params = params.class.new
95
+
96
+ params.each do |key, value|
97
+ filtered_params[key] = value_for_key(key, value, parents, original_params)
98
+ end
99
+
100
+ filtered_params
101
+ end
102
+
103
+ def value_for_key(key, value, parents = [], original_params = nil)
104
+ parents.push(key) if deep_regexps
105
+ if regexps.any? { |r| r.match?(key.to_s) }
106
+ value = @mask
107
+ elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| r.match?(joined) }
108
+ value = @mask
109
+ elsif value.is_a?(Hash)
110
+ value = call(value, parents, original_params)
111
+ elsif value.is_a?(Array)
112
+ # If we don't pop the current parent it will be duplicated as we
113
+ # process each array value.
114
+ parents.pop if deep_regexps
115
+ value = value.map { |v| value_for_key(key, v, parents, original_params) }
116
+ # Restore the parent stack after processing the array.
117
+ parents.push(key) if deep_regexps
118
+ elsif blocks.any?
119
+ key = key.dup if key.duplicable?
120
+ value = value.dup if value.duplicable?
121
+ blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
122
+ end
123
+ parents.pop if deep_regexps
124
+ value
125
+ end
126
+ end
127
+ end
128
+ end
@@ -1,54 +1,31 @@
1
1
  require 'fileutils'
2
2
 
3
- if ActiveSupport::VERSION::STRING < "4.0"
4
- require 'active_support/buffered_logger'
5
- require 'active_support/core_ext/logger'
6
- if ActiveSupport::VERSION::STRING >= "3.2"
7
- require 'active_support/tagged_logging'
8
- # monkey patch to handle exceptions correctly
9
- # not needed for rails 4 as this uses a Formatter to add the tags
10
- class ActiveSupport::TaggedLogging
11
- def initialize(logger)
12
- @logger = logger
13
- if logger.is_a?(LogjamAgent::BufferedLogger)
14
- self.class.class_eval <<-EVAL, __FILE__, __LINE__ + 1
15
- def add(severity, message = nil, progname = nil, &block)
16
- @logger.add(severity, message, progname, tags_text, &block)
17
- end
18
- EVAL
19
- end
20
- end
21
- end
22
- end
23
- else
24
- require 'active_support/logger'
3
+ require 'active_support/logger'
25
4
 
26
- class LogjamAgent::ConsoleFormatter < Logger::Formatter
27
- # This method is invoked when a log event occurs
28
- def call(severity, timestamp, progname, msg)
29
- "[#{format_time(timestamp)}] #{String === msg ? msg : msg.inspect}\n"
30
- end
5
+ class LogjamAgent::ConsoleFormatter < Logger::Formatter
6
+ # This method is invoked when a log event occurs
7
+ def call(severity, timestamp, progname, msg)
8
+ "[#{format_time(timestamp)}] #{String === msg ? msg : msg.inspect}\n"
9
+ end
31
10
 
32
- def format_time(timestamp)
33
- timestamp.strftime("%H:%M:%S.#{"%06d" % timestamp.usec}")
34
- end
11
+ def format_time(timestamp)
12
+ timestamp.strftime("%H:%M:%S.#{"%06d" % timestamp.usec}")
35
13
  end
14
+ end
36
15
 
37
- class ActiveSupport::Logger
38
- class << self
39
- alias_method :original_broadcast, :broadcast
40
- def broadcast(logger)
41
- logger.formatter = LogjamAgent::ConsoleFormatter.new
42
- logger.formatter.extend(ActiveSupport::TaggedLogging::Formatter)
43
- original_broadcast(logger)
44
- end
16
+ class ActiveSupport::Logger
17
+ class << self
18
+ alias_method :original_broadcast, :broadcast
19
+ def broadcast(logger)
20
+ logger.formatter = LogjamAgent::ConsoleFormatter.new
21
+ logger.formatter.extend(ActiveSupport::TaggedLogging::Formatter)
22
+ original_broadcast(logger)
45
23
  end
46
24
  end
47
25
  end
48
26
 
49
27
  module LogjamAgent
50
- class BufferedLogger < ( ActiveSupport::VERSION::STRING < "4.0" ?
51
- ActiveSupport::BufferedLogger : ActiveSupport::Logger )
28
+ class BufferedLogger < ActiveSupport::Logger
52
29
 
53
30
  attr_accessor :formatter
54
31
 
@@ -57,8 +34,6 @@ module LogjamAgent
57
34
 
58
35
  def initialize(*args)
59
36
  super(*args)
60
- # stupid bug in the buffered logger code (Rails::VERSION::STRING < "3.2")
61
- @log.write "\n" if @log && respond_to?(:buffer)
62
37
  @formatter = lambda{|_, _, _, message| message}
63
38
  end
64
39
 
@@ -1,11 +1,16 @@
1
1
  module LogjamAgent
2
2
  class Middleware
3
- def initialize(app, options={})
3
+ def initialize(app, framework = :rails)
4
4
  @app = app
5
- @options = options
5
+ @framework = framework
6
+ unless %i{rails sinatra}.include?(framework)
7
+ raise ArgumentError.new("Invalid logjam_agent framework: #{framework}. Only :rails and :sinatra are valid!")
8
+ end
9
+ @reraise = defined?(Rails::Railtie) && Rails.env.test?
6
10
  end
7
11
 
8
12
  def call(env)
13
+ env["logjam_agent.framework"] = @framework
9
14
  strip_encoding_from_etag(env)
10
15
  request = start_request(env)
11
16
  result = @app.call(env)
@@ -13,9 +18,13 @@ module LogjamAgent
13
18
  result
14
19
  rescue Exception
15
20
  result = [500, {'Content-Type' => 'text/html'}, ["<html><body><h1>500 Internal Server Error</h1></body></html>"]]
21
+ raise if @reraise
16
22
  ensure
17
23
  headers = result[1]
18
24
  headers["X-Logjam-Request-Id"] = request.id
25
+ if env["sinatra.static_file"]
26
+ request.fields[:action] = "Sinatra#static_file"
27
+ end
19
28
  unless (request_action = request.fields[:action]).blank?
20
29
  headers["X-Logjam-Request-Action"] = request_action
21
30
  end
@@ -41,7 +50,10 @@ module LogjamAgent
41
50
  env_name = env["logjam_agent.environment_name"] || LogjamAgent.environment_name
42
51
  caller_id = env["HTTP_X_LOGJAM_CALLER_ID"] || ""
43
52
  caller_action = env["HTTP_X_LOGJAM_ACTION"] || ""
44
- LogjamAgent.start_request(app_name, env_name, :caller_id => caller_id, :caller_action => caller_action)
53
+ extra_fields = {}
54
+ extra_fields[:caller_id] = caller_id if caller_id.present?
55
+ extra_fields[:caller_action] = caller_action if caller_action.present?
56
+ LogjamAgent.start_request(app_name, env_name, extra_fields)
45
57
  end
46
58
 
47
59
  def finish_request(env)
@@ -7,14 +7,19 @@ module LogjamAgent
7
7
  class Logger < ActiveSupport::LogSubscriber
8
8
  def initialize(app, taggers = nil)
9
9
  @app = app
10
- @taggers = taggers || Rails.application.config.log_tags || []
10
+ @taggers = taggers || (defined?(Rails::Railtie) ? Rails.application.config.log_tags : []) || []
11
11
  @hostname = LogjamAgent.hostname
12
12
  @asset_prefix = Rails.application.config.assets.prefix rescue "---"
13
13
  @ignore_asset_requests = LogjamAgent.ignore_asset_requests
14
14
  end
15
15
 
16
16
  def call(env)
17
- request = ActionDispatch::Request.new(env)
17
+ if env["logjam_agent.framework"] == :sinatra
18
+ request = ::Sinatra::Request.new(env)
19
+ env["rack.logger"] = logger
20
+ else
21
+ request = ActionDispatch::Request.new(env)
22
+ end
18
23
 
19
24
  if logger.respond_to?(:tagged) && !@taggers.empty?
20
25
  logger.tagged(compute_tags(request)) { call_app(request, env) }
@@ -88,7 +93,7 @@ module LogjamAgent
88
93
  spoofed = nil
89
94
  ip = nil
90
95
  begin
91
- ip = LogjamAgent.ip_obfuscator(env["action_dispatch.remote_ip"].to_s)
96
+ ip = LogjamAgent.ip_obfuscator((env["action_dispatch.remote_ip"] || request.ip).to_s)
92
97
  rescue ActionDispatch::RemoteIp::IpSpoofAttackError => spoofed
93
98
  ip = "*** SPOOFED IP ***"
94
99
  end
@@ -107,6 +112,11 @@ module LogjamAgent
107
112
  if completed_info = Thread.current.thread_variable_get(:time_bandits_completed_info)
108
113
  _, additions, view_time, _ = completed_info
109
114
  end
115
+ additions ||= []
116
+ if env["logjam_agent.framework"] == :sinatra
117
+ TimeBandits.consumed
118
+ additions.concat TimeBandits.runtimes
119
+ end
110
120
  logjam_request = LogjamAgent.request
111
121
 
112
122
  if (allowed_time_ms = env['HTTP_X_LOGJAM_CALLER_TIMEOUT'].to_i) > 0 && (run_time_ms > allowed_time_ms)
@@ -123,9 +133,9 @@ module LogjamAgent
123
133
  info message unless logjam_request.ignored?
124
134
 
125
135
  ActiveSupport::LogSubscriber.flush_all!
126
- request_info = {
127
- :total_time => run_time_ms, :code => status, :view_time => view_time || 0.0, :wait_time => wait_time_ms
128
- }
136
+ request_info = { :total_time => run_time_ms, :code => status }
137
+ request_info[:view_time] = view_time if view_time
138
+ request_info[:wait_time] = wait_time_ms if wait_time_ms > 0
129
139
  logjam_request.fields.merge!(request_info)
130
140
 
131
141
  env["time_bandits.metrics"] = TimeBandits.metrics
@@ -153,7 +163,7 @@ module LogjamAgent
153
163
 
154
164
  result
155
165
  rescue Exception => e
156
- Rails.logger.error(e)
166
+ logger.error(e)
157
167
  result
158
168
  end
159
169
 
@@ -197,82 +207,10 @@ module LogjamAgent
197
207
 
198
208
  headers
199
209
  end
200
-
201
210
  end
202
211
  end
203
212
  end
204
213
 
205
- # patch the actioncontroller logsubscriber to set the action on the logjam logger as soon as it starts processing the request
206
- require 'action_controller/metal/instrumentation'
207
- require 'action_controller/log_subscriber'
208
-
209
- module ActionController #:nodoc:
210
-
211
- class LogSubscriber
212
- if Rails::VERSION::STRING =~ /\A3\.0/
213
- def start_processing(event)
214
- payload = event.payload
215
- params = payload[:params].except(*INTERNAL_PARAMS)
216
-
217
- controller = payload[:controller]
218
- action = payload[:action]
219
- full_name = "#{controller}##{action}"
220
- action_name = LogjamAgent.action_name_proc.call(full_name)
221
-
222
- LogjamAgent.request.fields[:action] = action_name
223
-
224
- info " Processing by #{full_name} as #{payload[:formats].first.to_s.upcase}"
225
- info " Parameters: #{params.inspect}" unless params.empty?
226
- end
227
-
228
- elsif Rails::VERSION::STRING =~ /\A3\.1/
229
-
230
- def start_processing(event)
231
- payload = event.payload
232
- params = payload[:params].except(*INTERNAL_PARAMS)
233
- format = payload[:format]
234
- format = format.to_s.upcase if format.is_a?(Symbol)
235
-
236
- controller = payload[:controller]
237
- action = payload[:action]
238
- full_name = "#{controller}##{action}"
239
- action_name = LogjamAgent.action_name_proc.call(full_name)
240
-
241
- LogjamAgent.request.fields[:action] = action_name
242
-
243
- info " Processing by #{full_name} as #{format}"
244
- info " Parameters: #{params.inspect}" unless params.empty?
245
- end
246
-
247
- elsif Rails::VERSION::STRING =~ /\A(3\.2|4|5|6)/
248
-
249
- # Rails 4.1 uses method_added to automatically subscribe newly
250
- # added methods. Since start_processing is already defined, the
251
- # net effect is that start_processing gets called
252
- # twice. Therefore, we temporarily switch to protected mode and
253
- # change it back later to public.
254
- protected
255
- def start_processing(event)
256
- payload = event.payload
257
- params = payload[:params].except(*INTERNAL_PARAMS)
258
- format = payload[:format]
259
- format = format.to_s.upcase if format.is_a?(Symbol)
260
-
261
- controller = payload[:controller]
262
- action = payload[:action]
263
- full_name = "#{controller}##{action}"
264
- action_name = LogjamAgent.action_name_proc.call(full_name)
265
-
266
- LogjamAgent.request.fields[:action] = action_name
267
-
268
- info "Processing by #{full_name} as #{format}"
269
- info " Parameters: #{params.inspect}" unless params.empty?
270
- end
271
- public :start_processing
272
-
273
- else
274
- raise "logjam_agent ActionController monkey patch is not compatible with your Rails version"
275
- end
276
- end
277
-
214
+ if defined?(Rails::Railtie)
215
+ require_relative "rails_support"
278
216
  end
@@ -0,0 +1,26 @@
1
+ # patch the actioncontroller logsubscriber to set the action on the logjam logger as soon as it starts processing the request
2
+ require 'action_controller/metal/instrumentation'
3
+ require 'action_controller/log_subscriber'
4
+
5
+ module ActionController #:nodoc:
6
+
7
+ class LogSubscriber
8
+ def start_processing(event)
9
+ payload = event.payload
10
+ params = payload[:params].except(*INTERNAL_PARAMS)
11
+ format = payload[:format]
12
+ format = format.to_s.upcase if format.is_a?(Symbol)
13
+
14
+ controller = payload[:controller]
15
+ action = payload[:action]
16
+ full_name = "#{controller}##{action}"
17
+ action_name = LogjamAgent.action_name_proc.call(full_name)
18
+
19
+ LogjamAgent.request.fields[:action] = action_name
20
+
21
+ info "Processing by #{full_name} as #{format}"
22
+ info " Parameters: #{params.inspect}" unless params.empty?
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,32 @@
1
+ require 'sinatra/base'
2
+ begin
3
+ require 'active_support/parameter_filter'
4
+ rescue LoadError
5
+ require_relative '../active_support/parameter_filter'
6
+ end
7
+
8
+ # Extend the Sinatra Request class with some methods to make it look more like an
9
+ # ActionDispatch request.
10
+
11
+ class Sinatra::Request
12
+ alias_method :method, :request_method
13
+ def query_parameters; self.GET; end
14
+ def request_parameters; self.POST; end
15
+
16
+ def parameter_filter
17
+ ActiveSupport::ParameterFilter.new(LogjamAgent.parameter_filters)
18
+ end
19
+
20
+ KV_RE = '[^&;=]+'
21
+ PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})}
22
+
23
+ def filtered_path
24
+ return path if query_string.empty?
25
+ filter = parameter_filter
26
+ filtered_query_string = query_string.gsub(PAIR_RE) do |_|
27
+ filter.filter($1 => $2).first.join("=")
28
+ end
29
+ "#{path}?#{filtered_query_string}"
30
+ end
31
+
32
+ end
@@ -80,6 +80,9 @@ module LogjamAgent
80
80
  # disable logjam request forwarding by default in test environment
81
81
  LogjamAgent.disable! if Rails.env.test?
82
82
 
83
+ # only sent pings in production like environments
84
+ LogjamAgent.ensure_ping_at_exit = !%w(test development).include?(Rails.env.to_s)
85
+
83
86
  # patch controller testing to create a logjam request, because middlewares aren't executed
84
87
  if Rails.env.test?
85
88
  ActiveSupport.on_load(:action_controller) do
@@ -0,0 +1,22 @@
1
+ module LogjamAgent
2
+ class Receiver
3
+ def initialize
4
+ @socket = ZMQForwarder.context.socket(ZMQ::ROUTER)
5
+ @socket.setsockopt(ZMQ::RCVTIMEO, 100)
6
+ if @socket.bind("inproc://app") < 0
7
+ raise "ZMQ error on binding: #{ZMQ::Util.error_string}"
8
+ end
9
+ at_exit { @socket.close }
10
+ end
11
+
12
+ def receive
13
+ answer_parts = []
14
+ if @socket.recv_strings(answer_parts) < 0
15
+ raise "ZMQ error on receiving: #{ZMQ::Util.error_string}"
16
+ end
17
+ answer_parts.shift
18
+ answer_parts[2] = JSON.parse(answer_parts[2])
19
+ answer_parts
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,116 @@
1
+ require 'sinatra'
2
+ require 'logger'
3
+ require 'logjam_agent'
4
+ require 'logjam_agent/middleware'
5
+ require 'logjam_agent/rack/sinatra_request'
6
+ require 'logjam_agent/rack/logger'
7
+ require 'time_bandits'
8
+
9
+ module LogjamAgent
10
+ module Sinatra
11
+ class Middleware
12
+ def initialize(app)
13
+ app_with_logging = LogjamAgent::Rack::Logger.new(app)
14
+ @app = LogjamAgent::Middleware.new(app_with_logging, :sinatra)
15
+ end
16
+ def call(env)
17
+ @app.call(env)
18
+ end
19
+ end
20
+
21
+ module Helpers
22
+ def action_name(action_name)
23
+ LogjamAgent.request.fields[:action] = action_name
24
+ end
25
+
26
+ def logger
27
+ LogjamAgent.logger
28
+ end
29
+ end
30
+
31
+ def setup_logjam_logger
32
+ log_path = ENV["APP_LOG_TO_STDOUT"].present? ? STDOUT : "#{settings.root}/log/#{LogjamAgent.environment_name}.log"
33
+ logger = LogjamAgent::BufferedLogger.new(log_path) rescue LogjamAgent::BufferedLogger.new(STDERR)
34
+
35
+ loglevel = settings.respond_to?(:loglevel) ? settings.loglevel : :info
36
+ logger.level = ::Logger.const_get(loglevel.to_s.upcase)
37
+
38
+ LogjamAgent.log_device_log_level = logger.level
39
+ LogjamAgent.log_device_log_level = ::Logger::ERROR unless %i[test development].include?(settings.environment.to_sym)
40
+
41
+ logger.formatter = LogjamAgent::SyslogLikeFormatter.new
42
+ logger = ActiveSupport::TaggedLogging.new(logger)
43
+ LogjamAgent.logger = logger
44
+ ActiveSupport::LogSubscriber.logger = logger
45
+
46
+ log_path = ENV["APP_LOG_TO_STDOUT"].present? ? STDOUT : "#{settings.root}/log/logjam_agent_error.log"
47
+ forwarding_error_logger = ::Logger.new(log_path) rescue ::Logger.new(STDERR)
48
+ forwarding_error_logger.level = ::Logger::ERROR
49
+ forwarding_error_logger.formatter = ::Logger::Formatter.new
50
+ LogjamAgent.forwarding_error_logger = forwarding_error_logger
51
+
52
+ truncate_overlong_params = lambda { |key, value|
53
+ max_size = LogjamAgent.max_logged_size_for(key)
54
+ if value.is_a?(String) && value.size > max_size
55
+ value[max_size..-1] = " ... [TRUNCATED]"
56
+ end
57
+ }
58
+ LogjamAgent.parameter_filters << truncate_overlong_params
59
+ end
60
+
61
+ def self.registered(app)
62
+ app.helpers Helpers
63
+ LogjamAgent.environment_name = ENV['LOGJAM_ENV'] || app.settings.environment.to_s
64
+ LogjamAgent.auto_detect_logged_exceptions
65
+ LogjamAgent.disable! if app.settings.environment.to_sym == :test
66
+ end
67
+ end
68
+ end
69
+
70
+ # For classic apps.
71
+ Sinatra.register LogjamAgent::Sinatra
72
+
73
+ # We already supply a logger.
74
+ Sinatra::Base.class_eval do
75
+ class << self
76
+ def setup_logging(builder); end
77
+ end
78
+ end
79
+
80
+ # Patch Sinatra's render logic to compute corrected view times.
81
+ module LogjamAgent
82
+ module ComputeRenderTimes
83
+ def render(engine, data, options = {}, locals = {}, &block)
84
+ consumed_before_rendering = TimeBandits.consumed
85
+ result = exception = nil
86
+ duration = Benchmark.ms do
87
+ begin
88
+ result = super
89
+ rescue => exception
90
+ end
91
+ end
92
+ consumed_during_rendering = TimeBandits.consumed - consumed_before_rendering
93
+ duration -= consumed_during_rendering
94
+ raise exception if exception
95
+ result
96
+ ensure
97
+ Thread.current.thread_variable_set(
98
+ :time_bandits_completed_info,
99
+ [ duration, ["Views: %.3fms" % duration.to_f], duration, "" ]
100
+ )
101
+ end
102
+ end
103
+ end
104
+
105
+ Sinatra::Base.prepend LogjamAgent::ComputeRenderTimes
106
+
107
+ # Define exception, but don't do anything about it. Sneaky!
108
+ module ActionDispatch
109
+ module RemoteIp
110
+ class IpSpoofAttackError < StandardError; end
111
+ end
112
+ end
113
+
114
+ # Add GC time bandit
115
+ TimeBandits.reset
116
+ TimeBandits.add TimeBandits::TimeConsumers::GarbageCollection.instance if GC.respond_to? :enable_stats
@@ -41,7 +41,7 @@ module LogjamAgent
41
41
  "#{format_severity(severity)} #{format_time(timestamp)}#{render_attributes}#{format_host_info(progname)}: #{format_message(msg)}#{@newline}"
42
42
  end
43
43
 
44
- if !defined?(Rails) || Rails.env.development?
44
+ if !defined?(Rails::Railtie) || Rails.env.development?
45
45
  def format_host_info(progname); ""; end
46
46
  else
47
47
  def format_host_info(progname)
@@ -62,7 +62,12 @@ module LogjamAgent
62
62
  protocol, host, port = %r{\A(?:([^:]+)://)?([^:]+)(?::(\d+))?\z}.match(spec).captures
63
63
  protocol ||= "tcp"
64
64
  port ||= default_port
65
- "#{protocol}://#{host}:#{port}"
65
+ if protocol == "inproc"
66
+ # should only be used for integration tests
67
+ "#{protocol}://#{host}"
68
+ else
69
+ "#{protocol}://#{host}:#{port}"
70
+ end
66
71
  end
67
72
  end
68
73
  end
@@ -1,3 +1,3 @@
1
1
  module LogjamAgent
2
- VERSION = "0.30.0"
2
+ VERSION = "0.31.0"
3
3
  end
@@ -53,7 +53,12 @@ module LogjamAgent
53
53
  def socket
54
54
  return @socket if @socket
55
55
  @socket = self.class.context.socket(ZMQ::DEALER)
56
- ensure_ping_at_exit
56
+ raise "ZMQ error on socket creation: #{ZMQ::Util.error_string}" if @socket.nil?
57
+ if LogjamAgent.ensure_ping_at_exit
58
+ ensure_ping_at_exit
59
+ else
60
+ at_exit { reset }
61
+ end
57
62
  @socket.setsockopt(ZMQ::LINGER, @config[:linger])
58
63
  @socket.setsockopt(ZMQ::SNDHWM, @config[:snd_hwm])
59
64
  @socket.setsockopt(ZMQ::RCVHWM, @config[:rcv_hwm])
@@ -98,8 +103,9 @@ module LogjamAgent
98
103
  info = pack_info(@sequence = next_fixnum(@sequence))
99
104
  parts = [app_env, key, data, info]
100
105
  if socket.send_strings(parts, ZMQ::DONTWAIT) < 0
106
+ error = ZMQ::Util.error_string
101
107
  reset if connection_specs.size > 1
102
- raise "ZMQ error on publishing: #{ZMQ::Util.error_string}"
108
+ raise "ZMQ error on publishing: #{error}"
103
109
  end
104
110
  end
105
111
 
@@ -0,0 +1,32 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'logjam_agent/sinatra'
4
+
5
+ class SinatraTestApp < Sinatra::Base
6
+ register LogjamAgent::Sinatra
7
+
8
+ use LogjamAgent::Sinatra::Middleware
9
+
10
+ configure do
11
+ set :root, File.expand_path('../..', __FILE__)
12
+ set :environment, :test
13
+ set :loglevel, :debug
14
+ setup_logjam_logger
15
+
16
+ LogjamAgent.application_name = "myapp"
17
+ LogjamAgent.add_forwarder(:zmq, :host => "inproc://app")
18
+ LogjamAgent.parameter_filters << :password
19
+ LogjamAgent.ensure_ping_at_exit = false
20
+ end
21
+
22
+ before '/index' do
23
+ action_name "Simple#index"
24
+ end
25
+
26
+ get '/index' do
27
+ logger.info 'Hello World!'
28
+ 'Hello World!'
29
+ end
30
+
31
+ run! if __FILE__ == $0
32
+ end
@@ -0,0 +1,31 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'logjam_agent/sinatra'
4
+
5
+ use LogjamAgent::Sinatra::Middleware
6
+
7
+ configure do
8
+ set :root, File.expand_path('../..', __FILE__)
9
+ set :environment, :test
10
+ set :loglevel, :debug
11
+ setup_logjam_logger
12
+
13
+ LogjamAgent.application_name = "myapp"
14
+ LogjamAgent.add_forwarder(
15
+ :zmq,
16
+ :host => "localhost",
17
+ :port => 9604,
18
+ :linger => 10,
19
+ :snd_hwm => 10,
20
+ :rcv_hwm => 10,
21
+ :rcv_timeo => 10,
22
+ :snd_timeo => 10
23
+ )
24
+ LogjamAgent.parameter_filters << :password
25
+ end
26
+
27
+ get '/index' do
28
+ action_name "Simple#index"
29
+ logger.info 'Hello World!'
30
+ 'Hello World!'
31
+ end
@@ -0,0 +1,20 @@
1
+ require_relative "test_helper.rb"
2
+ require_relative "sinatra_classic_app"
3
+ require "rack/test"
4
+
5
+ module LogjamAgent
6
+ class SinatraClassicTest < MiniTest::Test
7
+
8
+ include ::Rack::Test::Methods
9
+
10
+ def app
11
+ ::Sinatra::Application
12
+ end
13
+
14
+ def test_root
15
+ get '/index?mumu=1&password=5'
16
+ assert_equal 'Hello World!', last_response.body
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,54 @@
1
+ require_relative "test_helper.rb"
2
+ require_relative "sinatra_app"
3
+ require "rack/test"
4
+
5
+ module LogjamAgent
6
+ class SinatraTest < MiniTest::Test
7
+ def setup
8
+ @@receiver ||= LogjamAgent::Receiver.new
9
+ LogjamAgent.enable!
10
+ end
11
+
12
+ def teardown
13
+ LogjamAgent.disable!
14
+ end
15
+
16
+ def logjam_message
17
+ @@receiver.receive
18
+ end
19
+
20
+ include ::Rack::Test::Methods
21
+
22
+ def app
23
+ SinatraTestApp
24
+ end
25
+
26
+ def test_root
27
+ get '/index?mumu=1&password=5'
28
+ assert_equal 'Hello World!', last_response.body
29
+ assert_equal 200, last_response.status
30
+
31
+ stream, topic, payload = logjam_message
32
+ assert_equal "myapp-test", stream
33
+ assert_equal "logs.myapp.test", topic
34
+ assert_equal 200, payload["code"]
35
+ assert_equal "Simple#index", payload["action"]
36
+ assert_kind_of Float, payload["total_time"]
37
+ assert_kind_of String, payload["started_at"]
38
+ assert_kind_of Integer, payload["started_ms"]
39
+ assert_kind_of String, payload["ip"]
40
+ # assert_kind_of Float, payload["view_time"]
41
+ lines = payload["lines"]
42
+ assert_match(/Started GET.*password=\[FILTERED\]/, lines[0][2])
43
+ assert_match(/Hello World/, lines[1][2])
44
+ assert_match(/Completed 200 OK/, lines[2][2])
45
+ assert_nil(lines[3])
46
+ request_info = payload["request_info"]
47
+ method, url, query_parameters = request_info.values_at(*%w(method url query_parameters))
48
+ assert_equal method, "GET"
49
+ assert_equal url, "/index?mumu=1&password=[FILTERED]"
50
+ assert_equal(query_parameters, { "mumu" => "1", "password" => "[FILTERED]" })
51
+ end
52
+
53
+ end
54
+ end
@@ -8,4 +8,9 @@ class MiniTest::Test
8
8
  extend ActiveSupport::Testing::Declarative
9
9
  end
10
10
 
11
- require_relative "../lib/logjam_agent"
11
+ $:.unshift File.expand_path('../../lib', __FILE__)
12
+ require "logjam_agent"
13
+ require "logjam_agent/receiver"
14
+
15
+ # for Sinatra
16
+ ENV['RACK_ENV'] = "test"
@@ -24,5 +24,10 @@ module LogjamAgent
24
24
  assert_equal "tcp://a:1", augmented
25
25
  end
26
26
 
27
+ test "supports inproc" do
28
+ augmented = augment_connection_spec("inproc://hugo-schnugo", 2)
29
+ assert_equal "inproc://hugo-schnugo", augmented
30
+ end
31
+
27
32
  end
28
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logjam_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.30.0
4
+ version: 0.31.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Kaes
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-15 00:00:00.000000000 Z
11
+ date: 2020-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -122,6 +122,48 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: sinatra
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rack-test
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: appraisal
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
125
167
  - !ruby/object:Gem::Dependency
126
168
  name: activesupport
127
169
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +184,14 @@ dependencies:
142
184
  requirements:
143
185
  - - ">="
144
186
  - !ruby/object:Gem::Version
145
- version: 0.6.0
187
+ version: 0.12.2
146
188
  type: :runtime
147
189
  prerelease: false
148
190
  version_requirements: !ruby/object:Gem::Requirement
149
191
  requirements:
150
192
  - - ">="
151
193
  - !ruby/object:Gem::Version
152
- version: 0.6.0
194
+ version: 0.12.2
153
195
  - !ruby/object:Gem::Dependency
154
196
  name: ffi-rzmq-core
155
197
  requirement: !ruby/object:Gem::Requirement
@@ -185,32 +227,39 @@ executables: []
185
227
  extensions: []
186
228
  extra_rdoc_files: []
187
229
  files:
188
- - ".gitignore"
189
- - Gemfile
190
230
  - README.md
191
231
  - Rakefile
192
232
  - lib/logjam_agent.rb
193
233
  - lib/logjam_agent/actionpack/lib/action_dispatch/middleware/remote_ip.rb
234
+ - lib/logjam_agent/active_support/core_ext/array/extract.rb
235
+ - lib/logjam_agent/active_support/parameter_filter.rb
194
236
  - lib/logjam_agent/buffered_logger.rb
195
237
  - lib/logjam_agent/forwarders.rb
196
238
  - lib/logjam_agent/middleware.rb
197
239
  - lib/logjam_agent/rack/logger.rb
240
+ - lib/logjam_agent/rack/rails_support.rb
241
+ - lib/logjam_agent/rack/sinatra_request.rb
198
242
  - lib/logjam_agent/railtie.rb
243
+ - lib/logjam_agent/receiver.rb
199
244
  - lib/logjam_agent/request.rb
245
+ - lib/logjam_agent/sinatra.rb
200
246
  - lib/logjam_agent/syslog_like_formatter.rb
201
247
  - lib/logjam_agent/util.rb
202
248
  - lib/logjam_agent/version.rb
203
249
  - lib/logjam_agent/zmq_forwarder.rb
204
- - logjam_agent.gemspec
205
- - script/console
206
250
  - test/request_test.rb
251
+ - test/sinatra_app.rb
252
+ - test/sinatra_classic_app.rb
253
+ - test/sinatra_classic_test.rb
254
+ - test/sinatra_test.rb
207
255
  - test/test_helper.rb
208
256
  - test/util_test.rb
209
257
  - test/zmq_forwarder_test.rb
210
- homepage: ''
211
- licenses: []
258
+ homepage: https://github.com/skaes/logjam_agent
259
+ licenses:
260
+ - MIT
212
261
  metadata: {}
213
- post_install_message:
262
+ post_install_message:
214
263
  rdoc_options: []
215
264
  require_paths:
216
265
  - lib
@@ -225,12 +274,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
274
  - !ruby/object:Gem::Version
226
275
  version: '0'
227
276
  requirements: []
228
- rubygems_version: 3.0.6
229
- signing_key:
277
+ rubygems_version: 3.1.2
278
+ signing_key:
230
279
  specification_version: 4
231
280
  summary: Logjam client library to be used with logjam
232
281
  test_files:
282
+ - test/sinatra_app.rb
283
+ - test/sinatra_classic_test.rb
284
+ - test/sinatra_classic_app.rb
233
285
  - test/request_test.rb
234
- - test/test_helper.rb
235
- - test/util_test.rb
236
286
  - test/zmq_forwarder_test.rb
287
+ - test/util_test.rb
288
+ - test/test_helper.rb
289
+ - test/sinatra_test.rb
data/.gitignore DELETED
@@ -1,5 +0,0 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- pkg/*
5
- .rvmrc
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in logjam_agent.gemspec
4
- gemspec
@@ -1,32 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "logjam_agent/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "logjam_agent"
7
- s.version = LogjamAgent::VERSION
8
- s.authors = ["Stefan Kaes"]
9
- s.email = ["stefan.kaes@xing.com"]
10
- s.homepage = ""
11
- s.summary = %q{Logjam client library to be used with logjam}
12
- s.description = %q{Logjam logger and request information forwarding}
13
-
14
- s.files = `git ls-files`.split("\n")
15
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
- s.require_paths = ["lib"]
18
-
19
- s.add_development_dependency "rake"
20
- s.add_development_dependency "i18n"
21
- s.add_development_dependency "snappy"
22
- s.add_development_dependency "lz4-ruby"
23
- s.add_development_dependency "oj"
24
- s.add_development_dependency "byebug"
25
- s.add_development_dependency "minitest"
26
- s.add_development_dependency "mocha"
27
-
28
- s.add_runtime_dependency "activesupport"
29
- s.add_runtime_dependency "time_bandits", [">= 0.6.0"]
30
- s.add_runtime_dependency "ffi-rzmq-core", [">= 1.0.5"]
31
- s.add_runtime_dependency "ffi-rzmq", [">= 2.0.4"]
32
- end
@@ -1,28 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'optparse'
3
-
4
- options = { }
5
- OptionParser.new do |opt|
6
- opt.banner = "Usage: console [options]"
7
- opt.on("--debugger", 'Enable ruby-debugging for the console.') { |v| options[:debugger] = v }
8
- opt.parse!(ARGV)
9
- end
10
-
11
- lib_dir = File.expand_path("../../lib/", __FILE__)
12
- libs = " -r irb/completion"
13
- libs << " -I #{lib_dir}"
14
- libs << " -r #{lib_dir}/logjam_agent.rb"
15
-
16
- if options[:debugger]
17
- begin
18
- require 'byebug'
19
- libs << " -r byebug"
20
- puts "=> Debugger enabled"
21
- rescue Exception
22
- puts "You need to install ruby-debug to run the console in debugging mode. With gems, use 'gem install ruby-debug'"
23
- exit
24
- end
25
- end
26
-
27
- irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
28
- exec "#{irb} #{libs} --simple-prompt"