trinidad 1.4.4 → 1.4.5.B1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/History.txt +36 -0
- data/README.md +130 -64
- data/Rakefile +6 -3
- data/lib/trinidad.rb +1 -0
- data/lib/trinidad/extensions.rb +16 -16
- data/lib/trinidad/helpers.rb +34 -0
- data/lib/trinidad/lifecycle/base.rb +20 -20
- data/lib/trinidad/lifecycle/host.rb +34 -9
- data/lib/trinidad/lifecycle/host/rolling_reload.rb +31 -9
- data/lib/trinidad/lifecycle/web_app/default.rb +1 -1
- data/lib/trinidad/lifecycle/web_app/shared.rb +15 -8
- data/lib/trinidad/lifecycle/web_app/war.rb +26 -26
- data/lib/trinidad/logging.rb +149 -120
- data/lib/trinidad/server.rb +375 -135
- data/lib/trinidad/version.rb +1 -1
- data/lib/trinidad/web_app.rb +69 -35
- data/rakelib/tomcat.rake +1 -0
- data/trinidad.gemspec +4 -6
- metadata +160 -155
@@ -0,0 +1,34 @@
|
|
1
|
+
module Trinidad
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
@@silence = nil # :nodoc
|
5
|
+
# Should we be silent - no warnings will be printed.
|
6
|
+
def self.silence?; @@silence; end
|
7
|
+
# Silence ! (... or I kill you)
|
8
|
+
def self.silence!; @@silence = true; end
|
9
|
+
|
10
|
+
# Print a warning (Kernel.warn).
|
11
|
+
def self.warn(msg)
|
12
|
+
super unless silence? # Kernel.warn
|
13
|
+
end
|
14
|
+
|
15
|
+
module_function
|
16
|
+
|
17
|
+
@@deprecated = {} # :nodoc
|
18
|
+
|
19
|
+
# Print a deprecated message (once - no matter how many times it's called).
|
20
|
+
def deprecate(msg, prefix = '[DEPRECATED] ')
|
21
|
+
return nil if @@deprecated[msg]
|
22
|
+
@@deprecated[msg] = true
|
23
|
+
Helpers.warn "#{prefix}#{msg}" # Kernel.warn
|
24
|
+
end
|
25
|
+
|
26
|
+
def camelize(string)
|
27
|
+
string = string.to_s.sub(/^[a-z\d]*/) { $&.capitalize }
|
28
|
+
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
|
29
|
+
string.gsub!('/', '::')
|
30
|
+
string
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -3,41 +3,42 @@ module Trinidad
|
|
3
3
|
# Trinidad lifecycle listener (generic) base class.
|
4
4
|
# Allows hooking into the container's lifecycle using the provided methods.
|
5
5
|
class Base
|
6
|
-
|
6
|
+
|
7
7
|
include Trinidad::Tomcat::LifecycleListener
|
8
8
|
|
9
|
+
EVENTS = Trinidad::Tomcat::Lifecycle # :nodoc:
|
10
|
+
|
9
11
|
# The base implementation simply routes events to correspondig methods.
|
10
12
|
#
|
11
13
|
# http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/Lifecycle.html
|
12
14
|
# http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/LifecycleListener.html
|
13
15
|
def lifecycleEvent(event)
|
14
|
-
events = Trinidad::Tomcat::Lifecycle
|
15
16
|
case event.type
|
16
|
-
when
|
17
|
+
when EVENTS::BEFORE_INIT_EVENT then
|
17
18
|
before_init(event)
|
18
|
-
when
|
19
|
+
when EVENTS::AFTER_INIT_EVENT then
|
19
20
|
after_init(event)
|
20
|
-
when
|
21
|
-
configure_start(event)
|
22
|
-
when events::CONFIGURE_STOP_EVENT then
|
23
|
-
configure_stop(event)
|
24
|
-
when events::BEFORE_START_EVENT then
|
21
|
+
when EVENTS::BEFORE_START_EVENT then
|
25
22
|
before_start(event)
|
26
|
-
when
|
23
|
+
when EVENTS::CONFIGURE_START_EVENT then
|
24
|
+
configure_start(event)
|
25
|
+
when EVENTS::START_EVENT then
|
27
26
|
start(event)
|
28
|
-
when
|
27
|
+
when EVENTS::AFTER_START_EVENT then
|
29
28
|
after_start(event)
|
30
|
-
when
|
29
|
+
when EVENTS::BEFORE_STOP_EVENT then
|
31
30
|
before_stop(event)
|
32
|
-
when
|
31
|
+
when EVENTS::STOP_EVENT then
|
33
32
|
stop(event)
|
34
|
-
when
|
33
|
+
when EVENTS::CONFIGURE_STOP_EVENT then
|
34
|
+
configure_stop(event)
|
35
|
+
when EVENTS::AFTER_STOP_EVENT then
|
35
36
|
after_stop(event)
|
36
|
-
when
|
37
|
+
when EVENTS::BEFORE_DESTROY_EVENT then
|
37
38
|
before_destroy(event)
|
38
|
-
when
|
39
|
+
when EVENTS::AFTER_DESTROY_EVENT then
|
39
40
|
after_destroy(event)
|
40
|
-
when
|
41
|
+
when EVENTS::PERIODIC_EVENT then
|
41
42
|
periodic(event)
|
42
43
|
else
|
43
44
|
raise "unsupported event.type = #{event.type}"
|
@@ -48,16 +49,15 @@ module Trinidad
|
|
48
49
|
|
49
50
|
def before_init(event); end
|
50
51
|
def after_init(event); end
|
51
|
-
|
52
|
-
def configure_start(event); end
|
53
|
-
def configure_stop(event); end
|
54
52
|
|
55
53
|
def before_start(event); end
|
54
|
+
def configure_start(event); end
|
56
55
|
def start(event); end
|
57
56
|
def after_start(event); end
|
58
57
|
|
59
58
|
def before_stop(event); end
|
60
59
|
def stop(event); end
|
60
|
+
def configure_stop(event); end
|
61
61
|
def after_stop(event); end
|
62
62
|
|
63
63
|
def before_destroy(event); end
|
@@ -2,8 +2,13 @@ require 'trinidad/lifecycle/base'
|
|
2
2
|
|
3
3
|
module Trinidad
|
4
4
|
module Lifecycle
|
5
|
-
#
|
6
|
-
|
5
|
+
# Host listener - monitors deployed applications
|
6
|
+
# (re-invented HostConfig with Ruby/Rack semantics).
|
7
|
+
class Host # TODO < Tomcat::HostConfig !
|
8
|
+
|
9
|
+
include Trinidad::Tomcat::LifecycleListener
|
10
|
+
|
11
|
+
EVENTS = Trinidad::Tomcat::Lifecycle # :nodoc:
|
7
12
|
|
8
13
|
attr_reader :server, :app_holders
|
9
14
|
# @deprecated (<= 1.3.5)
|
@@ -21,21 +26,40 @@ module Trinidad
|
|
21
26
|
end
|
22
27
|
@server, @app_holders = server, app_holders
|
23
28
|
end
|
24
|
-
|
25
|
-
|
29
|
+
|
30
|
+
def lifecycleEvent(event) # :nodoc:
|
31
|
+
case event.type
|
32
|
+
when EVENTS::BEFORE_START_EVENT then
|
33
|
+
before_start(event)
|
34
|
+
when EVENTS::START_EVENT then
|
35
|
+
start(event)
|
36
|
+
when EVENTS::STOP_EVENT then
|
37
|
+
stop(event)
|
38
|
+
when EVENTS::PERIODIC_EVENT then
|
39
|
+
periodic(event)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
26
43
|
def before_start(event)
|
27
44
|
init_monitors
|
28
45
|
end
|
29
46
|
|
30
|
-
|
47
|
+
def start(event); end # :nodoc:
|
48
|
+
|
31
49
|
def periodic(event)
|
32
|
-
|
50
|
+
check_changes event.lifecycle
|
33
51
|
end
|
34
52
|
|
35
|
-
def
|
53
|
+
def stop(event); end # :nodoc:
|
54
|
+
|
55
|
+
def tomcat; @server.tomcat; end # :nodoc: for backwards compatibility
|
36
56
|
|
37
57
|
protected
|
38
58
|
|
59
|
+
def check_changes(host)
|
60
|
+
check_monitors
|
61
|
+
end
|
62
|
+
|
39
63
|
def init_monitors
|
40
64
|
app_holders.each do |app_holder|
|
41
65
|
monitor = app_holder.monitor
|
@@ -80,8 +104,9 @@ module Trinidad
|
|
80
104
|
strategy = (app_holder.web_app.reload_strategy || :default).to_sym
|
81
105
|
strategy = RELOAD_STRATEGIES[ strategy ]
|
82
106
|
strategy = strategy ? self.class.const_get(strategy) : RestartReload
|
83
|
-
|
84
|
-
|
107
|
+
new_args = []
|
108
|
+
new_args << server if strategy.instance_method(:initialize).arity != 0
|
109
|
+
strategy.new(*new_args).reload!(app_holder)
|
85
110
|
end
|
86
111
|
|
87
112
|
end
|
@@ -16,19 +16,32 @@ module Trinidad
|
|
16
16
|
|
17
17
|
web_app.reset! # force a new class loader + re-read state (from config)
|
18
18
|
no_host = org.apache.catalina.Host.impl {} # do not add to parent yet
|
19
|
-
new_context = @server.add_web_app(web_app, no_host)
|
20
|
-
new_context.add_lifecycle_listener(Takeover.new(old_context))
|
19
|
+
new_context = @server.add_web_app(web_app, no_host, false)
|
21
20
|
# Tomcat requires us to have unique names for its containers :
|
22
21
|
new_context.name = "#{old_context.name}-#{java.lang.System.currentTimeMillis}"
|
23
|
-
|
22
|
+
new_context.add_lifecycle_listener(takeover = Takeover.new(old_context))
|
24
23
|
app_holder.context = new_context
|
25
24
|
|
26
25
|
Thread.new do
|
27
26
|
begin
|
28
27
|
logger.debug "Starting a new Context for [#{new_context.path}]"
|
29
28
|
old_context.parent.add_child new_context # NOTE: likely starts!
|
30
|
-
|
31
|
-
|
29
|
+
|
30
|
+
new_context.start unless new_context.state_name =~ /START|STOP|FAILED/i
|
31
|
+
|
32
|
+
if new_context.state_name =~ /STOP|FAILED/i
|
33
|
+
logger.error("Context with name [#{old_context.name}] failed rolling")
|
34
|
+
takeover.failed!(new_context)
|
35
|
+
else
|
36
|
+
logger.info "Context with name [#{old_context.name}] has completed rolling"
|
37
|
+
end
|
38
|
+
rescue => error
|
39
|
+
e = org.jruby.exceptions.RaiseException.new(error)
|
40
|
+
logger.error("Context with name [#{old_context.name}] failed rolling", e)
|
41
|
+
takeover.failed!(new_context)
|
42
|
+
rescue java.lang.Exception => e
|
43
|
+
logger.error("Context with name [#{old_context.name}] failed rolling", e)
|
44
|
+
takeover.failed!(new_context)
|
32
45
|
ensure
|
33
46
|
app_holder.unlock
|
34
47
|
end
|
@@ -39,9 +52,9 @@ module Trinidad
|
|
39
52
|
def self.logger # log into the same location as context.reload does :
|
40
53
|
Trinidad::Logging::LogFactory.getLog('org.apache.catalina.core.StandardContext')
|
41
54
|
end
|
42
|
-
|
55
|
+
|
43
56
|
class Takeover < Trinidad::Lifecycle::Base # :nodoc
|
44
|
-
|
57
|
+
|
45
58
|
def initialize(context)
|
46
59
|
@old_context = context
|
47
60
|
end
|
@@ -53,12 +66,21 @@ module Trinidad
|
|
53
66
|
logger.debug "Stoping the old Context for [#{@old_context.path}]"
|
54
67
|
|
55
68
|
@old_context.stop
|
69
|
+
@old_context.work_dir = nil # make sure it's not deleted
|
56
70
|
@old_context.destroy
|
57
71
|
# NOTE: name might not be changed once added to a parent
|
58
|
-
new_context.name = @old_context.name
|
72
|
+
#new_context.name = @old_context.name
|
59
73
|
super
|
60
74
|
end
|
61
75
|
|
76
|
+
def failed!(new_context)
|
77
|
+
# NOTE: this will also likely destroy() the child - new context :
|
78
|
+
@old_context.parent.remove_child new_context
|
79
|
+
logger.info "Failed to start new Context for [#{@old_context.path}] " +
|
80
|
+
"(check application logs) keeping the old one running ..."
|
81
|
+
new_context.remove_lifecycle_listener(self)
|
82
|
+
end
|
83
|
+
|
62
84
|
private
|
63
85
|
|
64
86
|
def logger
|
@@ -66,7 +88,7 @@ module Trinidad
|
|
66
88
|
end
|
67
89
|
|
68
90
|
end
|
69
|
-
|
91
|
+
|
70
92
|
end
|
71
93
|
end
|
72
94
|
end
|
@@ -31,7 +31,7 @@ module Trinidad
|
|
31
31
|
def configure_deployment_descriptor(context)
|
32
32
|
descriptor = web_app.deployment_descriptor
|
33
33
|
if descriptor && File.exist?(descriptor)
|
34
|
-
listeners = context.
|
34
|
+
listeners = context.find_lifecycle_listeners
|
35
35
|
context_config = listeners && listeners.find do |listener|
|
36
36
|
listener.is_a?(Trinidad::Tomcat::ContextConfig)
|
37
37
|
end
|
@@ -12,6 +12,12 @@ module Trinidad
|
|
12
12
|
@web_app = web_app
|
13
13
|
end
|
14
14
|
|
15
|
+
def before_init(event)
|
16
|
+
#context = event.lifecycle
|
17
|
+
#context.name = context.path if context.name
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
15
21
|
# @see Trinidad::Lifecycle::Base#before_start
|
16
22
|
def before_start(event)
|
17
23
|
super
|
@@ -30,7 +36,12 @@ module Trinidad
|
|
30
36
|
protected
|
31
37
|
|
32
38
|
def adjust_context(context)
|
33
|
-
|
39
|
+
context_name = web_app.context_name
|
40
|
+
# on (rolling) reloads the name may have been set already :
|
41
|
+
if context_name && ! (context.name || '').index(context_name)
|
42
|
+
context.name = context_name
|
43
|
+
end
|
44
|
+
|
34
45
|
context.doc_base = web_app.doc_base if web_app.doc_base
|
35
46
|
context.work_dir = web_app.work_dir if web_app.work_dir
|
36
47
|
context.aliases = web_app.aliases if web_app.aliases
|
@@ -47,19 +58,15 @@ module Trinidad
|
|
47
58
|
|
48
59
|
def configure_default_servlet(context)
|
49
60
|
configure_builtin_servlet(context,
|
50
|
-
web_app.default_servlet,
|
51
|
-
Trinidad::WebApp::DEFAULT_SERVLET_NAME
|
61
|
+
web_app.default_servlet, Trinidad::WebApp::DEFAULT_SERVLET_NAME
|
52
62
|
)
|
53
63
|
end
|
54
64
|
|
55
65
|
def configure_jsp_servlet(context)
|
56
66
|
wrapper = configure_builtin_servlet(context,
|
57
|
-
web_app.jsp_servlet,
|
58
|
-
Trinidad::WebApp::JSP_SERVLET_NAME
|
67
|
+
web_app.jsp_servlet, Trinidad::WebApp::JSP_SERVLET_NAME
|
59
68
|
)
|
60
|
-
if wrapper == false # jsp servlet removed
|
61
|
-
context.process_tlds = false
|
62
|
-
end
|
69
|
+
context.process_tlds = false if wrapper == false # jsp servlet removed
|
63
70
|
wrapper
|
64
71
|
end
|
65
72
|
|
@@ -7,45 +7,45 @@ module Trinidad
|
|
7
7
|
class War < Base
|
8
8
|
include Shared
|
9
9
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
def before_init(event)
|
11
|
+
# NOTE: esp. important for .war applications that the name matches the path
|
12
|
+
# to work-around ProxyDirContext constructor's `contextPath = contextName;`
|
13
|
+
# @see {#adjust_context} also need to restore possible context name change!
|
14
|
+
context = event.lifecycle
|
15
|
+
context.name = context.path if context.name
|
16
16
|
super
|
17
|
-
remove_war_app(event.lifecycle)
|
18
17
|
end
|
19
18
|
|
20
19
|
def configure(context)
|
21
|
-
super #
|
20
|
+
super # Shared#configure
|
22
21
|
configure_class_loader(context)
|
23
22
|
end
|
24
|
-
|
23
|
+
|
25
24
|
protected
|
26
25
|
|
26
|
+
def adjust_context(context)
|
27
|
+
name = context.name
|
28
|
+
super
|
29
|
+
ensure # @see {#before_init}
|
30
|
+
context.name = name
|
31
|
+
# NOTE: mimics HostConfig#deploWAR and should be removed
|
32
|
+
# once Lifecycle::Host inherits func from HostConfig ...
|
33
|
+
# context_name = Trinidad::Tomcat::ContextName.new(name)
|
34
|
+
# context.setName context_name.getName()
|
35
|
+
# context.setPath context_name.getPath()
|
36
|
+
# context.setWebappVersion context_name.getVersion()
|
37
|
+
# context.setDocBase context_name.getBaseName() + '.war'
|
38
|
+
end
|
39
|
+
|
27
40
|
def configure_class_loader(context)
|
28
|
-
|
41
|
+
class_loader = web_app.class_loader || JRuby.runtime.jruby_class_loader
|
42
|
+
loader = Trinidad::Tomcat::WebappLoader.new(class_loader)
|
29
43
|
loader.container = context
|
30
44
|
context.loader = loader
|
31
45
|
end
|
32
46
|
|
33
|
-
|
34
|
-
|
35
|
-
def expand_war_app(context)
|
36
|
-
unless File.exist?(context.doc_base)
|
37
|
-
host = context.parent
|
38
|
-
war_file = java.io.File.new(web_app.root_dir)
|
39
|
-
war = java.net.URL.new("jar:" + war_file.toURI.toURL.to_s + "!/")
|
40
|
-
path_name = File.basename(context.doc_base)
|
41
|
-
|
42
|
-
Trinidad::Tomcat::ExpandWar.expand(host, war, path_name)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def remove_war_app(context)
|
47
|
-
require 'fileutils'
|
48
|
-
FileUtils.rm_rf web_app.root_dir.gsub(/\.war$/, '')
|
47
|
+
def remove_defaults(context = nil)
|
48
|
+
# NOTE: do not remove defaults (welcome files)
|
49
49
|
end
|
50
50
|
|
51
51
|
end
|
data/lib/trinidad/logging.rb
CHANGED
@@ -12,17 +12,13 @@ module Trinidad
|
|
12
12
|
# Configure the "global" Trinidad logging.
|
13
13
|
def self.configure(log_level = nil)
|
14
14
|
return false if @@configured
|
15
|
+
@@configured = true
|
15
16
|
|
16
17
|
root_logger = JUL::Logger.getLogger('')
|
17
18
|
level = parse_log_level(log_level, :INFO)
|
18
19
|
|
19
20
|
out_handler = new_console_handler JRuby.runtime.out
|
20
21
|
out_handler.formatter = console_formatter
|
21
|
-
|
22
|
-
err_handler = new_console_handler JRuby.runtime.err
|
23
|
-
err_handler.formatter = console_formatter
|
24
|
-
err_handler.level = level.intValue > JUL::Level::WARNING.intValue ?
|
25
|
-
level : JUL::Level::WARNING # only >= WARNING on STDERR
|
26
22
|
|
27
23
|
root_logger.synchronized do
|
28
24
|
root_logger.handlers.to_a.each do |handler|
|
@@ -30,24 +26,35 @@ module Trinidad
|
|
30
26
|
end
|
31
27
|
|
32
28
|
root_logger.add_handler(out_handler)
|
33
|
-
|
34
|
-
|
29
|
+
if JRuby.runtime.out != Java::JavaLang::System.out ||
|
30
|
+
JRuby.runtime.err != Java::JavaLang::System.err
|
31
|
+
# NOTE: only add err handler if customized STDOUT or STDERR :
|
32
|
+
err_handler = new_console_handler JRuby.runtime.err
|
33
|
+
err_handler.formatter = console_formatter
|
34
|
+
err_handler.level = level.intValue > JUL::Level::WARNING.intValue ?
|
35
|
+
level : JUL::Level::WARNING # only >= WARNING on STDERR
|
36
|
+
|
37
|
+
root_logger.add_handler(err_handler)
|
38
|
+
end
|
39
|
+
set_log_level(root_logger, level)
|
35
40
|
end
|
36
|
-
|
41
|
+
silence_tomcat_loggers
|
37
42
|
|
38
|
-
@@configured = true
|
39
43
|
root_logger
|
40
44
|
end
|
41
45
|
|
42
46
|
# Force logging (re-)configuration.
|
43
47
|
# @see #configure
|
44
48
|
def self.configure!(log_level = nil)
|
45
|
-
@@configured = false
|
46
|
-
|
49
|
+
( @@configured = false ) || configure(log_level)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.configure_web_app!(web_app, context)
|
53
|
+
configure_web_app!(web_app, context, true)
|
47
54
|
end
|
48
55
|
|
49
56
|
# Configure logging for a web application.
|
50
|
-
def self.configure_web_app(web_app, context)
|
57
|
+
def self.configure_web_app(web_app, context, reset = nil)
|
51
58
|
param_name, param_value = 'jruby.rack.logging', 'JUL'
|
52
59
|
# 1. delegate (jruby-rack) servlet log to JUL
|
53
60
|
if set_value = web_app_context_param(web_app, context, param_name)
|
@@ -62,12 +69,15 @@ module Trinidad
|
|
62
69
|
# org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/foo]
|
63
70
|
context.add_parameter(param_name, logger_name = context.send(:logName))
|
64
71
|
end
|
65
|
-
configure # make sure 'global' logging
|
72
|
+
configure # make sure 'global' logging is configured
|
66
73
|
|
67
74
|
logger = JUL::Logger.getLogger(logger_name) # exclusive for web app
|
68
|
-
|
69
|
-
|
75
|
+
logger.handlers.each { |h| logger.remove_handler(h); h.close } if reset
|
76
|
+
# avoid duplicate calls - do not configure (e.g. FileHandler) twice :
|
77
|
+
return false unless logger.handlers.empty?
|
78
|
+
|
70
79
|
logging = web_app.logging
|
80
|
+
|
71
81
|
logger.level = parse_log_level(logging[:level], nil)
|
72
82
|
# delegate to root (console) output only in development mode :
|
73
83
|
logger.use_parent_handlers = logging[:use_parent_handlers]
|
@@ -112,16 +122,26 @@ module Trinidad
|
|
112
122
|
JUL::Level.parse(log_level) if log_level
|
113
123
|
end
|
114
124
|
|
115
|
-
def self.
|
125
|
+
def self.set_log_level(logger, level)
|
126
|
+
logger.level = level; LogFactory.getLog(logger.name)
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.silence_tomcat_loggers
|
116
130
|
# org.apache.coyote.http11.Http11Protocol INFO: Initializing ProtocolHandler ["http-bio-3000"]
|
117
131
|
# org.apache.catalina.core.StandardService INFO: Starting service Tomcat
|
118
132
|
# org.apache.catalina.core.StandardEngine INFO: Starting Servlet Engine: Apache Tomcat/7.0.27
|
119
133
|
# org.apache.catalina.startup.ContextConfig INFO: No global web.xml found
|
120
134
|
# org.apache.coyote.http11.Http11Protocol INFO: Starting ProtocolHandler ["http-bio-3000"]
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
135
|
+
level = JUL::Level::WARNING
|
136
|
+
logger_names = [
|
137
|
+
'org.apache.catalina.core.StandardService',
|
138
|
+
'org.apache.catalina.core.StandardEngine',
|
139
|
+
'org.apache.catalina.startup.ContextConfig',
|
140
|
+
]
|
141
|
+
for name in logger_names
|
142
|
+
logger = JUL::Logger.getLogger(name)
|
143
|
+
set_log_level(logger, level) if logger
|
144
|
+
end
|
125
145
|
end
|
126
146
|
|
127
147
|
def self.web_app_context_param(web_app, context, name)
|
@@ -146,78 +166,82 @@ module Trinidad
|
|
146
166
|
handler
|
147
167
|
end
|
148
168
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
# NOTE: following code is heavily based on super's internals !
|
165
|
-
synchronized do
|
166
|
-
# we're normally in the lock here (from #publish)
|
167
|
-
# thus we do not perform any more synchronization
|
168
|
-
prev_rotatable = self.rotatable
|
169
|
-
begin
|
170
|
-
self.rotatable = false
|
171
|
-
# thus current file name will be always {prefix}{suffix} :
|
172
|
-
# due super's `prefix + (rotatable ? _date : "") + suffix`
|
173
|
-
super
|
174
|
-
ensure
|
175
|
-
self.rotatable = prev_rotatable
|
176
|
-
end
|
169
|
+
if ( Java::JavaClass.for_name('rb.trinidad.logging.FileHandler') rescue nil )
|
170
|
+
FileHandler = Java::RbTrinidadLogging::FileHandler # recent trinidad_jars
|
171
|
+
else
|
172
|
+
# we'd achieve logging to a production.log file while rotating it (daily)
|
173
|
+
class FileHandler < Java::OrgApacheJuli::FileHandler # :nodoc
|
174
|
+
|
175
|
+
field_reader :directory, :prefix, :suffix
|
176
|
+
field_accessor :rotatable, :bufferSize => :buffer_size
|
177
|
+
|
178
|
+
# JULI::FileHandler internals :
|
179
|
+
field_accessor :date => :_date # current date string e.g. 2012-06-26
|
180
|
+
|
181
|
+
def initialize(directory, prefix, suffix)
|
182
|
+
super(directory, prefix, suffix)
|
183
|
+
self._date = nil # to openWriter on first #publish(record)
|
177
184
|
end
|
178
|
-
end
|
179
185
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
dir = java.io.File.new(directory).getAbsoluteFile
|
194
|
-
log = java.io.File.new(dir, prefix + "" + suffix)
|
195
|
-
if log.exists
|
196
|
-
if ! date || date.empty?
|
197
|
-
date = log.lastModified
|
198
|
-
# we abuse Timestamp to get a date formatted !
|
199
|
-
# just like super does internally (just in case)
|
200
|
-
date = java.sql.Timestamp.new(date).toString[0, 10]
|
201
|
-
end
|
202
|
-
today = java.lang.System.currentTimeMillis
|
203
|
-
today = java.sql.Timestamp.new(today).toString[0, 10]
|
204
|
-
return if date == today # no need to rotate just yet
|
205
|
-
to_file = java.io.File.new(dir, prefix + date + suffix)
|
206
|
-
if to_file.exists
|
207
|
-
file = java.io.RandomAccessFile.new(to_file, 'rw')
|
208
|
-
file.seek(file.length)
|
209
|
-
log_channel = java.io.FileInputStream.new(log).getChannel
|
210
|
-
log_channel.transferTo(0, log_channel.size, file.getChannel)
|
211
|
-
file.close
|
212
|
-
log_channel.close
|
213
|
-
log.delete
|
214
|
-
else
|
215
|
-
log.renameTo(to_file)
|
186
|
+
def openWriter
|
187
|
+
# NOTE: following code is heavily based on super's internals !
|
188
|
+
synchronized do
|
189
|
+
# we're normally in the lock here (from #publish)
|
190
|
+
# thus we do not perform any more synchronization
|
191
|
+
prev_rotatable = self.rotatable
|
192
|
+
begin
|
193
|
+
self.rotatable = false
|
194
|
+
# thus current file name will be always {prefix}{suffix} :
|
195
|
+
# due super's `prefix + (rotatable ? _date : "") + suffix`
|
196
|
+
super
|
197
|
+
ensure
|
198
|
+
self.rotatable = prev_rotatable
|
216
199
|
end
|
217
200
|
end
|
218
|
-
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def close
|
204
|
+
@_close = true
|
205
|
+
super
|
206
|
+
@_close = nil
|
207
|
+
end
|
208
|
+
|
209
|
+
def closeWriter
|
210
|
+
date = _date
|
211
|
+
super # sets `date = null`
|
212
|
+
# the additional trick here is to rotate the closed file
|
213
|
+
synchronized do
|
214
|
+
# we're normally in the lock here (from #publish)
|
215
|
+
# thus we do not perform any more synchronization
|
216
|
+
dir = java.io.File.new(directory).getAbsoluteFile
|
217
|
+
log = java.io.File.new(dir, prefix + "" + suffix)
|
218
|
+
if log.exists
|
219
|
+
if ! date || date.empty?
|
220
|
+
date = log.lastModified
|
221
|
+
# we abuse Timestamp to get a date formatted !
|
222
|
+
# just like super does internally (just in case)
|
223
|
+
date = java.sql.Timestamp.new(date).toString[0, 10]
|
224
|
+
end
|
225
|
+
today = java.lang.System.currentTimeMillis
|
226
|
+
today = java.sql.Timestamp.new(today).toString[0, 10]
|
227
|
+
return if date == today # no need to rotate just yet
|
228
|
+
to_file = java.io.File.new(dir, prefix + date + suffix)
|
229
|
+
if to_file.exists
|
230
|
+
file = java.io.RandomAccessFile.new(to_file, 'rw')
|
231
|
+
file.seek(file.length)
|
232
|
+
log_channel = java.io.FileInputStream.new(log).getChannel
|
233
|
+
log_channel.transferTo(0, log_channel.size, file.getChannel)
|
234
|
+
file.close
|
235
|
+
log_channel.close
|
236
|
+
log.delete
|
237
|
+
else
|
238
|
+
log.renameTo(to_file)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end if rotatable && ! @_close
|
242
|
+
end
|
243
|
+
|
219
244
|
end
|
220
|
-
|
221
245
|
end
|
222
246
|
|
223
247
|
# We're truly missing a #formatThrown exception helper method.
|
@@ -265,47 +289,52 @@ module Trinidad
|
|
265
289
|
|
266
290
|
end
|
267
291
|
|
268
|
-
|
269
|
-
|
292
|
+
if ( Java::JavaClass.for_name('rb.trinidad.logging.DefaultFormatter') rescue nil )
|
293
|
+
DefaultFormatter = Java::RbTrinidadLogging::DefaultFormatter # recent trinidad_jars
|
294
|
+
else
|
295
|
+
# A formatter that formats application file logs (e.g. production.log).
|
296
|
+
class DefaultFormatter < JUL::Formatter # :nodoc
|
270
297
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
@format.time_zone = time_zone
|
282
|
-
when String then
|
283
|
-
time_zone = Java::JavaUtil::TimeZone.getTimeZone(time_zone)
|
284
|
-
@format.time_zone = time_zone
|
285
|
-
when Numeric then
|
286
|
-
time_zones = Java::JavaUtil::TimeZone.getAvailableIDs(time_zone)
|
287
|
-
if time_zones.length > 0
|
288
|
-
time_zone = Java::JavaUtil::TimeZone.getTimeZone(time_zones[0])
|
298
|
+
# Allows customizing the date format + the time zone to be used.
|
299
|
+
def initialize(format = nil, time_zone = nil)
|
300
|
+
super()
|
301
|
+
@format = format ?
|
302
|
+
Java::JavaText::SimpleDateFormat.new(format) :
|
303
|
+
Java::JavaText::SimpleDateFormat.new
|
304
|
+
case time_zone
|
305
|
+
when Java::JavaUtil::Calendar then
|
306
|
+
@format.calendar = time_zone
|
307
|
+
when Java::JavaUtil::TimeZone then
|
289
308
|
@format.time_zone = time_zone
|
290
|
-
|
291
|
-
|
292
|
-
|
309
|
+
when String then
|
310
|
+
time_zone = Java::JavaUtil::TimeZone.getTimeZone(time_zone)
|
311
|
+
@format.time_zone = time_zone
|
312
|
+
when Numeric then
|
313
|
+
time_zones = Java::JavaUtil::TimeZone.getAvailableIDs(time_zone)
|
314
|
+
if time_zones.length > 0
|
315
|
+
time_zone = Java::JavaUtil::TimeZone.getTimeZone(time_zones[0])
|
316
|
+
@format.time_zone = time_zone
|
317
|
+
end
|
318
|
+
end if time_zone
|
319
|
+
end
|
293
320
|
|
294
|
-
|
321
|
+
JDate = Java::JavaUtil::Date
|
295
322
|
|
296
|
-
|
297
|
-
|
298
|
-
|
323
|
+
def format(record)
|
324
|
+
timestamp = @format.synchronized do
|
325
|
+
@format.format JDate.new(record.millis)
|
326
|
+
end
|
327
|
+
level = record.level.name
|
328
|
+
message = formatMessage(record)
|
329
|
+
|
330
|
+
out = "#{timestamp} #{level}: #{message}"
|
331
|
+
out << formatThrown(record).to_s
|
332
|
+
(lns = "\n") == out[-1, 1] ? out : out << lns
|
299
333
|
end
|
300
|
-
level = record.level.name
|
301
|
-
message = formatMessage(record)
|
302
334
|
|
303
|
-
out = "#{timestamp} #{level}: #{message}"
|
304
|
-
out << formatThrown(record).to_s
|
305
|
-
(lns = "\n") == out[-1, 1] ? out : out << lns
|
306
335
|
end
|
307
|
-
|
308
336
|
end
|
337
|
+
|
309
338
|
end
|
310
339
|
LogFormatter = Logging::DefaultFormatter # backwards compatibility
|
311
340
|
end
|