thin 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG +11 -0
- data/ext/thin_parser/common.rl +8 -4
- data/ext/thin_parser/parser.c +531 -328
- data/ext/thin_parser/parser.rl +9 -9
- data/ext/thin_parser/thin.c +3 -4
- data/lib/thin/backends/base.rb +13 -3
- data/lib/thin/command.rb +2 -2
- data/lib/thin/connection.rb +19 -15
- data/lib/thin/controllers/cluster.rb +4 -4
- data/lib/thin/controllers/controller.rb +5 -4
- data/lib/thin/controllers/service.rb +16 -16
- data/lib/thin/daemonizing.rb +10 -12
- data/lib/thin/logging.rb +144 -33
- data/lib/thin/request.rb +7 -1
- data/lib/thin/runner.rb +23 -6
- data/lib/thin/server.rb +47 -33
- data/lib/thin/stats.rb +1 -1
- data/lib/thin/version.rb +3 -3
- metadata +17 -26
data/ext/thin_parser/parser.rl
CHANGED
@@ -109,7 +109,7 @@ size_t thin_http_parser_execute(http_parser *parser, const char *buffer, size_t
|
|
109
109
|
pe = buffer+len;
|
110
110
|
|
111
111
|
assert(*pe == '\0' && "pointer does not end on NUL");
|
112
|
-
assert(pe - p == len - off && "pointers aren't same distance");
|
112
|
+
assert(pe - p == (long)(len - off) && "pointers aren't same distance");
|
113
113
|
|
114
114
|
|
115
115
|
%% write exec;
|
@@ -132,6 +132,14 @@ size_t thin_http_parser_execute(http_parser *parser, const char *buffer, size_t
|
|
132
132
|
return(parser->nread);
|
133
133
|
}
|
134
134
|
|
135
|
+
int thin_http_parser_has_error(http_parser *parser) {
|
136
|
+
return parser->cs == http_parser_error;
|
137
|
+
}
|
138
|
+
|
139
|
+
int thin_http_parser_is_finished(http_parser *parser) {
|
140
|
+
return parser->cs == http_parser_first_final;
|
141
|
+
}
|
142
|
+
|
135
143
|
int thin_http_parser_finish(http_parser *parser)
|
136
144
|
{
|
137
145
|
int cs = parser->cs;
|
@@ -147,11 +155,3 @@ int thin_http_parser_finish(http_parser *parser)
|
|
147
155
|
return 0;
|
148
156
|
}
|
149
157
|
}
|
150
|
-
|
151
|
-
int thin_http_parser_has_error(http_parser *parser) {
|
152
|
-
return parser->cs == http_parser_error;
|
153
|
-
}
|
154
|
-
|
155
|
-
int thin_http_parser_is_finished(http_parser *parser) {
|
156
|
-
return parser->cs == http_parser_first_final;
|
157
|
-
}
|
data/ext/thin_parser/thin.c
CHANGED
@@ -71,7 +71,6 @@ DEF_MAX_LENGTH(REQUEST_PATH, 1024);
|
|
71
71
|
DEF_MAX_LENGTH(QUERY_STRING, (1024 * 10));
|
72
72
|
DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32)));
|
73
73
|
|
74
|
-
|
75
74
|
static void http_field(void *data, const char *field, size_t flen, const char *value, size_t vlen)
|
76
75
|
{
|
77
76
|
char *ch, *end;
|
@@ -87,10 +86,10 @@ static void http_field(void *data, const char *field, size_t flen, const char *v
|
|
87
86
|
f = rb_str_buf_cat(f, field, flen);
|
88
87
|
|
89
88
|
for(ch = RSTRING_PTR(f) + RSTRING_LEN(global_http_prefix), end = RSTRING_PTR(f) + RSTRING_LEN(f); ch < end; ch++) {
|
90
|
-
if(*ch
|
89
|
+
if (*ch >= 'a' && *ch <= 'z') {
|
90
|
+
*ch &= ~0x20; // upcase
|
91
|
+
} else if (*ch == '-') {
|
91
92
|
*ch = '_';
|
92
|
-
} else {
|
93
|
-
*ch = toupper(*ch);
|
94
93
|
}
|
95
94
|
}
|
96
95
|
|
data/lib/thin/backends/base.rb
CHANGED
@@ -22,11 +22,18 @@ module Thin
|
|
22
22
|
|
23
23
|
# Maximum number of connections that can be persistent
|
24
24
|
attr_accessor :maximum_persistent_connections
|
25
|
-
|
25
|
+
|
26
|
+
#allows setting of the eventmachine threadpool size
|
27
|
+
attr_reader :threadpool_size
|
28
|
+
def threadpool_size=(size)
|
29
|
+
@threadpool_size = size
|
30
|
+
EventMachine.threadpool_size = size
|
31
|
+
end
|
32
|
+
|
26
33
|
# Allow using threads in the backend.
|
27
34
|
attr_writer :threaded
|
28
35
|
def threaded?; @threaded end
|
29
|
-
|
36
|
+
|
30
37
|
# Allow using SSL in the backend.
|
31
38
|
attr_writer :ssl, :ssl_options
|
32
39
|
def ssl?; @ssl end
|
@@ -46,6 +53,7 @@ module Thin
|
|
46
53
|
@no_epoll = false
|
47
54
|
@ssl = nil
|
48
55
|
@threaded = nil
|
56
|
+
@started_reactor = false
|
49
57
|
end
|
50
58
|
|
51
59
|
# Start the backend and connect it.
|
@@ -53,6 +61,7 @@ module Thin
|
|
53
61
|
@stopping = false
|
54
62
|
starter = proc do
|
55
63
|
connect
|
64
|
+
yield if block_given?
|
56
65
|
@running = true
|
57
66
|
end
|
58
67
|
|
@@ -60,6 +69,7 @@ module Thin
|
|
60
69
|
if EventMachine.reactor_running?
|
61
70
|
starter.call
|
62
71
|
else
|
72
|
+
@started_reactor = true
|
63
73
|
EventMachine.run(&starter)
|
64
74
|
end
|
65
75
|
end
|
@@ -81,7 +91,7 @@ module Thin
|
|
81
91
|
@running = false
|
82
92
|
@stopping = false
|
83
93
|
|
84
|
-
EventMachine.stop if EventMachine.reactor_running?
|
94
|
+
EventMachine.stop if @started_reactor && EventMachine.reactor_running?
|
85
95
|
@connections.each_value { |connection| connection.close_connection }
|
86
96
|
close
|
87
97
|
end
|
data/lib/thin/command.rb
CHANGED
@@ -26,8 +26,8 @@ module Thin
|
|
26
26
|
trace shell_cmd
|
27
27
|
trap('INT') {} # Ignore INT signal to pass CTRL+C to subprocess
|
28
28
|
Open3.popen3(shell_cmd) do |stdin, stdout, stderr|
|
29
|
-
|
30
|
-
|
29
|
+
log_info stdout.gets until stdout.eof?
|
30
|
+
log_info stderr.gets until stderr.eof?
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
data/lib/thin/connection.rb
CHANGED
@@ -10,6 +10,8 @@ module Thin
|
|
10
10
|
# This is a template async response. N.B. Can't use string for body on 1.9
|
11
11
|
AsyncResponse = [-1, {}, []].freeze
|
12
12
|
|
13
|
+
EMPTY_BODY = [].freeze
|
14
|
+
|
13
15
|
# Rack application (adapter) served by this connection.
|
14
16
|
attr_accessor :app
|
15
17
|
|
@@ -35,11 +37,10 @@ module Thin
|
|
35
37
|
# Called when data is received from the client.
|
36
38
|
def receive_data(data)
|
37
39
|
@idle = false
|
38
|
-
trace
|
40
|
+
trace data
|
39
41
|
process if @request.parse(data)
|
40
42
|
rescue InvalidRequest => e
|
41
|
-
|
42
|
-
log_error e
|
43
|
+
log_error("Invalid request", e)
|
43
44
|
post_process Response::BAD_REQUEST
|
44
45
|
end
|
45
46
|
|
@@ -81,8 +82,8 @@ module Thin
|
|
81
82
|
response = @app.call(@request.env)
|
82
83
|
end
|
83
84
|
response
|
84
|
-
rescue Exception
|
85
|
-
|
85
|
+
rescue Exception => e
|
86
|
+
unexpected_error(e)
|
86
87
|
# Pass through error response
|
87
88
|
can_persist? && @request.persistent? ? Response::PERSISTENT_ERROR : Response::ERROR
|
88
89
|
end
|
@@ -96,19 +97,23 @@ module Thin
|
|
96
97
|
|
97
98
|
@response.status, @response.headers, @response.body = *result
|
98
99
|
|
99
|
-
|
100
|
+
log_error("Rack application returned nil body. " \
|
101
|
+
"Probably you wanted it to be an empty string?") if @response.body.nil?
|
102
|
+
|
103
|
+
# HEAD requests should not return a body.
|
104
|
+
@response.body = EMPTY_BODY if @request.head?
|
100
105
|
|
101
106
|
# Make the response persistent if requested by the client
|
102
107
|
@response.persistent! if @request.persistent?
|
103
108
|
|
104
109
|
# Send the response
|
105
110
|
@response.each do |chunk|
|
106
|
-
trace
|
111
|
+
trace chunk
|
107
112
|
send_data chunk
|
108
113
|
end
|
109
114
|
|
110
|
-
rescue Exception
|
111
|
-
|
115
|
+
rescue Exception => e
|
116
|
+
unexpected_error(e)
|
112
117
|
# Close connection since we can't handle response gracefully
|
113
118
|
close_connection
|
114
119
|
ensure
|
@@ -122,10 +127,9 @@ module Thin
|
|
122
127
|
end
|
123
128
|
end
|
124
129
|
|
125
|
-
# Logs
|
126
|
-
def
|
127
|
-
|
128
|
-
log_error
|
130
|
+
# Logs information about an unexpected exceptional condition
|
131
|
+
def unexpected_error(e)
|
132
|
+
log_error("Unexpected error while processing request", e)
|
129
133
|
end
|
130
134
|
|
131
135
|
def close_request_response
|
@@ -192,8 +196,8 @@ module Thin
|
|
192
196
|
# IP Address of the remote client.
|
193
197
|
def remote_address
|
194
198
|
socket_address
|
195
|
-
rescue Exception
|
196
|
-
log_error
|
199
|
+
rescue Exception => e
|
200
|
+
log_error('Could not infer remote address', e)
|
197
201
|
nil
|
198
202
|
end
|
199
203
|
|
@@ -45,7 +45,7 @@ module Thin
|
|
45
45
|
|
46
46
|
# Start a single server
|
47
47
|
def start_server(number)
|
48
|
-
|
48
|
+
log_info "Starting server on #{server_id(number)} ... "
|
49
49
|
|
50
50
|
run :start, number
|
51
51
|
end
|
@@ -57,7 +57,7 @@ module Thin
|
|
57
57
|
|
58
58
|
# Stop a single server
|
59
59
|
def stop_server(number)
|
60
|
-
|
60
|
+
log_info "Stopping server on #{server_id(number)} ... "
|
61
61
|
|
62
62
|
run :stop, number
|
63
63
|
end
|
@@ -91,7 +91,7 @@ module Thin
|
|
91
91
|
|
92
92
|
# Make sure the server is running before moving on to the next one.
|
93
93
|
def wait_until_server_started(number)
|
94
|
-
|
94
|
+
log_info "Waiting for server to start ..."
|
95
95
|
STDOUT.flush # Need this to make sure user got the message
|
96
96
|
|
97
97
|
tries = 0
|
@@ -175,4 +175,4 @@ module Thin
|
|
175
175
|
end
|
176
176
|
end
|
177
177
|
end
|
178
|
-
end
|
178
|
+
end
|
@@ -37,7 +37,7 @@ module Thin
|
|
37
37
|
def start
|
38
38
|
# Constantize backend class
|
39
39
|
@options[:backend] = eval(@options[:backend], TOPLEVEL_BINDING) if @options[:backend]
|
40
|
-
|
40
|
+
|
41
41
|
server = Server.new(@options[:socket] || @options[:address], # Server detects kind of socket
|
42
42
|
@options[:port], # Port ignored on UNIX socket
|
43
43
|
@options)
|
@@ -50,6 +50,7 @@ module Thin
|
|
50
50
|
server.maximum_persistent_connections = @options[:max_persistent_conns]
|
51
51
|
server.threaded = @options[:threaded]
|
52
52
|
server.no_epoll = @options[:no_epoll] if server.backend.respond_to?(:no_epoll=)
|
53
|
+
server.threadpool_size = @options[:threadpool_size] if server.threaded?
|
53
54
|
|
54
55
|
# ssl support
|
55
56
|
if @options[:ssl]
|
@@ -113,7 +114,7 @@ module Thin
|
|
113
114
|
@options.keys.each { |o| @options[o.to_s] = @options.delete(o) }
|
114
115
|
|
115
116
|
File.open(config_file, 'w') { |f| f << @options.to_yaml }
|
116
|
-
|
117
|
+
log_info "Wrote configuration to #{config_file}"
|
117
118
|
end
|
118
119
|
|
119
120
|
protected
|
@@ -165,7 +166,7 @@ module Thin
|
|
165
166
|
private
|
166
167
|
def load_adapter
|
167
168
|
adapter = @options[:adapter] || Rack::Adapter.guess(@options[:chdir])
|
168
|
-
|
169
|
+
log_info "Using #{adapter} adapter"
|
169
170
|
Rack::Adapter.for(adapter, @options)
|
170
171
|
rescue Rack::AdapterNotFound => e
|
171
172
|
raise InvalidOption, e.message
|
@@ -185,4 +186,4 @@ module Thin
|
|
185
186
|
end
|
186
187
|
end
|
187
188
|
end
|
188
|
-
end
|
189
|
+
end
|
@@ -33,11 +33,11 @@ module Thin
|
|
33
33
|
|
34
34
|
def install(config_files_path=DEFAULT_CONFIG_PATH)
|
35
35
|
if File.exist?(INITD_PATH)
|
36
|
-
|
36
|
+
log_info "Thin service already installed at #{INITD_PATH}"
|
37
37
|
else
|
38
|
-
|
38
|
+
log_info "Installing thin service at #{INITD_PATH} ..."
|
39
39
|
sh "mkdir -p #{File.dirname(INITD_PATH)}"
|
40
|
-
|
40
|
+
log_info "writing #{INITD_PATH}"
|
41
41
|
File.open(INITD_PATH, 'w') do |f|
|
42
42
|
f << ERB.new(File.read(TEMPLATE)).result(binding)
|
43
43
|
end
|
@@ -46,30 +46,30 @@ module Thin
|
|
46
46
|
|
47
47
|
sh "mkdir -p #{config_files_path}"
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
59
|
end
|
60
60
|
|
61
61
|
private
|
62
62
|
def run(command)
|
63
63
|
Dir[config_path + '/*'].each do |config|
|
64
|
-
|
64
|
+
log_info "[#{command}] #{config} ..."
|
65
65
|
Command.run(command, :config => config, :daemonize => true)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
69
|
def sh(cmd)
|
70
|
-
|
70
|
+
log_info cmd
|
71
71
|
system(cmd)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
75
|
-
end
|
75
|
+
end
|
data/lib/thin/daemonizing.rb
CHANGED
@@ -55,10 +55,8 @@ module Thin
|
|
55
55
|
|
56
56
|
write_pid_file
|
57
57
|
|
58
|
-
self.after_daemonize if self.respond_to? :after_daemonize
|
59
|
-
|
60
58
|
at_exit do
|
61
|
-
|
59
|
+
log_info "Exiting!"
|
62
60
|
remove_pid_file
|
63
61
|
end
|
64
62
|
end
|
@@ -66,7 +64,7 @@ module Thin
|
|
66
64
|
# Change privileges of the process
|
67
65
|
# to the specified user and group.
|
68
66
|
def change_privilege(user, group=user)
|
69
|
-
|
67
|
+
log_info "Changing process privilege to #{user}:#{group}"
|
70
68
|
|
71
69
|
uid, gid = Process.euid, Process.egid
|
72
70
|
target_uid = Etc.getpwnam(user).uid
|
@@ -82,7 +80,7 @@ module Thin
|
|
82
80
|
Process::UID.change_privilege(target_uid)
|
83
81
|
end
|
84
82
|
rescue Errno::EPERM => e
|
85
|
-
|
83
|
+
log_info "Couldn't change user and group to #{user}:#{group}: #{e}"
|
86
84
|
end
|
87
85
|
|
88
86
|
# Register a proc to be called to restart the server.
|
@@ -93,7 +91,7 @@ module Thin
|
|
93
91
|
# Restart the server.
|
94
92
|
def restart
|
95
93
|
if @on_restart
|
96
|
-
|
94
|
+
log_info 'Restarting ...'
|
97
95
|
stop
|
98
96
|
remove_pid_file
|
99
97
|
@on_restart.call
|
@@ -122,7 +120,7 @@ module Thin
|
|
122
120
|
# Send a +signal+ to the process which PID is stored in +pid_file+.
|
123
121
|
def send_signal(signal, pid_file, timeout=60)
|
124
122
|
if pid = read_pid_file(pid_file)
|
125
|
-
Logging.
|
123
|
+
Logging.log_info "Sending #{signal} signal to process #{pid} ... "
|
126
124
|
Process.kill(signal, pid)
|
127
125
|
Timeout.timeout(timeout) do
|
128
126
|
sleep 0.1 while Process.running?(pid)
|
@@ -131,17 +129,17 @@ module Thin
|
|
131
129
|
raise PidFileNotFound, "Can't stop process, no PID found in #{pid_file}"
|
132
130
|
end
|
133
131
|
rescue Timeout::Error
|
134
|
-
Logging.
|
132
|
+
Logging.log_info "Timeout!"
|
135
133
|
force_kill(pid, pid_file)
|
136
134
|
rescue Interrupt
|
137
135
|
force_kill(pid, pid_file)
|
138
136
|
rescue Errno::ESRCH # No such process
|
139
|
-
Logging.
|
137
|
+
Logging.log_info "process not found!"
|
140
138
|
force_kill(pid, pid_file)
|
141
139
|
end
|
142
140
|
|
143
141
|
def force_kill(pid, pid_file)
|
144
|
-
Logging.
|
142
|
+
Logging.log_info "Sending KILL signal to process #{pid} ... "
|
145
143
|
Process.kill("KILL", pid)
|
146
144
|
File.delete(pid_file) if File.exist?(pid_file)
|
147
145
|
end
|
@@ -161,7 +159,7 @@ module Thin
|
|
161
159
|
end
|
162
160
|
|
163
161
|
def write_pid_file
|
164
|
-
|
162
|
+
log_info "Writing PID to #{@pid_file}"
|
165
163
|
open(@pid_file,"w") { |f| f.write(Process.pid) }
|
166
164
|
File.chmod(0644, @pid_file)
|
167
165
|
end
|
@@ -173,7 +171,7 @@ module Thin
|
|
173
171
|
raise PidFileExist, "#{@pid_file} already exists, seems like it's already running (process ID: #{pid}). " +
|
174
172
|
"Stop the process or delete #{@pid_file}."
|
175
173
|
else
|
176
|
-
|
174
|
+
log_info "Deleting stale PID file #{@pid_file}"
|
177
175
|
remove_pid_file
|
178
176
|
end
|
179
177
|
end
|
data/lib/thin/logging.rb
CHANGED
@@ -1,54 +1,165 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
1
3
|
module Thin
|
2
4
|
# To be included in classes to allow some basic logging
|
3
5
|
# that can be silenced (<tt>Logging.silent=</tt>) or made
|
4
6
|
# more verbose.
|
5
|
-
# <tt>Logging.
|
6
|
-
#
|
7
|
-
# <tt>Logging.
|
8
|
-
#
|
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.
|
9
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
|
+
|
10
20
|
class << self
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
|
22
|
+
attr_reader :logger
|
23
|
+
attr_reader :trace_logger
|
24
|
+
|
25
|
+
def trace=(enabled)
|
26
|
+
if enabled
|
27
|
+
@trace_logger ||= Logger.new(STDOUT)
|
28
|
+
else
|
29
|
+
@trace_logger = nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def trace?
|
34
|
+
!@trace_logger.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def silent=(shh)
|
38
|
+
if shh
|
39
|
+
@logger = nil
|
40
|
+
else
|
41
|
+
@logger ||= Logger.new(STDOUT)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def silent?
|
46
|
+
!@logger.nil?
|
47
|
+
end
|
48
|
+
|
49
|
+
def level
|
50
|
+
@logger ? @logger.level : nil # or 'silent'
|
51
|
+
end
|
52
|
+
|
53
|
+
def level=(value)
|
54
|
+
# If logging has been silenced, then re-enable logging
|
55
|
+
@logger = Logger.new(STDOUT) if @logger.nil?
|
56
|
+
@logger.level = value
|
57
|
+
end
|
58
|
+
|
59
|
+
# Allow user to specify a custom logger to use.
|
60
|
+
# This object must respond to:
|
61
|
+
# +level+, +level=+ and +debug+, +info+, +warn+, +error+, +fatal+
|
62
|
+
def logger=(custom_logger)
|
63
|
+
[ :level ,
|
64
|
+
:level= ,
|
65
|
+
:debug ,
|
66
|
+
:info ,
|
67
|
+
:warn ,
|
68
|
+
:error ,
|
69
|
+
:fatal ,
|
70
|
+
:unknown ,
|
71
|
+
].each do |method|
|
72
|
+
if not custom_logger.respond_to?(method)
|
73
|
+
raise ArgumentError, "logger must respond to #{method}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
@logger = custom_logger
|
78
|
+
end
|
79
|
+
|
80
|
+
def trace_logger=(custom_tracer)
|
81
|
+
[ :level ,
|
82
|
+
:level= ,
|
83
|
+
:debug ,
|
84
|
+
:info ,
|
85
|
+
:warn ,
|
86
|
+
:error ,
|
87
|
+
:fatal ,
|
88
|
+
:unknown ,
|
89
|
+
].each do |method|
|
90
|
+
if not custom_tracer.respond_to?(method)
|
91
|
+
raise ArgumentError, "trace logger must respond to #{method}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
@trace_logger = custom_tracer
|
96
|
+
end
|
97
|
+
|
98
|
+
def log_msg(msg, level=Logger::INFO)
|
99
|
+
return unless @logger
|
100
|
+
@logger.add(level, msg)
|
101
|
+
end
|
102
|
+
|
103
|
+
def trace_msg(msg)
|
104
|
+
return unless @trace_logger
|
105
|
+
@trace_logger.info(msg)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Provided for backwards compatibility.
|
109
|
+
# Callers should be using the +level+ (on the +Logging+ module
|
110
|
+
# or on the instance) to figure out what the log level is.
|
111
|
+
def debug?
|
112
|
+
self.level == Logger::DEBUG
|
113
|
+
end
|
114
|
+
def debug=(val)
|
115
|
+
self.level = (val ? Logger::DEBUG : Logger::INFO)
|
116
|
+
end
|
117
|
+
|
118
|
+
end # module methods
|
119
|
+
|
19
120
|
def silent
|
20
121
|
Logging.silent?
|
21
122
|
end
|
123
|
+
|
22
124
|
def silent=(value)
|
23
125
|
Logging.silent = value
|
24
126
|
end
|
25
|
-
|
26
|
-
# Log a message
|
27
|
-
def log(msg)
|
28
|
-
puts msg unless Logging.silent?
|
29
|
-
end
|
30
|
-
module_function :log
|
31
|
-
public :log
|
32
|
-
|
33
|
-
# Log a message to the console if tracing is activated
|
127
|
+
|
128
|
+
# Log a message if tracing is activated
|
34
129
|
def trace(msg=nil)
|
35
|
-
|
130
|
+
Logging.trace_msg(msg) if msg
|
36
131
|
end
|
37
132
|
module_function :trace
|
38
133
|
public :trace
|
39
|
-
|
40
|
-
# Log a message
|
41
|
-
def
|
42
|
-
|
43
|
-
end
|
44
|
-
module_function :
|
45
|
-
public :
|
46
|
-
|
47
|
-
# Log
|
48
|
-
def
|
49
|
-
|
134
|
+
|
135
|
+
# Log a message at DEBUG level
|
136
|
+
def log_debug(msg=nil)
|
137
|
+
Logging.log_msg(msg || yield, Logger::DEBUG)
|
138
|
+
end
|
139
|
+
module_function :log_debug
|
140
|
+
public :log_debug
|
141
|
+
|
142
|
+
# Log a message at INFO level
|
143
|
+
def log_info(msg)
|
144
|
+
Logging.log_msg(msg || yield, Logger::INFO)
|
145
|
+
end
|
146
|
+
module_function :log_info
|
147
|
+
public :log_info
|
148
|
+
|
149
|
+
# Log a message at ERROR level (and maybe a backtrace)
|
150
|
+
def log_error(msg, e=nil)
|
151
|
+
log_msg = msg + ": #{e}\n\t" + e.backtrace.join("\n\t") + "\n" if e
|
152
|
+
Logging.log_msg(log_msg, Logger::ERROR)
|
50
153
|
end
|
51
154
|
module_function :log_error
|
52
155
|
public :log_error
|
156
|
+
|
157
|
+
# For backwards compatibility
|
158
|
+
def log msg
|
159
|
+
STDERR.puts('#log has been deprecated, please use the ' \
|
160
|
+
'log_level function instead (e.g. - log_info).')
|
161
|
+
log_info(msg)
|
162
|
+
end
|
163
|
+
|
53
164
|
end
|
54
165
|
end
|