logjam_agent 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +86 -0
- data/lib/logjam_agent.rb +31 -1
- data/lib/logjam_agent/amqp_forwarder.rb +5 -4
- data/lib/logjam_agent/rack/logger.rb +11 -4
- data/lib/logjam_agent/railtie.rb +16 -3
- data/lib/logjam_agent/version.rb +1 -1
- data/lib/logjam_agent/zmq_forwarder.rb +5 -4
- metadata +3 -3
- data/README.rdoc +0 -8
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDhjMTU4YjU0MGMxMzVkN2JjNzhiOTU0ZjhhYjRkZTljY2ZkZTM5Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MWE0YzJiZWE3YjE3YjI4MzZiOTY5OGYyODExZWFkOWI0NWM0ZDBjNw==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MDc1ZmQyZTdlZjRkNjFmMjhlMzQ2NWQ0MGJjM2E3YWVhMGEzYjZiMTEzOWI0
|
10
|
+
NzQ5YjExMWRhMTQxOWY5MmM4ODllN2EwOWIxMjQyNjAwODk5MmJhMWJiOWRh
|
11
|
+
M2RiZGRmMTEyMmE0M2U3ZWY0Zjk5ODg2ZjlmYzRlOWEwOTg5NjA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZTRjMGUzMjFjN2M5ODVmNTczYzJjMmQ3Y2UyNzA4NjY3YjhjMTI5ODA4ZjMz
|
14
|
+
ODJkNzIwNjAzMjRlZGQ4YjE4ODZhODQ1ZGQwYmM0OTQ5YjcyZWViZjdjYWJk
|
15
|
+
YjVlNWRkMWRmOTZhZWYwYjhiYjEzMjhlNDlkNTQ4ODY5ZDg1NGI=
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# Logjam Agent
|
2
|
+
|
3
|
+
Client side library for logjam.
|
4
|
+
|
5
|
+
Hooks into Rails, collects log lines, performance metrics, error/exception infomation and Rack
|
6
|
+
environment information and sends this data to [Logjam](https://github.com/skaes/logjam_app).
|
7
|
+
|
8
|
+
Currently two alternate mechanisms are available for data transport: AMQP or ZeroMQ.
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
For AMQP, add
|
13
|
+
|
14
|
+
gem "logjam_agent"
|
15
|
+
gem "bunny"
|
16
|
+
|
17
|
+
For ZeroMQ, add
|
18
|
+
|
19
|
+
gem "logjam_agent"
|
20
|
+
gem "ffi-rzmq"
|
21
|
+
|
22
|
+
to your Gemfile.
|
23
|
+
|
24
|
+
Add an initializer
|
25
|
+
config/initializers/logjam_agent.rb
|
26
|
+
to your app and configure class LogjamAgent.
|
27
|
+
|
28
|
+
````ruby
|
29
|
+
module LogjamAgent
|
30
|
+
# Configure the application name (required). Must not contain dots of hyphens.
|
31
|
+
self.application_name = "myapp"
|
32
|
+
|
33
|
+
# Configure the environment name (optional). Defaults to Rails.env.
|
34
|
+
# self.environment_name = Rails.env
|
35
|
+
|
36
|
+
# Configure request data forwarder for ZeroMQ.
|
37
|
+
add_forwarder(:zmq, :host => "logjam.instance.at.your.org", :port => 9605)
|
38
|
+
|
39
|
+
# Configure request data forwarder for ZeroMQ.
|
40
|
+
# add_forwarder(:amqp, :host => "message.broker.at.your.org"))
|
41
|
+
|
42
|
+
# Configure ip obfuscation. Defaults to no obfuscation.
|
43
|
+
self.obfuscate_ips = true
|
44
|
+
|
45
|
+
# Configure cookie obfuscation. Defaults to [/_session\z/].
|
46
|
+
# self.obfuscated_cookies = [/_session\z/]
|
47
|
+
end
|
48
|
+
````
|
49
|
+
|
50
|
+
## Troubleshooting
|
51
|
+
|
52
|
+
If the agent experiences problems when sending data, it will log information to a file named
|
53
|
+
`logjam_agent_error_log` which you can find under `Rails.root/log`.
|
54
|
+
|
55
|
+
This behavior is customizable via a module level call back method:
|
56
|
+
|
57
|
+
LogjamAgent.error_handler = lambda {|exception| ... }
|
58
|
+
|
59
|
+
# License
|
60
|
+
|
61
|
+
The MIT License
|
62
|
+
|
63
|
+
Copyright (c) 2013 Stefan Kaes
|
64
|
+
|
65
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
66
|
+
of this software and associated documentation files (the "Software"), to deal
|
67
|
+
in the Software without restriction, including without limitation the rights
|
68
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
69
|
+
copies of the Software, and to permit persons to whom the Software is
|
70
|
+
furnished to do so, subject to the following conditions:
|
71
|
+
|
72
|
+
The above copyright notice and this permission notice shall be included in
|
73
|
+
all copies or substantial portions of the Software.
|
74
|
+
|
75
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
76
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
77
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
78
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
79
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
80
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
81
|
+
THE SOFTWARE.
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
data/lib/logjam_agent.rb
CHANGED
@@ -47,8 +47,13 @@ module LogjamAgent
|
|
47
47
|
mattr_accessor :logger
|
48
48
|
self.logger = nil
|
49
49
|
|
50
|
+
mattr_accessor :forwarding_error_logger
|
51
|
+
self.forwarding_error_logger = nil
|
52
|
+
|
50
53
|
mattr_accessor :error_handler
|
51
|
-
self.error_handler = lambda
|
54
|
+
self.error_handler = lambda do |exception|
|
55
|
+
forwarding_error_logger.error "#{exception.class.name}: #{exception.message}" if forwarding_error_logger
|
56
|
+
end
|
52
57
|
|
53
58
|
mattr_accessor :application_name
|
54
59
|
self.application_name = nil
|
@@ -82,6 +87,21 @@ module LogjamAgent
|
|
82
87
|
mattr_accessor :disabled
|
83
88
|
self.disabled = false
|
84
89
|
|
90
|
+
mattr_accessor :obfuscate_ips
|
91
|
+
self.obfuscate_ips = false
|
92
|
+
|
93
|
+
# TODO: ipv6 obfuscation
|
94
|
+
def self.ip_fuscator(ip)
|
95
|
+
obfuscate_ips ? ip.to_s.sub(/\d+\z/, 'XXX') : ip
|
96
|
+
end
|
97
|
+
|
98
|
+
mattr_accessor :obfuscated_cookies
|
99
|
+
self.obfuscated_cookies = [/_session\z/]
|
100
|
+
|
101
|
+
def self.cookie_obfuscator
|
102
|
+
@cookie_obfuscator ||= ActionDispatch::Http::ParameterFilter.new(obfuscated_cookies)
|
103
|
+
end
|
104
|
+
|
85
105
|
extend RequestHandling
|
86
106
|
|
87
107
|
mattr_accessor :exception_classes
|
@@ -109,6 +129,7 @@ module LogjamAgent
|
|
109
129
|
end
|
110
130
|
|
111
131
|
def self.auto_detect_logged_exceptions
|
132
|
+
return if @_exception_auto_detection_initialized
|
112
133
|
determine_loaded_exception_classes
|
113
134
|
Exception.class_eval <<-"EOS"
|
114
135
|
def self.inherited(subclass)
|
@@ -116,6 +137,7 @@ module LogjamAgent
|
|
116
137
|
::LogjamAgent.reset_exception_matcher
|
117
138
|
end
|
118
139
|
EOS
|
140
|
+
@_exception_auto_detection_initialized = true
|
119
141
|
end
|
120
142
|
|
121
143
|
# setup uuid generation
|
@@ -152,6 +174,14 @@ module LogjamAgent
|
|
152
174
|
forwarder.forward(encode_payload(fields), :routing_key => events_routing_key)
|
153
175
|
end
|
154
176
|
|
177
|
+
def self.add_forwarder(type, *args)
|
178
|
+
case type
|
179
|
+
when :zmq then Forwarders.add(ZMQForwarder.new(*args))
|
180
|
+
when :amqp then Forwarders.add(AMQPForwarder.new(*args))
|
181
|
+
else raise ArgumentError.new("unkown logjam transport: '#{type}'")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
155
185
|
private
|
156
186
|
|
157
187
|
def self.events_routing_key
|
@@ -5,10 +5,11 @@ module LogjamAgent
|
|
5
5
|
|
6
6
|
attr_reader :app, :env
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
|
10
|
-
@
|
11
|
-
@
|
8
|
+
def initialize(*args)
|
9
|
+
opts = args.extract_options!
|
10
|
+
@app = args[0] || LogjamAgent.application_name
|
11
|
+
@env = args[1] || LogjamAgent.environment_name
|
12
|
+
@config = default_options(@app, @env).merge!(opts)
|
12
13
|
@exchange = @bunny = nil
|
13
14
|
ensure_bunny_gem_is_available
|
14
15
|
end
|
@@ -53,11 +53,11 @@ module LogjamAgent
|
|
53
53
|
path = request.filtered_path
|
54
54
|
|
55
55
|
logjam_fields = LogjamAgent.request.fields
|
56
|
-
|
56
|
+
ip = LogjamAgent.ip_fuscator(request.remote_ip)
|
57
|
+
logjam_fields.merge!(:started_at => start_time.iso8601, :ip => ip, :host => @hostname)
|
57
58
|
logjam_fields.merge!(extract_request_info(request))
|
58
59
|
|
59
|
-
|
60
|
-
info "Started #{request.request_method} \"#{path}\" for #{request.ip} at #{start_time.to_default_s}"
|
60
|
+
info "Started #{request.request_method} \"#{path}\" for #{ip} at #{start_time.to_default_s}"
|
61
61
|
end
|
62
62
|
|
63
63
|
def after_dispatch(env, result, run_time_ms)
|
@@ -108,7 +108,7 @@ module LogjamAgent
|
|
108
108
|
result
|
109
109
|
end
|
110
110
|
|
111
|
-
HIDDEN_VARIABLES = /\A([a-z]|SERVER|PATH|GATEWAY|REQUEST|SCRIPT|REMOTE|QUERY|PASSENGER|DOCUMENT|SCGI|UNION_STATION|
|
111
|
+
HIDDEN_VARIABLES = /\A([a-z]|SERVER|PATH|GATEWAY|REQUEST|SCRIPT|REMOTE|QUERY|PASSENGER|DOCUMENT|SCGI|UNION_STATION|ORIGINAL_|ROUTES_|RAW_POST_DATA)/o
|
112
112
|
|
113
113
|
TRANSLATED_VARIABLES = /\A(HTTP|CONTENT_LENGTH|CONTENT_TYPE)/
|
114
114
|
|
@@ -118,6 +118,7 @@ module LogjamAgent
|
|
118
118
|
|
119
119
|
REFERER = 'HTTP_REFERER'
|
120
120
|
CONTENT_LENGTH = 'CONTENT_LENGTH'
|
121
|
+
COOKIE = 'HTTP_COOKIE'
|
121
122
|
|
122
123
|
KV_RE = '[^&;=]+'
|
123
124
|
PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})}
|
@@ -133,6 +134,12 @@ module LogjamAgent
|
|
133
134
|
end
|
134
135
|
end
|
135
136
|
|
137
|
+
if cookie = headers[COOKIE]
|
138
|
+
headers[COOKIE] = cookie.gsub(PAIR_RE) do |_|
|
139
|
+
LogjamAgent.cookie_obfuscator.filter([[$1, $2]]).first.join("=")
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
136
143
|
headers.keys.each do |k|
|
137
144
|
if t = TRANSLATED_KEYS[k]
|
138
145
|
headers[t] = headers.delete(k)
|
data/lib/logjam_agent/railtie.rb
CHANGED
@@ -8,12 +8,15 @@ module LogjamAgent
|
|
8
8
|
autoload :Middleware, 'logjam_agent/middleware'
|
9
9
|
|
10
10
|
class Railtie < Rails::Railtie
|
11
|
+
def logjam_log_path(app)
|
12
|
+
paths = app.config.paths
|
13
|
+
(Rails::VERSION::STRING < "3.1" ? paths.log.to_a : paths['log']).first.to_s
|
14
|
+
end
|
11
15
|
|
12
16
|
initializer "initialize_logjam_agent_logger", :before => :initialize_logger do |app|
|
13
17
|
Rails.logger ||= app.config.logger ||
|
14
18
|
begin
|
15
|
-
|
16
|
-
path = (Rails::VERSION::STRING < "3.1" ? paths.log.to_a : paths['log']).first.to_s
|
19
|
+
path = logjam_log_path(app)
|
17
20
|
logger = LogjamAgent::BufferedLogger.new(path)
|
18
21
|
logger.level = ::Logger.const_get(app.config.log_level.to_s.upcase)
|
19
22
|
logger.formatter = LogjamAgent::SyslogLikeFormatter.new
|
@@ -38,9 +41,19 @@ module LogjamAgent
|
|
38
41
|
end
|
39
42
|
|
40
43
|
initializer "logjam_agent", :after => "time_bandits" do |app|
|
44
|
+
LogjamAgent.environment_name = Rails.env
|
45
|
+
LogjamAgent.auto_detect_logged_exceptions
|
46
|
+
|
41
47
|
app.config.middleware.swap("TimeBandits::Rack::Logger", "LogjamAgent::Rack::Logger")
|
42
48
|
app.config.middleware.insert_before("LogjamAgent::Rack::Logger", "LogjamAgent::Middleware")
|
43
49
|
|
50
|
+
# install a default error handler for forwarding errors
|
51
|
+
log_dir = File.dirname(logjam_log_path(app))
|
52
|
+
forwarding_error_logger = ::Logger.new("#{log_dir}/logjam_agent_error.log")
|
53
|
+
forwarding_error_logger.level = ::Logger::ERROR
|
54
|
+
forwarding_error_logger.formatter = ::Logger::Formatter.new
|
55
|
+
LogjamAgent.forwarding_error_logger = forwarding_error_logger
|
56
|
+
|
44
57
|
# patch controller testing to create a logjam request, because middlewares aren't executed
|
45
58
|
if Rails.env.test?
|
46
59
|
ActiveSupport.on_load(:action_controller) do
|
@@ -58,7 +71,7 @@ module LogjamAgent
|
|
58
71
|
end
|
59
72
|
end
|
60
73
|
|
61
|
-
#
|
74
|
+
# avoid garbled tempfile information in the logs
|
62
75
|
ActiveSupport.on_load(:action_controller) do
|
63
76
|
ActionDispatch::Http::UploadedFile.class_eval <<-"EVA"
|
64
77
|
def to_hash
|
data/lib/logjam_agent/version.rb
CHANGED
@@ -2,10 +2,11 @@ module LogjamAgent
|
|
2
2
|
class ZMQForwarder
|
3
3
|
attr_reader :app, :env
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
|
7
|
-
@
|
8
|
-
@
|
5
|
+
def initialize(*args)
|
6
|
+
opts = args.extract_options!
|
7
|
+
@app = args[0] || LogjamAgent.application_name
|
8
|
+
@env = args[1] || LogjamAgent.environment_name
|
9
|
+
@config = default_options(@app, @env).merge!(opts)
|
9
10
|
@exchange = @config[:exchange]
|
10
11
|
@zmq_hosts = Array(@config[:host])
|
11
12
|
@zmq_port = @config[:port]
|
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.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Kaes
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,7 +75,7 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- .gitignore
|
77
77
|
- Gemfile
|
78
|
-
- README.
|
78
|
+
- README.md
|
79
79
|
- Rakefile
|
80
80
|
- lib/logjam_agent.rb
|
81
81
|
- lib/logjam_agent/amqp_forwarder.rb
|