amqp_logging 0.5.0 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,15 +3,23 @@ require 'bunny'
3
3
  begin
4
4
  # ActiveSupport 3.x
5
5
  require 'active_support/time'
6
+ require 'active_support/core_ext/module/aliasing'
6
7
  require 'active_support/core_ext/hash/slice'
7
8
  rescue LoadError
8
- require 'active_support' # ActiveSupport 2.x
9
+ # ActiveSupport 2.x
10
+ require 'active_support'
9
11
  end
10
12
 
11
13
  module AMQPLogging
12
14
  autoload :MetricsAgent, 'amqp_logging/metrics_agent'
15
+
16
+ private
17
+ def self.iso_time_with_microseconds(t = Time.now)
18
+ t.strftime("%Y-%m-%dT%H:%M:%S.#{t.usec}")
19
+ end
13
20
  end
14
21
 
15
22
  require 'logger'
16
23
  require 'amqp_logging/logger'
17
24
  require 'amqp_logging/log_device'
25
+ require 'amqp_logging/ext/qrack/client'
@@ -0,0 +1,44 @@
1
+ require 'qrack/client'
2
+
3
+
4
+ unless Qrack::Client.instance_methods.include?("socket_with_reliable_timeout")
5
+ module AMQPLogging
6
+ Timer = if RUBY_VERSION < "1.9"
7
+ begin
8
+ require 'system_timer'
9
+ SystemTimer
10
+ rescue LoadError
11
+ require 'timeout'
12
+ Timeout
13
+ end
14
+ else
15
+ require 'timeout'
16
+ Timeout
17
+ end
18
+ end
19
+
20
+ module Qrack
21
+ class Client
22
+ # overwrite the timeout method so that SystemTimer is used
23
+ # instead the standard timeout.rb: http://ph7spot.com/musings/system-timer
24
+ delegate :timeout, :to => AMQPLogging::Timer
25
+
26
+ def socket_with_reliable_timeout
27
+ socket_without_reliable_timeout
28
+
29
+ secs = Integer(CONNECT_TIMEOUT)
30
+ usecs = Integer((CONNECT_TIMEOUT - secs) * 1_000_000)
31
+ optval = [secs, usecs].pack("l_2")
32
+
33
+ begin
34
+ @socket.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
35
+ @socket.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
36
+ rescue Errno::ENOPROTOOPT
37
+ end
38
+ @socket
39
+ end
40
+ alias_method_chain :socket, :reliable_timeout
41
+
42
+ end
43
+ end
44
+ end
@@ -3,7 +3,9 @@ require 'json'
3
3
 
4
4
  module AMQPLogging
5
5
  class MetricsAgent
6
+ DEFAULT_MAX_LINES_PER_LOGGER = 1000
6
7
  attr_reader :fields
8
+ attr_accessor :max_lines_per_logger
7
9
 
8
10
  def initialize
9
11
  @default_fields = {
@@ -13,6 +15,7 @@ module AMQPLogging
13
15
  :default => []
14
16
  }
15
17
  }
18
+ @max_lines_per_logger = DEFAULT_MAX_LINES_PER_LOGGER
16
19
  @logger_types = {}
17
20
  reset_fields
18
21
  end
@@ -41,9 +44,19 @@ module AMQPLogging
41
44
  end
42
45
 
43
46
  def add_logline(severity, message, progname, logger)
44
- t = Time.now
45
- msg = (message || progname).strip
46
- @fields[:loglines][@logger_types[logger]] << [severity, t.strftime("%Y-%d-%mT%H:%M:%S.#{t.usec}"), msg]
47
+ timestring = AMQPLogging.iso_time_with_microseconds
48
+ logtype = @logger_types[logger]
49
+ lines = @fields[:loglines][logtype]
50
+ if !@truncated_status[logtype] && lines.size < @max_lines_per_logger
51
+ msg = (message || progname).strip
52
+ lines << [severity, timestring, msg]
53
+ true
54
+ else
55
+ msg = "Loglines truncated to #{@max_lines_per_logger} lines (MetricsAgent#max_lines_per_logger)"
56
+ lines[-1] = [Logger::INFO, timestring, msg]
57
+ @truncated_status[logtype] = true
58
+ false
59
+ end
47
60
  end
48
61
 
49
62
  def wrap_logger(logger, type = :default)
@@ -58,6 +71,10 @@ module AMQPLogging
58
71
  logger
59
72
  end
60
73
 
74
+ def dirty?
75
+ @fields != @default_fields
76
+ end
77
+
61
78
  private
62
79
  def register_logger(logger, type)
