trinidad 1.4.0.RC → 1.4.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.
- data/History.txt +4 -1
- data/README.md +16 -8
- data/lib/trinidad/configuration.rb +7 -2
- data/lib/trinidad/logging.rb +6 -2
- data/lib/trinidad/version.rb +1 -1
- data/lib/trinidad/web_app.rb +6 -4
- data/trinidad.gemspec +1 -0
- metadata +5 -6
- data/src/java/org/apache/juli/FileHandler.java +0 -401
data/History.txt
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
== Trinidad 1.4.0
|
1
|
+
== Trinidad 1.4.0 (2012-07-24)
|
2
2
|
|
3
|
+
* fix incorrect context-param parsing and only configure logging when
|
4
|
+
deployment descriptor did not specified jruby.rack.logging param (#76)
|
5
|
+
* deep symbolize_options should account for arrays of hashes (#80)
|
3
6
|
* requires latest Tomcat 7.0.28 (jars 1.0.5) due context reloading fix
|
4
7
|
* requires latest jruby-rack 1.1.7 due delegating RackLogger to JUL
|
5
8
|
* Trinidad::WebApp API revisited some changes are non-backwards compatible !
|
data/README.md
CHANGED
@@ -145,15 +145,23 @@ Context with name [/] has completed rolling
|
|
145
145
|
```
|
146
146
|
|
147
147
|
It also prints warnings and error messages on error output, while application
|
148
|
-
specific log messages (e.g. logs from `Rails.logger`) go into the expected
|
149
|
-
location at *log/{environment}.log*.
|
148
|
+
specific log messages (e.g. logs from `Rails.logger`) always go into the expected
|
149
|
+
file location at *log/{environment}.log*.
|
150
150
|
|
151
|
-
Application logging performs daily rolling out of the box and only prints
|
152
|
-
messages
|
151
|
+
Application logging performs daily file rolling out of the box and only prints
|
152
|
+
messages to the console while it runs in development mode, that means you won't
|
153
|
+
see any application specific output on the console say in production !
|
153
154
|
|
154
155
|
Please note that these logging details as well as the logging format will be
|
155
156
|
configurable with *trinidad.yml/.rb* within the next **1.4.x** release.
|
156
157
|
|
158
|
+
If you plan to use a slice of Java with your JRuby and require a logger, consider
|
159
|
+
using `ServletContext#log`. By default it is setup in a way that logging with
|
160
|
+
`ServletContext` ends up in the same location as the Rails log.
|
161
|
+
If this is not enough you can still configure a Java logging library e.g. SLF4J,
|
162
|
+
just make sure you tell Trinidad to use it as well, if needed, using the
|
163
|
+
**jruby.rack.logging** context parameter in *web.xml*.
|
164
|
+
|
157
165
|
## Hot Deployment
|
158
166
|
|
159
167
|
Trinidad supports monitoring a file to reload applications, when the file
|
@@ -170,10 +178,10 @@ Since version **1.4.0** Trinidad supports 2 reload strategies :
|
|
170
178
|
|
171
179
|
* **rolling** "zero-downtime" (asynchronous) reloading strategy similar to
|
172
180
|
Passenger's rolling reloads. This has been the default since **1.1.0** up till
|
173
|
-
|
174
|
-
|
175
|
-
requests are being served
|
176
|
-
|
181
|
+
the **1.3.x** line. If you use this you should account that your JVM memory
|
182
|
+
requirements might increase quite a lot (esp. if you reload under heavy loads)
|
183
|
+
since requests are being served while there's another version of the
|
184
|
+
application being loaded.
|
177
185
|
|
178
186
|
Configure the reload strategy per web application or globally e.g. :
|
179
187
|
|
@@ -90,8 +90,13 @@ module Trinidad
|
|
90
90
|
# a Hash like #symbolize helper
|
91
91
|
def self.symbolize_options(options, deep = true)
|
92
92
|
new_options = options.class.new
|
93
|
-
options.each do |key, value|
|
94
|
-
if deep &&
|
93
|
+
options.each do |key, value|
|
94
|
+
if deep && value.is_a?(Array) # YAML::Omap is an Array
|
95
|
+
array = new_options[key.to_sym] = value.class.new
|
96
|
+
value.each do |v|
|
97
|
+
array << ( options_like?(v) ? symbolize_options(v, deep) : v )
|
98
|
+
end
|
99
|
+
elsif deep && options_like?(value)
|
95
100
|
new_options[key.to_sym] = symbolize_options(value, deep)
|
96
101
|
else
|
97
102
|
new_options[key.to_sym] = value
|
data/lib/trinidad/logging.rb
CHANGED
@@ -52,14 +52,14 @@ module Trinidad
|
|
52
52
|
def self.configure_web_app(web_app, context)
|
53
53
|
param_name, param_value = 'jruby.rack.logging', 'JUL'
|
54
54
|
# 1. delegate (jruby-rack) servlet log to JUL
|
55
|
-
if set_value = context
|
55
|
+
if set_value = web_app_context_param(web_app, context, param_name)
|
56
56
|
return nil if set_value.upcase != param_value
|
57
57
|
else
|
58
58
|
context.add_parameter(param_name, param_value)
|
59
59
|
end
|
60
60
|
# 2. use Tomcat's JUL logger name (unless set) :
|
61
61
|
param_name = 'jruby.rack.logging.name'
|
62
|
-
unless logger_name = context
|
62
|
+
unless logger_name = web_app_context_param(web_app, context, param_name)
|
63
63
|
# for a context path e.g. '/foo' most likely smt of the following :
|
64
64
|
# org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/foo]
|
65
65
|
context.add_parameter(param_name, logger_name = context.send(:logName))
|
@@ -118,6 +118,10 @@ module Trinidad
|
|
118
118
|
logger.level = JUL::Level::WARNING if logger
|
119
119
|
end
|
120
120
|
|
121
|
+
def self.web_app_context_param(web_app, context, name)
|
122
|
+
context.find_parameter(name) || web_app.web_xml_context_param(name)
|
123
|
+
end
|
124
|
+
|
121
125
|
# we'd achieve logging to a production.log file while rotating it (daily)
|
122
126
|
class FileHandler < Java::OrgApacheJuli::FileHandler # :nodoc
|
123
127
|
|
data/lib/trinidad/version.rb
CHANGED
data/lib/trinidad/web_app.rb
CHANGED
@@ -147,29 +147,31 @@ module Trinidad
|
|
147
147
|
config[:web_app_dir] ||= default_config[:web_app_dir] || Dir.pwd
|
148
148
|
end
|
149
149
|
|
150
|
+
public
|
151
|
+
|
150
152
|
def web_xml_servlet?(servlet_class, servlet_name = nil)
|
151
153
|
!!( web_xml_doc && (
|
152
|
-
web_xml_doc.root.elements["/web-app/servlet[
|
154
|
+
web_xml_doc.root.elements["/web-app/servlet[servlet-class = '#{servlet_class}']"]
|
153
155
|
)
|
154
156
|
)
|
155
157
|
end
|
156
158
|
|
157
159
|
def web_xml_filter?(filter_class)
|
158
160
|
!!( web_xml_doc && (
|
159
|
-
web_xml_doc.root.elements["/web-app/filter[
|
161
|
+
web_xml_doc.root.elements["/web-app/filter[filter-class = '#{filter_class}']"]
|
160
162
|
)
|
161
163
|
)
|
162
164
|
end
|
163
165
|
|
164
166
|
def web_xml_listener?(listener_class)
|
165
167
|
!!( web_xml_doc &&
|
166
|
-
web_xml_doc.root.elements["/web-app/listener[
|
168
|
+
web_xml_doc.root.elements["/web-app/listener[listener-class = '#{listener_class}']"]
|
167
169
|
)
|
168
170
|
end
|
169
171
|
|
170
172
|
def web_xml_context_param(name)
|
171
173
|
if web_xml_doc &&
|
172
|
-
param = web_xml_doc.root.elements["/web-app/context-param[
|
174
|
+
param = web_xml_doc.root.elements["/web-app/context-param[param-name = '#{name}']"]
|
173
175
|
param.elements['param-value'].text
|
174
176
|
end
|
175
177
|
end
|
data/trinidad.gemspec
CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.files = `git ls-files`.split("\n").sort.
|
35
35
|
reject { |file| file =~ /^\./ }. # .gitignore, .travis.yml
|
36
36
|
reject { |file| file =~ /^spec\// }. # spec/**/*.spec
|
37
|
+
reject { |file| file =~ /^src\// }. # src/* patched into tomcat-core.jar
|
37
38
|
# reject trinidad_jars.gemspec files :
|
38
39
|
reject { |file| file == 'trinidad_jars.gemspec' ||
|
39
40
|
file == 'lib/trinidad/jars.rb' ||
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trinidad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
version: 1.4.0
|
4
|
+
prerelease:
|
5
|
+
version: 1.4.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- David Calavera
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-07-
|
13
|
+
date: 2012-07-24 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: trinidad_jars
|
@@ -135,7 +135,6 @@ files:
|
|
135
135
|
- rakelib/tomcat.rake
|
136
136
|
- rakelib/trinidad.rake
|
137
137
|
- rakelib/trinidad_jars.rake
|
138
|
-
- src/java/org/apache/juli/FileHandler.java
|
139
138
|
- trinidad.gemspec
|
140
139
|
homepage: http://github.com/trinidad/trinidad
|
141
140
|
licenses: []
|
@@ -154,9 +153,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
154
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
154
|
none: false
|
156
155
|
requirements:
|
157
|
-
- - "
|
156
|
+
- - ">="
|
158
157
|
- !ruby/object:Gem::Version
|
159
|
-
version:
|
158
|
+
version: "0"
|
160
159
|
requirements: []
|
161
160
|
|
162
161
|
rubyforge_project: trinidad
|
@@ -1,401 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Licensed to the Apache Software Foundation (ASF) under one or more
|
3
|
-
* contributor license agreements. See the NOTICE file distributed with
|
4
|
-
* this work for additional information regarding copyright ownership.
|
5
|
-
* The ASF licenses this file to You under the Apache License, Version 2.0
|
6
|
-
* (the "License"); you may not use this file except in compliance with
|
7
|
-
* the License. You may obtain a copy of the License at
|
8
|
-
*
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
*
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
* See the License for the specific language governing permissions and
|
15
|
-
* limitations under the License.
|
16
|
-
*/
|
17
|
-
|
18
|
-
|
19
|
-
package org.apache.juli;
|
20
|
-
|
21
|
-
import java.io.BufferedOutputStream;
|
22
|
-
import java.io.File;
|
23
|
-
import java.io.FileOutputStream;
|
24
|
-
import java.io.OutputStream;
|
25
|
-
import java.io.OutputStreamWriter;
|
26
|
-
import java.io.PrintWriter;
|
27
|
-
import java.io.UnsupportedEncodingException;
|
28
|
-
import java.sql.Timestamp;
|
29
|
-
import java.util.concurrent.locks.ReadWriteLock;
|
30
|
-
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
31
|
-
import java.util.logging.ErrorManager;
|
32
|
-
import java.util.logging.Filter;
|
33
|
-
import java.util.logging.Formatter;
|
34
|
-
import java.util.logging.Handler;
|
35
|
-
import java.util.logging.Level;
|
36
|
-
import java.util.logging.LogManager;
|
37
|
-
import java.util.logging.LogRecord;
|
38
|
-
import java.util.logging.SimpleFormatter;
|
39
|
-
|
40
|
-
/**
|
41
|
-
* Implementation of <b>Handler</b> that appends log messages to a file
|
42
|
-
* named {prefix}{date}{suffix} in a configured directory.
|
43
|
-
*
|
44
|
-
* <p>The following configuration properties are available:</p>
|
45
|
-
*
|
46
|
-
* <ul>
|
47
|
-
* <li><code>directory</code> - The directory where to create the log file.
|
48
|
-
* If the path is not absolute, it is relative to the current working
|
49
|
-
* directory of the application. The Apache Tomcat configuration files usually
|
50
|
-
* specify an absolute path for this property,
|
51
|
-
* <code>${catalina.base}/logs</code>
|
52
|
-
* Default value: <code>logs</code></li>
|
53
|
-
* <li><code>rotatable</code> - If <code>true</code>, the log file will be
|
54
|
-
* rotated on the first write past midnight and the filename will be
|
55
|
-
* <code>{prefix}{date}{suffix}</code>, where date is yyyy-MM-dd. If <code>false</code>,
|
56
|
-
* the file will not be rotated and the filename will be <code>{prefix}{suffix}</code>.
|
57
|
-
* Default value: <code>true</code></li>
|
58
|
-
* <li><code>prefix</code> - The leading part of the log file name.
|
59
|
-
* Default value: <code>juli.</code></li>
|
60
|
-
* <li><code>suffix</code> - The trailing part of the log file name. Default value: <code>.log</code></li>
|
61
|
-
* <li><code>bufferSize</code> - Configures buffering. The value of <code>0</code>
|
62
|
-
* uses system default buffering (typically an 8K buffer will be used). A
|
63
|
-
* value of <code><0</code> forces a writer flush upon each log write. A
|
64
|
-
* value <code>>0</code> uses a BufferedOutputStream with the defined
|
65
|
-
* value but note that the system default buffering will also be
|
66
|
-
* applied. Default value: <code>-1</code></li>
|
67
|
-
* <li><code>encoding</code> - Character set used by the log file. Default value:
|
68
|
-
* empty string, which means to use the system default character set.</li>
|
69
|
-
* <li><code>level</code> - The level threshold for this Handler. See the
|
70
|
-
* <code>java.util.logging.Level</code> class for the possible levels.
|
71
|
-
* Default value: <code>ALL</code></li>
|
72
|
-
* <li><code>filter</code> - The <code>java.util.logging.Filter</code>
|
73
|
-
* implementation class name for this Handler. Default value: unset</li>
|
74
|
-
* <li><code>formatter</code> - The <code>java.util.logging.Formatter</code>
|
75
|
-
* implementation class name for this Handler. Default value:
|
76
|
-
* <code>java.util.logging.SimpleFormatter</code></li>
|
77
|
-
* </ul>
|
78
|
-
*
|
79
|
-
* @version $Id$
|
80
|
-
*/
|
81
|
-
|
82
|
-
public class FileHandler
|
83
|
-
extends Handler {
|
84
|
-
|
85
|
-
|
86
|
-
// ------------------------------------------------------------ Constructor
|
87
|
-
|
88
|
-
|
89
|
-
public FileHandler() {
|
90
|
-
this(null, null, null);
|
91
|
-
}
|
92
|
-
|
93
|
-
|
94
|
-
public FileHandler(String directory, String prefix, String suffix) {
|
95
|
-
this.directory = directory;
|
96
|
-
this.prefix = prefix;
|
97
|
-
this.suffix = suffix;
|
98
|
-
configure();
|
99
|
-
}
|
100
|
-
|
101
|
-
public FileHandler(String directory, String prefix, String suffix, boolean rotatable, int bufferSize) {
|
102
|
-
this.directory = directory;
|
103
|
-
this.prefix = prefix;
|
104
|
-
this.suffix = suffix;
|
105
|
-
this.rotatable = rotatable;
|
106
|
-
this.bufferSize = bufferSize;
|
107
|
-
configure();
|
108
|
-
}
|
109
|
-
|
110
|
-
// ----------------------------------------------------- Instance Variables
|
111
|
-
|
112
|
-
|
113
|
-
/**
|
114
|
-
* The directory in which log files are created.
|
115
|
-
*/
|
116
|
-
private String directory;
|
117
|
-
|
118
|
-
/**
|
119
|
-
* The prefix that is added to log file filenames.
|
120
|
-
*/
|
121
|
-
private String prefix;
|
122
|
-
|
123
|
-
/**
|
124
|
-
* The suffix that is added to log file filenames.
|
125
|
-
*/
|
126
|
-
private String suffix;
|
127
|
-
|
128
|
-
/**
|
129
|
-
* Determines whether the logfile is rotatable
|
130
|
-
*/
|
131
|
-
private Boolean rotatable;
|
132
|
-
|
133
|
-
/**
|
134
|
-
* Log buffer size.
|
135
|
-
*/
|
136
|
-
private Integer bufferSize;
|
137
|
-
|
138
|
-
/**
|
139
|
-
* The as-of date for the currently open log file, or null if there is no
|
140
|
-
* open log file.
|
141
|
-
*/
|
142
|
-
private volatile String date = null;
|
143
|
-
|
144
|
-
/**
|
145
|
-
* The PrintWriter to which we are currently logging, if any.
|
146
|
-
*/
|
147
|
-
private volatile PrintWriter writer = null;
|
148
|
-
|
149
|
-
/**
|
150
|
-
* Lock used to control access to the writer.
|
151
|
-
*/
|
152
|
-
protected final ReadWriteLock writerLock = new ReentrantReadWriteLock();
|
153
|
-
|
154
|
-
// --------------------------------------------------------- Public Methods
|
155
|
-
|
156
|
-
|
157
|
-
/**
|
158
|
-
* Format and publish a <tt>LogRecord</tt>.
|
159
|
-
*
|
160
|
-
* @param record description of the log event
|
161
|
-
*/
|
162
|
-
@Override
|
163
|
-
public void publish(LogRecord record) {
|
164
|
-
|
165
|
-
if (!isLoggable(record)) {
|
166
|
-
return;
|
167
|
-
}
|
168
|
-
|
169
|
-
final String tsDate = rotatable ?
|
170
|
-
new Timestamp(System.currentTimeMillis()).toString().substring(0, 10) : "";
|
171
|
-
|
172
|
-
try {
|
173
|
-
writerLock.readLock().lock();
|
174
|
-
// If the date has changed, switch log files
|
175
|
-
// Construct the timestamp we will use, if requested
|
176
|
-
// (... if not rotatable this will happen only once)
|
177
|
-
if ( !tsDate.equals(date) ) {
|
178
|
-
try {
|
179
|
-
// Update to writeLock before we switch
|
180
|
-
writerLock.readLock().unlock();
|
181
|
-
writerLock.writeLock().lock();
|
182
|
-
|
183
|
-
// Make sure another thread hasn't already done this
|
184
|
-
if ( !tsDate.equals(date) ) {
|
185
|
-
closeWriter();
|
186
|
-
date = tsDate;
|
187
|
-
openWriter();
|
188
|
-
}
|
189
|
-
} finally {
|
190
|
-
writerLock.writeLock().unlock();
|
191
|
-
// Down grade to read-lock. This ensures the writer remains valid
|
192
|
-
// until the log message is written
|
193
|
-
writerLock.readLock().lock();
|
194
|
-
}
|
195
|
-
}
|
196
|
-
|
197
|
-
String result = null;
|
198
|
-
try {
|
199
|
-
result = getFormatter().format(record);
|
200
|
-
} catch (Exception e) {
|
201
|
-
reportError(null, e, ErrorManager.FORMAT_FAILURE);
|
202
|
-
return;
|
203
|
-
}
|
204
|
-
|
205
|
-
try {
|
206
|
-
if (writer!=null) {
|
207
|
-
writer.write(result);
|
208
|
-
if (bufferSize == null || bufferSize < 0) {
|
209
|
-
writer.flush();
|
210
|
-
}
|
211
|
-
} else {
|
212
|
-
reportError("FileHandler is closed or not yet initialized, unable to log ["+result+"]", null, ErrorManager.WRITE_FAILURE);
|
213
|
-
}
|
214
|
-
} catch (Exception e) {
|
215
|
-
reportError(null, e, ErrorManager.WRITE_FAILURE);
|
216
|
-
return;
|
217
|
-
}
|
218
|
-
} finally {
|
219
|
-
writerLock.readLock().unlock();
|
220
|
-
}
|
221
|
-
}
|
222
|
-
|
223
|
-
|
224
|
-
// -------------------------------------------------------- Private Methods
|
225
|
-
|
226
|
-
|
227
|
-
/**
|
228
|
-
* Close the currently open log file (if any).
|
229
|
-
*/
|
230
|
-
@Override
|
231
|
-
public void close() {
|
232
|
-
closeWriter();
|
233
|
-
}
|
234
|
-
|
235
|
-
protected void closeWriter() {
|
236
|
-
|
237
|
-
writerLock.writeLock().lock();
|
238
|
-
try {
|
239
|
-
if (writer == null)
|
240
|
-
return;
|
241
|
-
writer.write(getFormatter().getTail(this));
|
242
|
-
writer.flush();
|
243
|
-
writer.close();
|
244
|
-
writer = null;
|
245
|
-
date = null;
|
246
|
-
} catch (Exception e) {
|
247
|
-
reportError(null, e, ErrorManager.CLOSE_FAILURE);
|
248
|
-
} finally {
|
249
|
-
writerLock.writeLock().unlock();
|
250
|
-
}
|
251
|
-
}
|
252
|
-
|
253
|
-
|
254
|
-
/**
|
255
|
-
* Flush the writer.
|
256
|
-
*/
|
257
|
-
@Override
|
258
|
-
public void flush() {
|
259
|
-
|
260
|
-
writerLock.readLock().lock();
|
261
|
-
try {
|
262
|
-
if (writer == null)
|
263
|
-
return;
|
264
|
-
writer.flush();
|
265
|
-
} catch (Exception e) {
|
266
|
-
reportError(null, e, ErrorManager.FLUSH_FAILURE);
|
267
|
-
} finally {
|
268
|
-
writerLock.readLock().unlock();
|
269
|
-
}
|
270
|
-
|
271
|
-
}
|
272
|
-
|
273
|
-
/**
|
274
|
-
* Configure from <code>LogManager</code> properties.
|
275
|
-
*/
|
276
|
-
private void configure() {
|
277
|
-
|
278
|
-
Timestamp ts = new Timestamp(System.currentTimeMillis());
|
279
|
-
date = ts.toString().substring(0, 10);
|
280
|
-
|
281
|
-
String className = this.getClass().getName(); //allow classes to override
|
282
|
-
|
283
|
-
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
284
|
-
|
285
|
-
// Retrieve configuration of logging file name
|
286
|
-
if (rotatable == null)
|
287
|
-
rotatable = Boolean.parseBoolean(getProperty(className + ".rotatable", "true"));
|
288
|
-
if (directory == null)
|
289
|
-
directory = getProperty(className + ".directory", "logs");
|
290
|
-
if (prefix == null)
|
291
|
-
prefix = getProperty(className + ".prefix", "juli.");
|
292
|
-
if (suffix == null)
|
293
|
-
suffix = getProperty(className + ".suffix", ".log");
|
294
|
-
if (bufferSize == null) {
|
295
|
-
String sBufferSize = getProperty(className + ".bufferSize", null);
|
296
|
-
try {
|
297
|
-
bufferSize = sBufferSize != null ? Integer.parseInt(sBufferSize) : null;
|
298
|
-
} catch (NumberFormatException ignore) { /* no op */ }
|
299
|
-
}
|
300
|
-
// Get encoding for the logging file
|
301
|
-
String encoding = getProperty(className + ".encoding", null);
|
302
|
-
if (encoding != null && encoding.length() > 0) {
|
303
|
-
try {
|
304
|
-
setEncoding(encoding);
|
305
|
-
} catch (UnsupportedEncodingException ex) {
|
306
|
-
// Ignore
|
307
|
-
}
|
308
|
-
}
|
309
|
-
|
310
|
-
// Get logging level for the handler
|
311
|
-
setLevel(Level.parse(getProperty(className + ".level", "" + Level.ALL)));
|
312
|
-
|
313
|
-
// Get filter configuration
|
314
|
-
String filterName = getProperty(className + ".filter", null);
|
315
|
-
if (filterName != null) {
|
316
|
-
try {
|
317
|
-
setFilter((Filter) cl.loadClass(filterName).newInstance());
|
318
|
-
} catch (Exception e) {
|
319
|
-
// Ignore
|
320
|
-
}
|
321
|
-
}
|
322
|
-
|
323
|
-
// Set formatter
|
324
|
-
String formatterName = getProperty(className + ".formatter", null);
|
325
|
-
if (formatterName != null) {
|
326
|
-
try {
|
327
|
-
setFormatter((Formatter) cl.loadClass(formatterName).newInstance());
|
328
|
-
} catch (Exception e) {
|
329
|
-
// Ignore and fallback to defaults
|
330
|
-
setFormatter(new SimpleFormatter());
|
331
|
-
}
|
332
|
-
} else {
|
333
|
-
setFormatter(new SimpleFormatter());
|
334
|
-
}
|
335
|
-
|
336
|
-
// Set error manager
|
337
|
-
setErrorManager(new ErrorManager());
|
338
|
-
|
339
|
-
}
|
340
|
-
|
341
|
-
|
342
|
-
private String getProperty(String name, String defaultValue) {
|
343
|
-
String value = LogManager.getLogManager().getProperty(name);
|
344
|
-
if (value == null) {
|
345
|
-
value = defaultValue;
|
346
|
-
} else {
|
347
|
-
value = value.trim();
|
348
|
-
}
|
349
|
-
return value;
|
350
|
-
}
|
351
|
-
|
352
|
-
|
353
|
-
/**
|
354
|
-
* Open the new log file for the date specified by <code>date</code>.
|
355
|
-
*/
|
356
|
-
public void open() {
|
357
|
-
openWriter();
|
358
|
-
}
|
359
|
-
|
360
|
-
protected void openWriter() {
|
361
|
-
|
362
|
-
// Create the directory if necessary
|
363
|
-
final File dir = new File(directory);
|
364
|
-
if ( !checkDir(dir) ) {
|
365
|
-
writer = null; return;
|
366
|
-
}
|
367
|
-
|
368
|
-
// Open the current log file
|
369
|
-
writerLock.writeLock().lock();
|
370
|
-
String logFileName = prefix + (rotatable ? date : "") + suffix;
|
371
|
-
try {
|
372
|
-
File logFile = new File(dir.getAbsoluteFile(), logFileName);
|
373
|
-
if ( !checkDir(logFile.getParentFile()) ) {
|
374
|
-
writer = null; return;
|
375
|
-
}
|
376
|
-
String encoding = getEncoding();
|
377
|
-
FileOutputStream fos = new FileOutputStream(logFile, true);
|
378
|
-
OutputStream os = (bufferSize != null && bufferSize > 0) ?
|
379
|
-
new BufferedOutputStream(fos, bufferSize) : fos;
|
380
|
-
writer = new PrintWriter(
|
381
|
-
(encoding != null) ? new OutputStreamWriter(os, encoding)
|
382
|
-
: new OutputStreamWriter(os), false);
|
383
|
-
writer.write(getFormatter().getHead(this));
|
384
|
-
} catch (Exception e) {
|
385
|
-
reportError(null, e, ErrorManager.OPEN_FAILURE);
|
386
|
-
writer = null;
|
387
|
-
} finally {
|
388
|
-
writerLock.writeLock().unlock();
|
389
|
-
}
|
390
|
-
|
391
|
-
}
|
392
|
-
|
393
|
-
private boolean checkDir(final File dir) {
|
394
|
-
if ( !dir.mkdirs() && !dir.isDirectory() ) {
|
395
|
-
reportError("Unable to create [" + dir + "]", null, ErrorManager.OPEN_FAILURE);
|
396
|
-
return false;
|
397
|
-
}
|
398
|
-
return true;
|
399
|
-
}
|
400
|
-
|
401
|
-
}
|