📄 accesslogvalve.java
字号:
/**
* Return the format pattern.
*/
public String getPattern() {
return (this.pattern);
}
/**
* Set the format pattern, first translating any recognized alias.
*
* @param pattern The new pattern
*/
public void setPattern(String pattern) {
if (pattern == null)
pattern = "";
if (pattern.equals(Constants.AccessLog.COMMON_ALIAS))
pattern = Constants.AccessLog.COMMON_PATTERN;
if (pattern.equals(Constants.AccessLog.COMBINED_ALIAS))
pattern = Constants.AccessLog.COMBINED_PATTERN;
this.pattern = pattern;
if (this.pattern.equals(Constants.AccessLog.COMMON_PATTERN))
common = true;
else
common = false;
if (this.pattern.equals(Constants.AccessLog.COMBINED_PATTERN))
combined = true;
else
combined = false;
}
/**
* Return the log file prefix.
*/
public String getPrefix() {
return (prefix);
}
/**
* Set the log file prefix.
*
* @param prefix The new log file prefix
*/
public void setPrefix(String prefix) {
this.prefix = prefix;
}
/**
* Should we rotate the logs
*/
public boolean isRotatable() {
return rotatable;
}
/**
* Set the value is we should we rotate the logs
*
* @param rotatable true is we should rotate.
*/
public void setRotatable(boolean rotatable) {
this.rotatable = rotatable;
}
/**
* Return the log file suffix.
*/
public String getSuffix() {
return (suffix);
}
/**
* Set the log file suffix.
*
* @param suffix The new log file suffix
*/
public void setSuffix(String suffix) {
this.suffix = suffix;
}
/**
* Set the resolve hosts flag.
*
* @param resolveHosts The new resolve hosts value
*/
public void setResolveHosts(boolean resolveHosts) {
this.resolveHosts = resolveHosts;
}
/**
* 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
/**
* 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
* @param context The valve context used to invoke the next valve
* in the current processing pipeline
*
* @exception IOException if an input/output error has occurred
* @exception ServletException if a servlet error has occurred
*/
public void invoke(Request request, Response response,
ValveContext context)
throws IOException, ServletException {
// Pass this request on to the next valve in our pipeline
long t1=System.currentTimeMillis();
context.invokeNext(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();
// Check to see if we should log using the "common" access log pattern
if (common || combined) {
String value = null;
ServletRequest req = request.getRequest();
HttpServletRequest hreq = (HttpServletRequest) req;
if (isResolveHosts())
result.append(req.getRemoteHost());
else
result.append(req.getRemoteAddr());
result.append(" - ");
value = hreq.getRemoteUser();
if (value == null)
result.append("- ");
else {
result.append(value);
result.append(space);
}
result.append("[");
result.append(dayFormatter.format(date)); // Day
result.append('/');
result.append(lookup(monthFormatter.format(date))); // Month
result.append('/');
result.append(yearFormatter.format(date)); // Year
result.append(':');
result.append(timeFormatter.format(date)); // Time
result.append(space);
result.append(timeZone); // Time Zone
result.append("] \"");
result.append(hreq.getMethod());
result.append(space);
result.append(hreq.getRequestURI());
if (hreq.getQueryString() != null) {
result.append('?');
result.append(hreq.getQueryString());
}
result.append(space);
result.append(hreq.getProtocol());
result.append("\" ");
result.append(((HttpResponse) response).getStatus());
result.append(space);
int length = response.getContentCount();
if (length <= 0)
value = "-";
else
value = "" + length;
result.append(value);
if (combined) {
result.append(space);
result.append("\"");
String referer = hreq.getHeader("referer");
if(referer != null)
result.append(referer);
else
result.append("-");
result.append("\"");
result.append(space);
result.append("\"");
String ua = hreq.getHeader("user-agent");
if(ua != null)
result.append(ua);
else
result.append("-");
result.append("\"");
}
} else {
// Generate a message based on the defined pattern
boolean replace = false;
for (int i = 0; i < pattern.length(); i++) {
char ch = pattern.charAt(i);
if (replace) {
/* For code that processes {, the behavior will be ... if I
* do not enounter a closing } - then I ignore the {
*/
if ('{' == ch){
StringBuffer name = new StringBuffer();
int j = i + 1;
for(;j < pattern.length() && '}' != pattern.charAt(j); j++) {
name.append(pattern.charAt(j));
}
if (j+1 < pattern.length()) {
/* the +1 was to account for } which we increment now */
j++;
result.append(replace(name.toString(),
pattern.charAt(j),
request,
response));
i=j; /*Since we walked more than one character*/
} else {
//D'oh - end of string - pretend we never did this
//and do processing the "old way"
result.append(replace(ch, date, request, response, time));
}
} else {
result.append(replace(ch, date, request, response,time ));
}
replace = false;
} else if (ch == '%') {
replace = true;
} else {
result.append(ch);
}
}
}
log(result.toString(), date);
}
// -------------------------------------------------------- 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
* @param date the current Date object (so this method doesn't need to
* create a new one)
*/
public void log(String message, Date date) {
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);
}
}
/**
* Return the month abbreviation for the specified month, which must
* be a two-digit String.
*
* @param month Month number ("01" .. "12").
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -