📄 accesslogvalve.java
字号:
}
/**
* Get the value of the resolve hosts flag.
*/
public boolean isResolveHosts() {
return resolveHosts;
}
/**
* Return whether the attribute name to look for when
* performing conditional loggging. If null, every
* request is logged.
*/
public String getCondition() {
return condition;
}
/**
* Set the ServletRequest.attribute to look for to perform
* conditional logging. Set to null to log everything.
*
* @param condition Set to null to log everything
*/
public void setCondition(String condition) {
this.condition = condition;
}
/**
* Return the date format date based log rotation.
*/
public String getFileDateFormat() {
return fileDateFormat;
}
/**
* Set the date format date based log rotation.
*/
public void setFileDateFormat(String fileDateFormat) {
this.fileDateFormat = fileDateFormat;
}
// --------------------------------------------------------- Public Methods
/**
* Execute a periodic task, such as reloading, etc. This method will be
* invoked inside the classloading context of this container. Unexpected
* throwables will be caught and logged.
*/
public void backgroundProcess() {
if (writer != null && buffered) {
writer.flush();
}
}
/**
* Log a message summarizing the specified request and response, according
* to the format specified by the <code>pattern</code> property.
*
* @param request Request being processed
* @param response Response being processed
*
* @exception IOException if an input/output error has occurred
* @exception ServletException if a servlet error has occurred
*/
public void invoke(Request request, Response response) throws IOException,
ServletException {
// Pass this request on to the next valve in our pipeline
long t1 = System.currentTimeMillis();
getNext().invoke(request, response);
long t2 = System.currentTimeMillis();
long time = t2 - t1;
if (condition != null
&& null != request.getRequest().getAttribute(condition)) {
return;
}
Date date = getDate();
StringBuffer result = new StringBuffer();
for (int i = 0; i < logElements.length; i++) {
logElements[i].addElement(result, date, request, response, time);
}
log(result.toString());
}
// -------------------------------------------------------- Private Methods
/**
* Close the currently open log file (if any)
*/
private synchronized void close() {
if (writer == null) {
return;
}
writer.flush();
writer.close();
writer = null;
dateStamp = "";
}
/**
* Log the specified message to the log file, switching files if the date
* has changed since the previous log call.
*
* @param message Message to be logged
*/
public void log(String message) {
if (rotatable) {
// Only do a logfile switch check once a second, max.
long systime = System.currentTimeMillis();
if ((systime - rotationLastChecked) > 1000) {
// We need a new currentDate
currentDate = new Date(systime);
rotationLastChecked = systime;
// Check for a change of date
String tsDate = dateFormatter.format(currentDate);
// If the date has changed, switch log files
if (!dateStamp.equals(tsDate)) {
synchronized (this) {
if (!dateStamp.equals(tsDate)) {
close();
dateStamp = tsDate;
open();
}
}
}
}
}
// Log this message
if (writer != null) {
writer.println(message);
if (!buffered) {
writer.flush();
}
}
}
/**
* Return the month abbreviation for the specified month, which must
* be a two-digit String.
*
* @param month Month number ("01" .. "12").
*/
private String lookup(String month) {
int index;
try {
index = Integer.parseInt(month) - 1;
} catch (Throwable t) {
index = 0; // Can not happen, in theory
}
return (months[index]);
}
/**
* Open the new log file for the date specified by <code>dateStamp</code>.
*/
private synchronized void open() {
// Create the directory if necessary
File dir = new File(directory);
if (!dir.isAbsolute())
dir = new File(System.getProperty("catalina.base"), directory);
dir.mkdirs();
// Open the current log file
try {
String pathname;
// If no rotate - no need for dateStamp in fileName
if (rotatable) {
pathname = dir.getAbsolutePath() + File.separator + prefix
+ dateStamp + suffix;
} else {
pathname = dir.getAbsolutePath() + File.separator + prefix
+ suffix;
}
writer = new PrintWriter(new BufferedWriter(new FileWriter(
pathname, true), 128000), false);
} catch (IOException e) {
writer = null;
}
}
/**
* This method returns a Date object that is accurate to within one second.
* If a thread calls this method to get a Date and it's been less than 1
* second since a new Date was created, this method simply gives out the
* same Date again so that the system doesn't spend time creating Date
* objects unnecessarily.
*
* @return Date
*/
private Date getDate() {
// Only create a new Date once per second, max.
long systime = System.currentTimeMillis();
if ((systime - currentMillis) > 1000) {
synchronized (this) {
if ((systime - currentMillis) > 1000) {
currentDate = new Date(systime);
currentMillis = systime;
}
}
}
return currentDate;
}
private String getTimeZone(Date date) {
if (timezone.inDaylightTime(date)) {
return timeZoneDST;
} else {
return timeZoneNoDST;
}
}
private String calculateTimeZoneOffset(long offset) {
StringBuffer tz = new StringBuffer();
if ((offset < 0)) {
tz.append("-");
offset = -offset;
} else {
tz.append("+");
}
long hourOffset = offset / (1000 * 60 * 60);
long minuteOffset = (offset / (1000 * 60)) % 60;
if (hourOffset < 10)
tz.append("0");
tz.append(hourOffset);
if (minuteOffset < 10)
tz.append("0");
tz.append(minuteOffset);
return tz.toString();
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Add a lifecycle event listener to this component.
*
* @param listener The listener to add
*/
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
/**
* Get the lifecycle listeners associated with this lifecycle. If this
* Lifecycle has no listeners registered, a zero-length array is returned.
*/
public LifecycleListener[] findLifecycleListeners() {
return lifecycle.findLifecycleListeners();
}
/**
* Remove a lifecycle event listener from this component.
*
* @param listener The listener to add
*/
public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
/**
* Prepare for the beginning of active use of the public methods of this
* component. This method should be called after <code>configure()</code>,
* and before any of the public methods of the component are utilized.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
public void start() throws LifecycleException {
// Validate and update our current component state
if (started)
throw new LifecycleException(sm
.getString("accessLogValve.alreadyStarted"));
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// Initialize the timeZone, Date formatters, and currentDate
timezone = TimeZone.getDefault();
timeZoneNoDST = calculateTimeZoneOffset(timezone.getRawOffset());
Calendar calendar = Calendar.getInstance(timezone);
int offset = calendar.get(Calendar.DST_OFFSET);
timeZoneDST = calculateTimeZoneOffset(timezone.getRawOffset() + offset);
if (fileDateFormat == null || fileDateFormat.length() == 0)
fileDateFormat = "yyyy-MM-dd";
dateFormatter = new SimpleDateFormat(fileDateFormat);
dateFormatter.setTimeZone(timezone);
dayFormatter = new SimpleDateFormat("dd");
dayFormatter.setTimeZone(timezone);
monthFormatter = new SimpleDateFormat("MM");
monthFormatter.setTimeZone(timezone);
yearFormatter = new SimpleDateFormat("yyyy");
yearFormatter.setTimeZone(timezone);
timeFormatter = new SimpleDateFormat("HH:mm:ss");
timeFormatter.setTimeZone(timezone);
currentDate = new Date();
dateStamp = dateFormatter.format(currentDate);
open();
}
/**
* Gracefully terminate the active use of the public methods of this
* component. This method should be the last one called on a given
* instance of this component.
*
* @exception LifecycleException if this component detects a fatal error
* that needs to be reported
*/
public void stop() throws LifecycleException {
// Validate and update our current component state
if (!started)
throw new LifecycleException(sm
.getString("accessLogValve.notStarted"));
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
close();
}
/**
* AccessLogElement writes the partial message into the buffer.
*/
private interface AccessLogElement {
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time);
}
/**
* write local IP address - %A
*/
private class LocalAddrElement implements AccessLogElement {
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time) {
String value;
try {
value = InetAddress.getLocalHost().getHostAddress();
} catch (Throwable e) {
value = "127.0.0.1";
}
buf.append(value);
}
}
/**
* write remote IP address - %a
*/
private class RemoteAddrElement implements AccessLogElement {
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time) {
buf.append(request.getRemoteAddr());
}
}
/**
* write remote host name - %h
*/
private class HostElement implements AccessLogElement {
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time) {
buf.append(request.getRemoteHost());
}
}
/**
* write remote logical username from identd (always returns '-') - %l
*/
private class LogicalUserNameElement implements AccessLogElement {
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time) {
buf.append('-');
}
}
/**
* write request protocol - %H
*/
private class ProtocolElement implements AccessLogElement {
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time) {
buf.append(request.getProtocol());
}
}
/**
* write remote user that was authenticated (if any), else '-' - %u
*/
private class UserElement implements AccessLogElement {
public void addElement(StringBuffer buf, Date date, Request request,
Response response, long time) {
if (request != null) {
String value = request.getRemoteUser();
if (value != null) {
buf.append(value);
} else {
buf.append('-');
}
} else {
buf.append('-');
}
}
}
/**
* write date and time, in Common Log Format - %t
*/
private class DateAndTimeElement implements AccessLogElement {
private Date currentDate = new Date(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -