thin 1.7.2 → 2.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of thin might be problematic. Click here for more details.
- data/.gitignore +9 -0
- data/CHANGELOG +29 -107
- data/Gemfile +8 -0
- data/README.md +44 -78
- data/Rakefile +28 -18
- data/bin/thin +4 -4
- data/examples/async.ru +21 -0
- data/examples/thin.conf.rb +39 -0
- data/lib/thin.rb +2 -44
- data/lib/thin/async.rb +108 -0
- data/lib/thin/backends/prefork.rb +44 -0
- data/lib/thin/backends/single_process.rb +28 -0
- data/lib/thin/chunked_body.rb +28 -0
- data/lib/thin/configurator.rb +118 -0
- data/lib/thin/connection.rb +246 -172
- data/lib/thin/listener.rb +114 -0
- data/lib/thin/request.rb +94 -74
- data/lib/thin/response.rb +112 -45
- data/lib/thin/runner.rb +134 -197
- data/lib/thin/server.rb +203 -252
- data/lib/thin/system.rb +49 -0
- data/lib/thin/version.rb +14 -29
- data/man/index.txt +3 -0
- data/man/thin-conf.5.ronn +121 -0
- data/man/thin.1.ronn +105 -0
- data/site/.gitignore +2 -0
- data/site/README.md +21 -0
- data/site/Rakefile +20 -0
- data/site/config.ru +4 -0
- data/site/public/images/grid.png +0 -0
- data/site/public/javascripts/dd_belatedpng.js +13 -0
- data/site/public/javascripts/modernizr-1.6.min.js +30 -0
- data/site/public/man/thin-conf.5.html +220 -0
- data/site/public/man/thin.1.html +177 -0
- data/site/site/assets/javascripts/main.coffee +2 -0
- data/site/site/assets/stylesheets/_config.scss +55 -0
- data/site/site/assets/stylesheets/main.scss +24 -0
- data/site/site/helpers.rb +17 -0
- data/site/site/layouts/base.erb +55 -0
- data/site/site/layouts/default.erb +17 -0
- data/site/site/pages/about.md +5 -0
- data/site/site/pages/index.erb +10 -0
- data/site/site/partials/.gitkeep +0 -0
- data/test/fixtures/big.txt +1 -0
- data/test/fixtures/small.txt +1 -0
- data/test/fixtures/thin.conf.rb +15 -0
- data/test/integration/async_test.rb +35 -0
- data/test/integration/big_request_test.rb +30 -0
- data/test/integration/config.ru +57 -0
- data/test/integration/daemonize_test.rb +26 -0
- data/test/integration/env_test.rb +44 -0
- data/test/integration/error_test.rb +37 -0
- data/test/integration/file_sending_test.rb +24 -0
- data/test/integration/keep_alive_test.rb +35 -0
- data/test/integration/robustness_test.rb +37 -0
- data/test/integration/single_process_test.rb +15 -0
- data/test/integration/socket_family_test.rb +38 -0
- data/test/integration/worker_test.rb +22 -0
- data/test/test_helper.rb +195 -0
- data/test/unit/configurator_test.rb +43 -0
- data/test/unit/connection_test.rb +94 -0
- data/test/unit/listener_test.rb +74 -0
- data/test/unit/request_test.rb +74 -0
- data/test/unit/response_test.rb +90 -0
- data/test/unit/server_test.rb +29 -0
- data/test/unit/system_test.rb +17 -0
- data/thin.gemspec +26 -0
- data/v2.todo +21 -0
- metadata +134 -89
- checksums.yaml +0 -7
- data/example/adapter.rb +0 -32
- data/example/async_app.ru +0 -126
- data/example/async_chat.ru +0 -247
- data/example/async_tailer.ru +0 -100
- data/example/config.ru +0 -22
- data/example/monit_sockets +0 -20
- data/example/monit_unixsock +0 -20
- data/example/myapp.rb +0 -1
- data/example/ramaze.ru +0 -12
- data/example/thin.god +0 -80
- data/example/thin_solaris_smf.erb +0 -36
- data/example/thin_solaris_smf.readme.txt +0 -150
- data/example/vlad.rake +0 -72
- data/ext/thin_parser/common.rl +0 -59
- data/ext/thin_parser/ext_help.h +0 -14
- data/ext/thin_parser/extconf.rb +0 -6
- data/ext/thin_parser/parser.c +0 -1447
- data/ext/thin_parser/parser.h +0 -49
- data/ext/thin_parser/parser.rl +0 -152
- data/ext/thin_parser/thin.c +0 -435
- data/lib/rack/adapter/loader.rb +0 -75
- data/lib/rack/adapter/rails.rb +0 -178
- data/lib/thin/backends/base.rb +0 -167
- data/lib/thin/backends/swiftiply_client.rb +0 -56
- data/lib/thin/backends/tcp_server.rb +0 -34
- data/lib/thin/backends/unix_server.rb +0 -56
- data/lib/thin/command.rb +0 -53
- data/lib/thin/controllers/cluster.rb +0 -178
- data/lib/thin/controllers/controller.rb +0 -189
- data/lib/thin/controllers/service.rb +0 -76
- data/lib/thin/controllers/service.sh.erb +0 -39
- data/lib/thin/daemonizing.rb +0 -180
- data/lib/thin/headers.rb +0 -40
- data/lib/thin/logging.rb +0 -174
- data/lib/thin/stats.html.erb +0 -216
- data/lib/thin/stats.rb +0 -52
- data/lib/thin/statuses.rb +0 -44
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'erb'
|
2
|
-
|
3
|
-
module Thin
|
4
|
-
module Controllers
|
5
|
-
# System service controller to launch all servers which
|
6
|
-
# config files are in a directory.
|
7
|
-
class Service < Controller
|
8
|
-
INITD_PATH = File.directory?('/etc/rc.d') ? '/etc/rc.d/thin' : '/etc/init.d/thin'
|
9
|
-
DEFAULT_CONFIG_PATH = '/etc/thin'
|
10
|
-
TEMPLATE = File.dirname(__FILE__) + '/service.sh.erb'
|
11
|
-
|
12
|
-
def initialize(options)
|
13
|
-
super
|
14
|
-
|
15
|
-
raise PlatformNotSupported, 'Running as a service only supported on Linux' unless Thin.linux?
|
16
|
-
end
|
17
|
-
|
18
|
-
def config_path
|
19
|
-
@options[:all] || DEFAULT_CONFIG_PATH
|
20
|
-
end
|
21
|
-
|
22
|
-
def start
|
23
|
-
run :start
|
24
|
-
end
|
25
|
-
|
26
|
-
def stop
|
27
|
-
run :stop
|
28
|
-
end
|
29
|
-
|
30
|
-
def restart
|
31
|
-
run :restart
|
32
|
-
end
|
33
|
-
|
34
|
-
def install(config_files_path=DEFAULT_CONFIG_PATH)
|
35
|
-
if File.exist?(INITD_PATH)
|
36
|
-
log_info "Thin service already installed at #{INITD_PATH}"
|
37
|
-
else
|
38
|
-
log_info "Installing thin service at #{INITD_PATH} ..."
|
39
|
-
sh "mkdir -p #{File.dirname(INITD_PATH)}"
|
40
|
-
log_info "writing #{INITD_PATH}"
|
41
|
-
File.open(INITD_PATH, 'w') do |f|
|
42
|
-
f << ERB.new(File.read(TEMPLATE)).result(binding)
|
43
|
-
end
|
44
|
-
sh "chmod +x #{INITD_PATH}" # Make executable
|
45
|
-
end
|
46
|
-
|
47
|
-
sh "mkdir -p #{config_files_path}"
|
48
|
-
|
49
|
-
log_info ''
|
50
|
-
log_info "To configure thin to start at system boot:"
|
51
|
-
log_info "on RedHat like systems:"
|
52
|
-
log_info " sudo /sbin/chkconfig --level 345 #{NAME} on"
|
53
|
-
log_info "on Debian-like systems (Ubuntu):"
|
54
|
-
log_info " sudo /usr/sbin/update-rc.d -f #{NAME} defaults"
|
55
|
-
log_info "on Gentoo:"
|
56
|
-
log_info " sudo rc-update add #{NAME} default"
|
57
|
-
log_info ''
|
58
|
-
log_info "Then put your config files in #{config_files_path}"
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
def run(command)
|
63
|
-
Dir[config_path + '/*'].each do |config|
|
64
|
-
next if config.end_with?("~")
|
65
|
-
log_info "[#{command}] #{config} ..."
|
66
|
-
Command.run(command, :config => config, :daemonize => true)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def sh(cmd)
|
71
|
-
log_info cmd
|
72
|
-
system(cmd)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
#!/bin/sh
|
2
|
-
### BEGIN INIT INFO
|
3
|
-
# Provides: thin
|
4
|
-
# Required-Start: $local_fs $remote_fs
|
5
|
-
# Required-Stop: $local_fs $remote_fs
|
6
|
-
# Default-Start: 2 3 4 5
|
7
|
-
# Default-Stop: S 0 1 6
|
8
|
-
# Short-Description: thin initscript
|
9
|
-
# Description: thin
|
10
|
-
### END INIT INFO
|
11
|
-
|
12
|
-
# Original author: Forrest Robertson
|
13
|
-
|
14
|
-
# Do NOT "set -e"
|
15
|
-
|
16
|
-
DAEMON=<%= Command.script %>
|
17
|
-
SCRIPT_NAME=<%= INITD_PATH %>
|
18
|
-
CONFIG_PATH=<%= config_files_path %>
|
19
|
-
|
20
|
-
# Exit if the package is not installed
|
21
|
-
[ -x "$DAEMON" ] || exit 0
|
22
|
-
|
23
|
-
case "$1" in
|
24
|
-
start)
|
25
|
-
$DAEMON start --all $CONFIG_PATH
|
26
|
-
;;
|
27
|
-
stop)
|
28
|
-
$DAEMON stop --all $CONFIG_PATH
|
29
|
-
;;
|
30
|
-
restart)
|
31
|
-
$DAEMON restart --all $CONFIG_PATH
|
32
|
-
;;
|
33
|
-
*)
|
34
|
-
echo "Usage: $SCRIPT_NAME {start|stop|restart}" >&2
|
35
|
-
exit 3
|
36
|
-
;;
|
37
|
-
esac
|
38
|
-
|
39
|
-
:
|
data/lib/thin/daemonizing.rb
DELETED
@@ -1,180 +0,0 @@
|
|
1
|
-
require 'etc'
|
2
|
-
require 'daemons' unless Thin.win?
|
3
|
-
|
4
|
-
module Process
|
5
|
-
# Returns +true+ the process identied by +pid+ is running.
|
6
|
-
def running?(pid)
|
7
|
-
Process.getpgid(pid) != -1
|
8
|
-
rescue Errno::EPERM
|
9
|
-
true
|
10
|
-
rescue Errno::ESRCH
|
11
|
-
false
|
12
|
-
end
|
13
|
-
module_function :running?
|
14
|
-
end
|
15
|
-
|
16
|
-
module Thin
|
17
|
-
# Raised when the pid file already exist starting as a daemon.
|
18
|
-
class PidFileExist < RuntimeError; end
|
19
|
-
class PidFileNotFound < RuntimeError; end
|
20
|
-
|
21
|
-
# Module included in classes that can be turned into a daemon.
|
22
|
-
# Handle stuff like:
|
23
|
-
# * storing the PID in a file
|
24
|
-
# * redirecting output to the log file
|
25
|
-
# * changing process privileges
|
26
|
-
# * killing the process gracefully
|
27
|
-
module Daemonizable
|
28
|
-
attr_accessor :pid_file, :log_file
|
29
|
-
|
30
|
-
def self.included(base)
|
31
|
-
base.extend ClassMethods
|
32
|
-
end
|
33
|
-
|
34
|
-
def pid
|
35
|
-
File.exist?(pid_file) && !File.zero?(pid_file) ? open(pid_file).read.to_i : nil
|
36
|
-
end
|
37
|
-
|
38
|
-
# Turns the current script into a daemon process that detaches from the console.
|
39
|
-
def daemonize
|
40
|
-
raise PlatformNotSupported, 'Daemonizing is not supported on Windows' if Thin.win?
|
41
|
-
raise ArgumentError, 'You must specify a pid_file to daemonize' unless @pid_file
|
42
|
-
|
43
|
-
remove_stale_pid_file
|
44
|
-
|
45
|
-
pwd = Dir.pwd # Current directory is changed during daemonization, so store it
|
46
|
-
|
47
|
-
# HACK we need to create the directory before daemonization to prevent a bug under 1.9
|
48
|
-
# ignoring all signals when the directory is created after daemonization.
|
49
|
-
FileUtils.mkdir_p File.dirname(@pid_file)
|
50
|
-
FileUtils.mkdir_p File.dirname(@log_file)
|
51
|
-
|
52
|
-
Daemonize.daemonize(File.expand_path(@log_file), name)
|
53
|
-
|
54
|
-
Dir.chdir(pwd)
|
55
|
-
|
56
|
-
write_pid_file
|
57
|
-
|
58
|
-
at_exit do
|
59
|
-
log_info "Exiting!"
|
60
|
-
remove_pid_file
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Change privileges of the process
|
65
|
-
# to the specified user and group.
|
66
|
-
def change_privilege(user, group=user)
|
67
|
-
log_info "Changing process privilege to #{user}:#{group}"
|
68
|
-
|
69
|
-
uid, gid = Process.euid, Process.egid
|
70
|
-
target_uid = Etc.getpwnam(user).uid
|
71
|
-
target_gid = Etc.getgrnam(group).gid
|
72
|
-
|
73
|
-
if uid != target_uid || gid != target_gid
|
74
|
-
# Change PID file ownership
|
75
|
-
File.chown(target_uid, target_gid, @pid_file) if File.exists?(@pid_file)
|
76
|
-
|
77
|
-
# Change process ownership
|
78
|
-
Process.initgroups(user, target_gid)
|
79
|
-
Process::GID.change_privilege(target_gid)
|
80
|
-
Process::UID.change_privilege(target_uid)
|
81
|
-
end
|
82
|
-
rescue Errno::EPERM => e
|
83
|
-
log_info "Couldn't change user and group to #{user}:#{group}: #{e}"
|
84
|
-
end
|
85
|
-
|
86
|
-
# Register a proc to be called to restart the server.
|
87
|
-
def on_restart(&block)
|
88
|
-
@on_restart = block
|
89
|
-
end
|
90
|
-
|
91
|
-
# Restart the server.
|
92
|
-
def restart
|
93
|
-
if @on_restart
|
94
|
-
log_info 'Restarting ...'
|
95
|
-
stop
|
96
|
-
remove_pid_file
|
97
|
-
@on_restart.call
|
98
|
-
EM.next_tick { exit! }
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
module ClassMethods
|
103
|
-
# Send a QUIT or INT (if timeout is +0+) signal the process which
|
104
|
-
# PID is stored in +pid_file+.
|
105
|
-
# If the process is still running after +timeout+, KILL signal is
|
106
|
-
# sent.
|
107
|
-
def kill(pid_file, timeout=60)
|
108
|
-
if timeout == 0
|
109
|
-
send_signal('INT', pid_file, timeout)
|
110
|
-
else
|
111
|
-
send_signal('QUIT', pid_file, timeout)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# Restart the server by sending HUP signal.
|
116
|
-
def restart(pid_file)
|
117
|
-
send_signal('HUP', pid_file)
|
118
|
-
end
|
119
|
-
|
120
|
-
# Send a +signal+ to the process which PID is stored in +pid_file+.
|
121
|
-
def send_signal(signal, pid_file, timeout=60)
|
122
|
-
if pid = read_pid_file(pid_file)
|
123
|
-
Logging.log_info "Sending #{signal} signal to process #{pid} ... "
|
124
|
-
Process.kill(signal, pid)
|
125
|
-
Timeout.timeout(timeout) do
|
126
|
-
sleep 0.1 while Process.running?(pid)
|
127
|
-
end
|
128
|
-
else
|
129
|
-
raise PidFileNotFound, "Can't stop process, no PID found in #{pid_file}"
|
130
|
-
end
|
131
|
-
rescue Timeout::Error
|
132
|
-
Logging.log_info "Timeout!"
|
133
|
-
force_kill(pid, pid_file)
|
134
|
-
rescue Interrupt
|
135
|
-
force_kill(pid, pid_file)
|
136
|
-
rescue Errno::ESRCH # No such process
|
137
|
-
Logging.log_info "process not found!"
|
138
|
-
force_kill(pid, pid_file)
|
139
|
-
end
|
140
|
-
|
141
|
-
def force_kill(pid, pid_file)
|
142
|
-
Logging.log_info "Sending KILL signal to process #{pid} ... "
|
143
|
-
Process.kill("KILL", pid)
|
144
|
-
File.delete(pid_file) if File.exist?(pid_file)
|
145
|
-
end
|
146
|
-
|
147
|
-
def read_pid_file(file)
|
148
|
-
if File.file?(file) && pid = File.read(file)
|
149
|
-
pid.to_i
|
150
|
-
else
|
151
|
-
nil
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
protected
|
157
|
-
def remove_pid_file
|
158
|
-
File.delete(@pid_file) if @pid_file && File.exists?(@pid_file)
|
159
|
-
end
|
160
|
-
|
161
|
-
def write_pid_file
|
162
|
-
log_info "Writing PID to #{@pid_file}"
|
163
|
-
open(@pid_file,"w") { |f| f.write(Process.pid) }
|
164
|
-
File.chmod(0644, @pid_file)
|
165
|
-
end
|
166
|
-
|
167
|
-
# If PID file is stale, remove it.
|
168
|
-
def remove_stale_pid_file
|
169
|
-
if File.exist?(@pid_file)
|
170
|
-
if pid && Process.running?(pid)
|
171
|
-
raise PidFileExist, "#{@pid_file} already exists, seems like it's already running (process ID: #{pid}). " +
|
172
|
-
"Stop the process or delete #{@pid_file}."
|
173
|
-
else
|
174
|
-
log_info "Deleting stale PID file #{@pid_file}"
|
175
|
-
remove_pid_file
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
data/lib/thin/headers.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
module Thin
|
2
|
-
# Store HTTP header name-value pairs direcly to a string
|
3
|
-
# and allow duplicated entries on some names.
|
4
|
-
class Headers
|
5
|
-
HEADER_FORMAT = "%s: %s\r\n".freeze
|
6
|
-
ALLOWED_DUPLICATES = %w(set-cookie set-cookie2 warning www-authenticate).freeze
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@sent = {}
|
10
|
-
@out = []
|
11
|
-
end
|
12
|
-
|
13
|
-
# Add <tt>key: value</tt> pair to the headers.
|
14
|
-
# Ignore if already sent and no duplicates are allowed
|
15
|
-
# for this +key+.
|
16
|
-
def []=(key, value)
|
17
|
-
downcase_key = key.downcase
|
18
|
-
if !@sent.has_key?(downcase_key) || ALLOWED_DUPLICATES.include?(downcase_key)
|
19
|
-
@sent[downcase_key] = true
|
20
|
-
value = case value
|
21
|
-
when Time
|
22
|
-
value.httpdate
|
23
|
-
when NilClass
|
24
|
-
return
|
25
|
-
else
|
26
|
-
value.to_s
|
27
|
-
end
|
28
|
-
@out << HEADER_FORMAT % [key, value]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def has_key?(key)
|
33
|
-
@sent[key.downcase]
|
34
|
-
end
|
35
|
-
|
36
|
-
def to_s
|
37
|
-
@out.join
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
data/lib/thin/logging.rb
DELETED
@@ -1,174 +0,0 @@
|
|
1
|
-
require 'logger'
|
2
|
-
|
3
|
-
module Thin
|
4
|
-
# To be included in classes to allow some basic logging
|
5
|
-
# that can be silenced (<tt>Logging.silent=</tt>) or made
|
6
|
-
# more verbose.
|
7
|
-
# <tt>Logging.trace=</tt>: log all raw request and response and
|
8
|
-
# messages logged with +trace+.
|
9
|
-
# <tt>Logging.silent=</tt>: silence all log all log messages
|
10
|
-
# altogether.
|
11
|
-
module Logging
|
12
|
-
# Simple formatter which only displays the message.
|
13
|
-
# Taken from ActiveSupport
|
14
|
-
class SimpleFormatter < Logger::Formatter
|
15
|
-
def call(severity, timestamp, progname, msg)
|
16
|
-
"#{String === msg ? msg : msg.inspect}\n"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
@trace_logger = nil
|
21
|
-
|
22
|
-
class << self
|
23
|
-
attr_reader :logger
|
24
|
-
attr_reader :trace_logger
|
25
|
-
|
26
|
-
def trace=(enabled)
|
27
|
-
if enabled
|
28
|
-
@trace_logger ||= Logger.new(STDOUT)
|
29
|
-
else
|
30
|
-
@trace_logger = nil
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def trace?
|
35
|
-
!@trace_logger.nil?
|
36
|
-
end
|
37
|
-
|
38
|
-
def silent=(shh)
|
39
|
-
if shh
|
40
|
-
@logger = nil
|
41
|
-
else
|
42
|
-
@logger ||= Logger.new(STDOUT)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def silent?
|
47
|
-
!@logger.nil?
|
48
|
-
end
|
49
|
-
|
50
|
-
def level
|
51
|
-
@logger ? @logger.level : nil # or 'silent'
|
52
|
-
end
|
53
|
-
|
54
|
-
def level=(value)
|
55
|
-
# If logging has been silenced, then re-enable logging
|
56
|
-
@logger = Logger.new(STDOUT) if @logger.nil?
|
57
|
-
@logger.level = value
|
58
|
-
end
|
59
|
-
|
60
|
-
# Allow user to specify a custom logger to use.
|
61
|
-
# This object must respond to:
|
62
|
-
# +level+, +level=+ and +debug+, +info+, +warn+, +error+, +fatal+
|
63
|
-
def logger=(custom_logger)
|
64
|
-
[ :level ,
|
65
|
-
:level= ,
|
66
|
-
:debug ,
|
67
|
-
:info ,
|
68
|
-
:warn ,
|
69
|
-
:error ,
|
70
|
-
:fatal ,
|
71
|
-
:unknown ,
|
72
|
-
].each do |method|
|
73
|
-
if not custom_logger.respond_to?(method)
|
74
|
-
raise ArgumentError, "logger must respond to #{method}"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
@logger = custom_logger
|
79
|
-
end
|
80
|
-
|
81
|
-
def trace_logger=(custom_tracer)
|
82
|
-
[ :level ,
|
83
|
-
:level= ,
|
84
|
-
:debug ,
|
85
|
-
:info ,
|
86
|
-
:warn ,
|
87
|
-
:error ,
|
88
|
-
:fatal ,
|
89
|
-
:unknown ,
|
90
|
-
].each do |method|
|
91
|
-
if not custom_tracer.respond_to?(method)
|
92
|
-
raise ArgumentError, "trace logger must respond to #{method}"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
@trace_logger = custom_tracer
|
97
|
-
end
|
98
|
-
|
99
|
-
def log_msg(msg, level=Logger::INFO)
|
100
|
-
return unless @logger
|
101
|
-
@logger.add(level, msg)
|
102
|
-
end
|
103
|
-
|
104
|
-
def trace_msg(msg)
|
105
|
-
return unless @trace_logger
|
106
|
-
@trace_logger.info(msg)
|
107
|
-
end
|
108
|
-
|
109
|
-
# Provided for backwards compatibility.
|
110
|
-
# Callers should be using the +level+ (on the +Logging+ module
|
111
|
-
# or on the instance) to figure out what the log level is.
|
112
|
-
def debug?
|
113
|
-
self.level == Logger::DEBUG
|
114
|
-
end
|
115
|
-
def debug=(val)
|
116
|
-
self.level = (val ? Logger::DEBUG : Logger::INFO)
|
117
|
-
end
|
118
|
-
|
119
|
-
end # module methods
|
120
|
-
|
121
|
-
# Default logger to stdout.
|
122
|
-
self.logger = Logger.new(STDOUT)
|
123
|
-
self.logger.level = Logger::INFO
|
124
|
-
self.logger.formatter = Logging::SimpleFormatter.new
|
125
|
-
|
126
|
-
def silent
|
127
|
-
Logging.silent?
|
128
|
-
end
|
129
|
-
|
130
|
-
def silent=(value)
|
131
|
-
Logging.silent = value
|
132
|
-
end
|
133
|
-
|
134
|
-
# Log a message if tracing is activated
|
135
|
-
def trace(msg=nil)
|
136
|
-
Logging.trace_msg(msg) if msg
|
137
|
-
end
|
138
|
-
module_function :trace
|
139
|
-
public :trace
|
140
|
-
|
141
|
-
# Log a message at DEBUG level
|
142
|
-
def log_debug(msg=nil)
|
143
|
-
Logging.log_msg(msg || yield, Logger::DEBUG)
|
144
|
-
end
|
145
|
-
module_function :log_debug
|
146
|
-
public :log_debug
|
147
|
-
|
148
|
-
# Log a message at INFO level
|
149
|
-
def log_info(msg)
|
150
|
-
Logging.log_msg(msg || yield, Logger::INFO)
|
151
|
-
end
|
152
|
-
module_function :log_info
|
153
|
-
public :log_info
|
154
|
-
|
155
|
-
# Log a message at ERROR level (and maybe a backtrace)
|
156
|
-
def log_error(msg, e=nil)
|
157
|
-
log_msg = msg
|
158
|
-
if e
|
159
|
-
log_msg += ": #{e}\n\t" + e.backtrace.join("\n\t") + "\n"
|
160
|
-
end
|
161
|
-
Logging.log_msg(log_msg, Logger::ERROR)
|
162
|
-
end
|
163
|
-
module_function :log_error
|
164
|
-
public :log_error
|
165
|
-
|
166
|
-
# For backwards compatibility
|
167
|
-
def log msg
|
168
|
-
STDERR.puts('#log has been deprecated, please use the ' \
|
169
|
-
'log_level function instead (e.g. - log_info).')
|
170
|
-
log_info(msg)
|
171
|
-
end
|
172
|
-
|
173
|
-
end
|
174
|
-
end
|