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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OGVlMTVjMWMzMTI1YzcxNzM3NTExZTc1MjQ3NmJkOTcxN2VhOTcyYw==
4
+ ZDhjMTU4YjU0MGMxMzVkN2JjNzhiOTU0ZjhhYjRkZTljY2ZkZTM5Mg==
5
5
  data.tar.gz: !binary |-
6
- YWI2N2Q1NTFkOTMxMTRlZWQwMjNlYWVlZGZmZGI1YjhmZGE4NDQwZA==
6
+ MWE0YzJiZWE3YjE3YjI4MzZiOTY5OGYyODExZWFkOWI0NWM0ZDBjNw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YWEzMTVkNTUyNDUxMTZmZDUyNTY3YTNlMDI2NmI2YzgzMjM1NDI1ZWU0MmEz
10
- MzdjZTA4ZmVjZTZiNjVkNTliOGU3ZmFhMTEzOTRkNGI1NzYyNmNlNTdkNWYw
11
- ZTdkNjNjNjdlNWMxMjA4MmYwY2JmYmZmOTdiZGE5ZjAxNGZkMTc=
9
+ MDc1ZmQyZTdlZjRkNjFmMjhlMzQ2NWQ0MGJjM2E3YWVhMGEzYjZiMTEzOWI0
10
+ NzQ5YjExMWRhMTQxOWY5MmM4ODllN2EwOWIxMjQyNjAwODk5MmJhMWJiOWRh
11
+ M2RiZGRmMTEyMmE0M2U3ZWY0Zjk5ODg2ZjlmYzRlOWEwOTg5NjA=
12
12
  data.tar.gz: !binary |-
13
- MDFlYTczMzNjMThlNDlmNTE0OTJmZTdlNzE4MTdmMzQ1OWU0MTRmYmEyODA0
14
- ODkzOTJjOTZmZTA4NThmZjBkZTk0YjM5ZmRjNTUyNWMwZmNkMDI1OWJlZjM5
15
- NzYwY2VhMTlhNjQwYTQ5NDUxZTU1MjQ3NjBlNzczZThkM2ZlODM=
13
+ ZTRjMGUzMjFjN2M5ODVmNTczYzJjMmQ3Y2UyNzA4NjY3YjhjMTI5ODA4ZjMz
14
+ ODJkNzIwNjAzMjRlZGQ4YjE4ODZhODQ1ZGQwYmM0OTQ5YjcyZWViZjdjYWJk
15
+ YjVlNWRkMWRmOTZhZWYwYjhiYjEzMjhlNDlkNTQ4ODY5ZDg1NGI=
@@ -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
+
@@ -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 { |exception| }
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(app, env, opts = {})
9
- @app = app
10
- @env = env
11
- @config = default_options(app, env).merge!(opts)
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
- logjam_fields.merge!(:started_at => start_time.iso8601, :ip => request.remote_ip, :host => @hostname)
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
- debug ""
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|ORIGINAL_FULLPATH|RAW_POST_DATA)/o
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)
@@ -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
- paths = app.config.paths
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
- # make
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
@@ -1,3 +1,3 @@
1
1
  module LogjamAgent
2
- VERSION = "0.9.0"
2
+ VERSION = "0.9.1"
3
3
  end
@@ -2,10 +2,11 @@ module LogjamAgent
2
2
  class ZMQForwarder
3
3
  attr_reader :app, :env
4
4
 
5
- def initialize(app, env, opts = {})
6
- @app = app
7
- @env = env
8
- @config = default_options(app, env).merge!(opts)
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.0
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-23 00:00:00.000000000 Z
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.rdoc
78
+ - README.md
79
79
  - Rakefile
80
80
  - lib/logjam_agent.rb
81
81
  - lib/logjam_agent/amqp_forwarder.rb
@@ -1,8 +0,0 @@
1
- == Logjam Agent
2
-
3
- Client side library for logjam.
4
-
5
- Provides a customized logger, which logs lines and sends combined request information via
6
- AMQP or ZeroMQ to logjam.
7
-
8
-