63
80
  @logger_types[logger] = type
@@ -68,6 +85,7 @@ module AMQPLogging
68
85
  @fields = {
69
86
  }.merge!(@default_fields)
70
87
  @logger_types.values.each {|logtype| @fields[:loglines][logtype] = []}
88
+ @truncated_status = {}
71
89
  end
72
90
 
73
91
  module MetricsAgentSupport
@@ -8,8 +8,7 @@ end
8
8
  class ActionController::Base
9
9
  def log_processing_for_request_id_with_metrics_agent
10
10
  logger.agent[:page] = "#{self.class.name}\##{action_name}"
11
- t = Time.now
12
- logger.agent[:started_at] = t.strftime("%Y-%d-%mT%H:%M:%S.#{t.usec}")
11
+ logger.agent[:started_at] = AMQPLogging.iso_time_with_microseconds
13
12
  log_processing_for_request_id_without_metrics_agent
14
13
  end
15
14
  alias_method_chain :log_processing_for_request_id, :metrics_agent
@@ -34,6 +34,21 @@ module AMQPLogging
34
34
  @agent.flush
35
35
  assert_equal nil, @agent[:foo]
36
36
  end
37
+
38
+ test "should keep track if the agents data is dirty" do
39
+ assert !@agent.dirty?
40
+
41
+ @agent[:foo] = :bar
42
+ assert @agent.dirty?
43
+ end
44
+
45
+ test "flushing should reset dirty status" do
46
+ @agent[:foo] = :bar
47
+ assert @agent.dirty?
48
+
49
+ @agent.flush
50
+ assert !@agent.dirty?
51
+ end
37
52
  end
38
53
 
39
54
  class LoggingProxyTest < Test::Unit::TestCase
@@ -104,5 +119,22 @@ module AMQPLogging
104
119
  @proxy.debug "\n\nfoo\n\n"
105
120
  assert_equal "foo", @agent[:loglines][:default][-1][2]
106
121
  end
122
+
123
+ test "should have a limit of loglines per logger after which they will get ignored" do
124
+ @agent.max_lines_per_logger = 2
125
+ @logger.debug "foo"
126
+ @logger.debug "bar"
127
+ no_lines_before = @agent[:loglines][:default].size
128
+ @logger.debug "baz"
129
+ assert_equal no_lines_before, @agent[:loglines][:default].size
130
+ end
131
+
132
+ test "should replace the last logged line with a truncation note if the limit of loglines is exceeded" do
133
+ @agent.max_lines_per_logger = 1
134
+ @logger.debug "foo"
135
+ assert_equal "foo", @agent[:loglines][:default].last[2]
136
+ @logger.debug "bar"
137
+ assert_match /truncated/, @agent[:loglines][:default].last[2]
138
+ end
107
139
  end
108
140
  end
@@ -4,8 +4,6 @@ require 'test/unit'
4
4
  require 'mocha'
5
5
  require 'active_support/testing/declarative'
6
6
 
7
- require File.expand_path(File.dirname(__FILE__) + '/../lib/amqp_logging')
8
-
9
7
  begin
10
8
  require 'redgreen' unless ENV['TM_FILENAME']
11
9
  rescue LoadError
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amqp_logging
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 1
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
- - 0
10
- version: 0.5.0
9
+ - 5
10
+ version: 0.5.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Pascal Friederich
@@ -104,6 +104,7 @@ extensions: []
104
104
  extra_rdoc_files:
105
105
  - Readme.rdoc
106
106
  files:
107
+ - lib/amqp_logging/ext/qrack/client.rb
107
108
  - lib/amqp_logging/log_device.rb
108
109
  - lib/amqp_logging/logger.rb
109
110
  - lib/amqp_logging/metrics_agent/rails/after_dispatch_callback_handler.rb
@@ -118,7 +119,7 @@ has_rdoc: true
118
119
  homepage: http://github.com/paukul/amqp_logging
119
120
  licenses: []
120
121
 
121
- post_install_message:
122
+ post_install_message: " *********************************************************************************************\n\n If you're running a ruby version < 1.9 please install the system_timer gem because rubys \n default timeout.rb isn't reliable.\n\n \"In particular, it is guaranteed to not work in Ruby M.R.I 1.8 when you are issuing \n system calls that can cause your Ruby process to sleep for a period of time that is \n longer than your timeout.\"\n\n See: http://ph7spot.com/musings/system-timer\n\n *********************************************************************************************\n"
122
123
  rdoc_options:
123
124
  - --charset=UTF-8
124
125
  require_paths: