Skip to content

Commit 4b8920f

Browse files
committed
Merge branch '1-x-stable'
forwardport Resque.logging from 1.x Conflicts: .gitignore Gemfile HISTORY.md lib/resque/version.rb lib/resque/worker.rb test/resque_failure_redis_test.rb test/test_helper.rb test/worker_test.rb
2 parents 642eb69 + 4763c81 commit 4b8920f

File tree

11 files changed

+297
-31
lines changed

11 files changed

+297
-31
lines changed

HISTORY.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
* Changed failures retry process to requeue. (@KensoDev #703)
44

5+
## 1.23.0 (2012-10-01)
6+
7+
* don't run `before_fork` hook if Resque can't fork (@kjwierenga, @tarcieri, #672, #697)
8+
* don't run `after_fork` hook if Resque can't fork (@kjwierenga, @tarcieri, #672, #697)
9+
* retry connecting to redis up to 3 times (@trevorturk, #693)
10+
* pass exceptions raised by the worker into the Failure backend (@trevorturk, #693)
11+
512
## 1.22.0 (2012-08-21)
613

714
* unregister signal handlers in child process when ENV["TERM_CHILD"] is set (@dylanasmith, #621)

lib/resque.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'logger'
12
require 'redis/namespace'
23

34
require 'resque/version'
@@ -9,6 +10,10 @@
910

1011
require 'resque/helpers'
1112
require 'resque/stat'
13+
require 'resque/logging'
14+
require 'resque/log_formatters/quiet_formatter'
15+
require 'resque/log_formatters/verbose_formatter'
16+
require 'resque/log_formatters/very_verbose_formatter'
1217
require 'resque/job'
1318
require 'resque/worker'
1419
require 'resque/plugin'
@@ -80,6 +85,9 @@ def redis_id
8085
end
8186
end
8287

88+
# Set or retrieve the current logger object
89+
attr_accessor :logger
90+
8391
# The `before_first_fork` hook will be run in the **parent** process
8492
# only once, before forking to run the first job. Be careful- any
8593
# changes you make will be permanent for the lifespan of the
@@ -444,3 +452,6 @@ def hooks(name)
444452
end
445453
end
446454

455+
# Log to STDOUT by default
456+
Resque.logger = Logger.new(STDOUT)
457+
Resque.logger.formatter = Resque::QuietFormatter.new
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module Resque
2+
class QuietFormatter
3+
def call(serverity, datetime, progname, msg)
4+
""
5+
end
6+
end
7+
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module Resque
2+
class VerboseFormatter
3+
def call(serverity, datetime, progname, msg)
4+
"*** #{msg}"
5+
end
6+
end
7+
end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module Resque
2+
class VeryVerboseFormatter
3+
def call(serverity, datetime, progname, msg)
4+
time = Time.now.strftime('%H:%M:%S %Y-%m-%d')
5+
"** [#{time}] #$$: #{msg}"
6+
end
7+
end
8+
end

lib/resque/logging.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module Resque
2+
# Include this module in classes you wish to have logging facilities
3+
module Logging
4+
module_function
5+
6+
# Thunk to the logger's own log method (if configured)
7+
def self.log(severity, message)
8+
Resque.logger.__send__(severity, message) if Resque.logger
9+
end
10+
11+
# Log level aliases
12+
def debug(message); Logging.log :debug, message; end
13+
def info(message); Logging.log :info, message; end
14+
def warn(message); Logging.log :warn, message; end
15+
def error(message); Logging.log :error, message; end
16+
def fatal(message); Logging.log :fatal, message; end
17+
end
18+
end

lib/resque/worker.rb

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,9 @@ module Resque
99
# It also ensures workers are always listening to signals from you,
1010
# their master, and can react accordingly.
1111
class Worker
12+
extend Resque::Helpers
1213
include Resque::Helpers
13-
extend Resque::Helpers
14-
15-
# Whether the worker should log basic info to STDOUT
16-
attr_accessor :verbose
17-
18-
# Whether the worker should log lots of info to STDOUT
19-
attr_accessor :very_verbose
14+
include Resque::Logging
2015

2116
# Boolean indicating whether this worker can or can not fork.
2217
# Automatically set if a fork(2) fails.
@@ -241,6 +236,24 @@ def reconnect
241236
end
242237
end
243238

239+
# Reconnect to Redis to avoid sharing a connection with the parent,
240+
# retry up to 3 times with increasing delay before giving up.
241+
def reconnect
242+
tries = 0
243+
begin
244+
redis.client.reconnect
245+
rescue Redis::BaseConnectionError
246+
if (tries += 1) <= 3
247+
log "Error reconnecting to Redis; retrying"
248+
sleep(tries)
249+
retry
250+
else
251+
log "Error reconnecting to Redis; quitting"
252+
raise
253+
end
254+
end
255+
end
256+
244257
# Returns a list of queues to use when searching for a job.
245258
# A splat ("*") means you want every queue (in alpha order) - this
246259
# can be useful for dynamically adding new queues. Low priority queues
@@ -612,17 +625,62 @@ def procline(string)
612625
log! $0
613626
end
614627

615-
# Log a message to STDOUT if we are verbose or very_verbose.
628+
# Log a message to Resque.logger
629+
# can't use alias_method since info/debug are private methods
616630
def log(message)
617-
if verbose || very_verbose
618-
time = Time.now.strftime('%H:%M:%S %Y-%m-%d')
619-
puts "[#{time}] #$$: #{message}"
620-
end
631+
info(message)
621632
end
622633

623-
# Logs a very verbose message to STDOUT.
624634
def log!(message)
625-
log message if very_verbose
635+
debug(message)
636+
end
637+
638+
# Deprecated legacy methods for controlling the logging threshhold
639+
# Use Resque.logger.level now, e.g.:
640+
#
641+
# Resque.logger.level = Logger::DEBUG
642+
#
643+
def verbose
644+
logger_severity_deprecation_warning
645+
@verbose
646+
end
647+
648+
def very_verbose
649+
logger_severity_deprecation_warning
650+
@very_verbose
651+
end
652+
653+
def verbose=(value);
654+
logger_severity_deprecation_warning
655+
656+
if value && !very_verbose
657+
Resque.logger.formatter = VerboseFormatter.new
658+
elsif !value
659+
Resque.logger.formatter = QuietFormatter.new
660+
end
661+
662+
@verbose = value
663+
end
664+
665+
def very_verbose=(value)
666+
logger_severity_deprecation_warning
667+
if value
668+
Resque.logger.formatter = VeryVerboseFormatter.new
669+
elsif !value && verbose
670+
Resque.logger.formatter = VerboseFormatter.new
671+
else
672+
Resque.logger.formatter = QuietFormatter.new
673+
end
674+
675+
@very_verbose = value
676+
end
677+
678+
def logger_severity_deprecation_warning
679+
return if $warned_logger_severity_deprecation
680+
Kernel.warn "*** DEPRECATION WARNING: Resque::Worker#verbose and #very_verbose are deprecated. Please set Resque.logger.level instead"
681+
Kernel.warn "Called from: #{caller[0..5].join("\n\t")}"
682+
$warned_logger_severity_deprecation = true
683+
nil
626684
end
627685
end
628686
end

log/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*

test/logging_test.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
require 'test_helper'
2+
require 'minitest/mock'
3+
4+
describe "Resque::Logging" do
5+
after { reset_logger }
6+
7+
it "sets and receives the active logger" do
8+
my_logger = Object.new
9+
Resque.logger = my_logger
10+
assert_equal my_logger, Resque.logger
11+
end
12+
13+
%w(debug info error fatal).each do |severity|
14+
it "logs #{severity} messages" do
15+
message = "test message"
16+
mock_logger = MiniTest::Mock.new
17+
mock_logger.expect severity.to_sym, nil, [message]
18+
Resque.logger = mock_logger
19+
20+
Resque::Logging.send severity, message
21+
mock_logger.verify
22+
end
23+
end
24+
end

test/test_helper.rb

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
require 'timeout'
33
require 'bundler/setup'
44
require 'redis/namespace'
5-
require 'minitest/unit'
6-
require 'minitest/spec'
5+
require 'minitest/autorun'
76

87
$dir = File.dirname(File.expand_path(__FILE__))
98
$LOAD_PATH.unshift $dir + '/../lib'
@@ -26,17 +25,12 @@
2625
# kill it when they end
2726
#
2827

29-
at_exit do
30-
next if $!
31-
32-
exit_code = MiniTest::Unit.new.run(ARGV)
33-
28+
MiniTest::Unit.after_tests do
3429
processes = `ps -A -o pid,command | grep [r]edis-test`.split($/)
3530
pids = processes.map { |process| process.split(" ")[0] }
3631
puts "Killing test redis server..."
3732
pids.each { |pid| Process.kill("TERM", pid.to_i) }
3833
system("rm -f #{$dir}/dump.rdb #{$dir}/dump-cluster.rdb")
39-
exit exit_code
4034
end
4135

4236
if ENV.key? 'RESQUE_DISTRIBUTED'
@@ -143,3 +137,27 @@ def now
143137

144138
self.fake_time = nil
145139
end
140+
141+
# From minitest/unit
142+
def capture_io
143+
require 'stringio'
144+
145+
orig_stdout, orig_stderr = $stdout, $stderr
146+
captured_stdout, captured_stderr = StringIO.new, StringIO.new
147+
$stdout, $stderr = captured_stdout, captured_stderr
148+
149+
yield
150+
151+
return captured_stdout.string, captured_stderr.string
152+
ensure
153+
$stdout = orig_stdout
154+
$stderr = orig_stderr
155+
end
156+
157+
# Log to log/test.log
158+
def reset_logger
159+
$test_logger ||= Logger.new(File.open(File.expand_path("../../log/test.log", __FILE__), "w"))
160+
Resque.logger = $test_logger
161+
end
162+
163+
reset_logger

0 commit comments

Comments
 (0)