logjam_agent 0.30.0 → 0.31.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.
- checksums.yaml +4 -4
- data/README.md +49 -28
- data/Rakefile +5 -0
- data/lib/logjam_agent.rb +7 -3
- data/lib/logjam_agent/active_support/core_ext/array/extract.rb +21 -0
- data/lib/logjam_agent/active_support/parameter_filter.rb +128 -0
- data/lib/logjam_agent/buffered_logger.rb +17 -42
- data/lib/logjam_agent/middleware.rb +15 -3
- data/lib/logjam_agent/rack/logger.rb +19 -81
- data/lib/logjam_agent/rack/rails_support.rb +26 -0
- data/lib/logjam_agent/rack/sinatra_request.rb +32 -0
- data/lib/logjam_agent/railtie.rb +3 -0
- data/lib/logjam_agent/receiver.rb +22 -0
- data/lib/logjam_agent/sinatra.rb +116 -0
- data/lib/logjam_agent/syslog_like_formatter.rb +1 -1
- data/lib/logjam_agent/util.rb +6 -1
- data/lib/logjam_agent/version.rb +1 -1
- data/lib/logjam_agent/zmq_forwarder.rb +8 -2
- data/test/sinatra_app.rb +32 -0
- data/test/sinatra_classic_app.rb +31 -0
- data/test/sinatra_classic_test.rb +20 -0
- data/test/sinatra_test.rb +54 -0
- data/test/test_helper.rb +6 -1
- data/test/util_test.rb +5 -0
- metadata +69 -16
- data/.gitignore +0 -5
- data/Gemfile +0 -4
- data/logjam_agent.gemspec +0 -32
- data/script/console +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b543de9e4f7a8d5ae896a7c2fa4524a8b220a1dad8a6b4e1be6b5eee4c8110e
|
4
|
+
data.tar.gz: 62f2aee617a120107307e625b2ba2df8fb461f53ba9fa3baff0ce0187fc1325f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
+
[](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
|
114
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
162
|
+
The environment name is picked up from either the environment variable `LOGJAM_ENV`, or
|
163
|
+
Sinatra's environment setting.
|
137
164
|
|
138
|
-
|
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
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
-
|
150
|
-
all copies or substantial portions of the Software.
|
175
|
+
This behavior is customizable via a module level call back method:
|
151
176
|
|
152
|
-
|
153
|
-
|
154
|
-
|
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
|
data/lib/logjam_agent.rb
CHANGED
@@ -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)
|
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
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
33
|
-
|
34
|
-
end
|
11
|
+
def format_time(timestamp)
|
12
|
+
timestamp.strftime("%H:%M:%S.#{"%06d" % timestamp.usec}")
|
35
13
|
end
|
14
|
+
end
|
36
15
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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 <
|
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,
|
3
|
+
def initialize(app, framework = :rails)
|
4
4
|
@app = app
|
5
|
-
@
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
206
|
-
|
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
|
data/lib/logjam_agent/railtie.rb
CHANGED
@@ -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)
|
data/lib/logjam_agent/util.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/logjam_agent/version.rb
CHANGED
@@ -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
|
-
|
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: #{
|
108
|
+
raise "ZMQ error on publishing: #{error}"
|
103
109
|
end
|
104
110
|
end
|
105
111
|
|
data/test/sinatra_app.rb
ADDED
@@ -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
|
data/test/test_helper.rb
CHANGED
@@ -8,4 +8,9 @@ class MiniTest::Test
|
|
8
8
|
extend ActiveSupport::Testing::Declarative
|
9
9
|
end
|
10
10
|
|
11
|
-
|
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"
|
data/test/util_test.rb
CHANGED
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.
|
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-
|
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.
|
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.
|
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.
|
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/Gemfile
DELETED
data/logjam_agent.gemspec
DELETED
@@ -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
|
data/script/console
DELETED
@@ -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"
|