ch.qos.logback.access.spi.AccessEvent Maven / Gradle / Ivy
/**
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2015, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package ch.qos.logback.access.spi;
import ch.qos.logback.access.AccessConstants;
import ch.qos.logback.access.pattern.AccessConverter;
import ch.qos.logback.access.servlet.Util;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;
// Contributors: Joern Huxhorn (see also bug #110)
/**
* The Access module's internal representation of logging events. When the
* logging component instance is called in the container to log then a
* AccessEvent
instance is created. This instance is passed
* around to the different logback components.
*
* @author Ceki Gülcü
* @author Sébastien Pennec
*/
public class AccessEvent implements Serializable, IAccessEvent {
private static final long serialVersionUID = 866718993618836343L;
private static final String EMPTY = "";
private transient final HttpServletRequest httpRequest;
private transient final HttpServletResponse httpResponse;
String queryString;
String requestURI;
String requestURL;
String remoteHost;
String remoteUser;
String remoteAddr;
String threadName;
String protocol;
String method;
String serverName;
String requestContent;
String responseContent;
String sessionID;
long elapsedTime;
Map requestHeaderMap;
Map requestParameterMap;
Map responseHeaderMap;
Map attributeMap;
long contentLength = SENTINEL;
int statusCode = SENTINEL;
int localPort = SENTINEL;
transient ServerAdapter serverAdapter;
/**
* The number of milliseconds elapsed from 1/1/1970 until logging event was
* created.
*/
private long timeStamp = 0;
public AccessEvent(HttpServletRequest httpRequest, HttpServletResponse httpResponse, ServerAdapter adapter) {
this.httpRequest = httpRequest;
this.httpResponse = httpResponse;
this.timeStamp = System.currentTimeMillis();
this.serverAdapter = adapter;
this.elapsedTime = calculateElapsedTime();
}
/**
* Returns the underlying HttpServletRequest. After serialization the returned
* value will be null.
*
* @return
*/
@Override
public HttpServletRequest getRequest() {
return httpRequest;
}
/**
* Returns the underlying HttpServletResponse. After serialization the returned
* value will be null.
*
* @return
*/
@Override
public HttpServletResponse getResponse() {
return httpResponse;
}
@Override
public long getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(long timeStamp) {
if (this.timeStamp != 0) {
throw new IllegalStateException("timeStamp has been already set for this event.");
} else {
this.timeStamp = timeStamp;
}
}
/**
* @param threadName The threadName to set.
*/
public void setThreadName(String threadName) {
this.threadName = threadName;
}
@Override
public String getThreadName() {
return threadName == null ? NA : threadName;
}
@Override
public String getRequestURI() {
if (requestURI == null) {
if (httpRequest != null) {
requestURI = httpRequest.getRequestURI();
} else {
requestURI = NA;
}
}
return requestURI;
}
@Override
public String getQueryString() {
if (queryString == null) {
if (httpRequest != null) {
StringBuilder buf = new StringBuilder();
final String qStr = httpRequest.getQueryString();
if (qStr != null) {
buf.append(AccessConverter.QUESTION_CHAR);
buf.append(qStr);
}
queryString = buf.toString();
} else {
queryString = NA;
}
}
return queryString;
}
/**
* The first line of the request.
*/
@Override
public String getRequestURL() {
if (requestURL == null) {
if (httpRequest != null) {
StringBuilder buf = new StringBuilder();
buf.append(httpRequest.getMethod());
buf.append(AccessConverter.SPACE_CHAR);
buf.append(httpRequest.getRequestURI());
buf.append(getQueryString());
buf.append(AccessConverter.SPACE_CHAR);
buf.append(httpRequest.getProtocol());
requestURL = buf.toString();
} else {
requestURL = NA;
}
}
return requestURL;
}
@Override
public String getRemoteHost() {
if (remoteHost == null) {
if (httpRequest != null) {
// the underlying implementation of HttpServletRequest will
// determine if remote lookup will be performed
remoteHost = httpRequest.getRemoteHost();
} else {
remoteHost = NA;
}
}
return remoteHost;
}
@Override
public String getRemoteUser() {
if (remoteUser == null) {
if (httpRequest != null) {
remoteUser = httpRequest.getRemoteUser();
} else {
remoteUser = NA;
}
}
return remoteUser;
}
@Override
public String getProtocol() {
if (protocol == null) {
if (httpRequest != null) {
protocol = httpRequest.getProtocol();
} else {
protocol = NA;
}
}
return protocol;
}
@Override
public String getMethod() {
if (method == null) {
if (httpRequest != null) {
method = httpRequest.getMethod();
} else {
method = NA;
}
}
return method;
}
@Override
public String getSessionID() {
if (sessionID == null) {
if (httpRequest != null) {
final HttpSession session = httpRequest.getSession();
if (session != null) {
sessionID = session.getId();
}
} else {
sessionID = NA;
}
}
return sessionID;
}
@Override
public String getServerName() {
if (serverName == null) {
if (httpRequest != null) {
serverName = httpRequest.getServerName();
} else {
serverName = NA;
}
}
return serverName;
}
@Override
public String getRemoteAddr() {
if (remoteAddr == null) {
if (httpRequest != null) {
remoteAddr = httpRequest.getRemoteAddr();
} else {
remoteAddr = NA;
}
}
return remoteAddr;
}
@Override
public String getRequestHeader(String key) {
String result = null;
key = key.toLowerCase();
if (requestHeaderMap == null) {
if (httpRequest != null) {
buildRequestHeaderMap();
result = requestHeaderMap.get(key);
}
} else {
result = requestHeaderMap.get(key);
}
if (result != null) {
return result;
} else {
return NA;
}
}
@Override
public Enumeration getRequestHeaderNames() {
// post-serialization
if (httpRequest == null) {
Vector list = new Vector(getRequestHeaderMap().keySet());
return list.elements();
}
return httpRequest.getHeaderNames();
}
@Override
public Map getRequestHeaderMap() {
if (requestHeaderMap == null) {
buildRequestHeaderMap();
}
return requestHeaderMap;
}
public void buildRequestHeaderMap() {
// according to RFC 2616 header names are case insensitive
// latest versions of Tomcat return header names in lower-case
requestHeaderMap = new TreeMap(String.CASE_INSENSITIVE_ORDER);
Enumeration e = httpRequest.getHeaderNames();
if (e == null) {
return;
}
while (e.hasMoreElements()) {
String key = e.nextElement();
requestHeaderMap.put(key, httpRequest.getHeader(key));
}
}
public void buildRequestParameterMap() {
requestParameterMap = new HashMap();
Enumeration e = httpRequest.getParameterNames();
if (e == null) {
return;
}
while (e.hasMoreElements()) {
String key = e.nextElement();
requestParameterMap.put(key, httpRequest.getParameterValues(key));
}
}
@Override
public Map getRequestParameterMap() {
if (requestParameterMap == null) {
buildRequestParameterMap();
}
return requestParameterMap;
}
@Override
public String getAttribute(String key) {
Object value = null;
if (attributeMap != null) {
// Event was prepared for deferred processing so we have a copy of attribute map and must use that copy
value = attributeMap.get(key);
} else if (httpRequest != null) {
// We have original request so take attribute from it
value = httpRequest.getAttribute(key);
}
return value != null ? value.toString() : NA;
}
private void copyAttributeMap() {
if (httpRequest == null) {
return;
}
attributeMap = new HashMap();
Enumeration names = httpRequest.getAttributeNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
Object value = httpRequest.getAttribute(name);
if (shouldCopyAttribute(name, value)) {
attributeMap.put(name, value);
}
}
}
private boolean shouldCopyAttribute(String name, Object value) {
if (AccessConstants.LB_INPUT_BUFFER.equals(name) || AccessConstants.LB_OUTPUT_BUFFER.equals(name)) {
// Do not copy attributes used by logback internally - these are available via other getters anyway
return false;
} else if (value == null) {
// No reasons to copy nulls - Map.get() will return null for missing keys and the list of attribute
// names is not available through IAccessEvent
return false;
} else {
// Only copy what is serializable
return value instanceof Serializable;
}
}
@Override
public String[] getRequestParameter(String key) {
if (httpRequest != null) {
String[] value = httpRequest.getParameterValues(key);
if (value == null) {
return new String[] { NA };
} else {
return value;
}
} else {
return new String[] { NA };
}
}
@Override
public String getCookie(String key) {
if (httpRequest != null) {
Cookie[] cookieArray = httpRequest.getCookies();
if (cookieArray == null) {
return NA;
}
for (Cookie cookie : cookieArray) {
if (key.equals(cookie.getName())) {
return cookie.getValue();
}
}
}
return NA;
}
@Override
public long getContentLength() {
if (contentLength == SENTINEL) {
if (httpResponse != null) {
contentLength = serverAdapter.getContentLength();
return contentLength;
}
}
return contentLength;
}
public int getStatusCode() {
if (statusCode == SENTINEL) {
if (httpResponse != null) {
statusCode = serverAdapter.getStatusCode();
}
}
return statusCode;
}
public long getElapsedSeconds() {
return elapsedTime < 0 ? elapsedTime : elapsedTime / 1000;
}
public long getElapsedTime() {
return elapsedTime;
}
private long calculateElapsedTime() {
if (serverAdapter.getRequestTimestamp() < 0) {
return -1;
}
return getTimeStamp() - serverAdapter.getRequestTimestamp();
}
public String getRequestContent() {
if (requestContent != null) {
return requestContent;
}
if (Util.isFormUrlEncoded(httpRequest)) {
StringBuilder buf = new StringBuilder();
Enumeration pramEnumeration = httpRequest.getParameterNames();
// example: id=1234&user=cgu
// number=1233&x=1
int count = 0;
try {
while (pramEnumeration.hasMoreElements()) {
String key = pramEnumeration.nextElement();
if (count++ != 0) {
buf.append("&");
}
buf.append(key);
buf.append("=");
String val = httpRequest.getParameter(key);
if (val != null) {
buf.append(val);
} else {
buf.append("");
}
}
} catch (Exception e) {
// FIXME Why is try/catch required?
e.printStackTrace();
}
requestContent = buf.toString();
} else {
// retrieve the byte array placed by TeeFilter
byte[] inputBuffer = (byte[]) httpRequest.getAttribute(AccessConstants.LB_INPUT_BUFFER);
if (inputBuffer != null) {
requestContent = new String(inputBuffer);
}
if (requestContent == null || requestContent.length() == 0) {
requestContent = EMPTY;
}
}
return requestContent;
}
public String getResponseContent() {
if (responseContent != null) {
return responseContent;
}
if (Util.isImageResponse(httpResponse)) {
responseContent = "[IMAGE CONTENTS SUPPRESSED]";
} else {
// retreive the byte array previously placed by TeeFilter
byte[] outputBuffer = (byte[]) httpRequest.getAttribute(AccessConstants.LB_OUTPUT_BUFFER);
if (outputBuffer != null) {
responseContent = new String(outputBuffer);
}
if (responseContent == null || responseContent.length() == 0) {
responseContent = EMPTY;
}
}
return responseContent;
}
public int getLocalPort() {
if (localPort == SENTINEL) {
if (httpRequest != null) {
localPort = httpRequest.getLocalPort();
}
}
return localPort;
}
public ServerAdapter getServerAdapter() {
return serverAdapter;
}
public String getResponseHeader(String key) {
buildResponseHeaderMap();
return responseHeaderMap.get(key);
}
void buildResponseHeaderMap() {
if (responseHeaderMap == null) {
responseHeaderMap = serverAdapter.buildResponseHeaderMap();
}
}
public Map getResponseHeaderMap() {
buildResponseHeaderMap();
return responseHeaderMap;
}
public List getResponseHeaderNameList() {
buildResponseHeaderMap();
return new ArrayList(responseHeaderMap.keySet());
}
public void prepareForDeferredProcessing() {
getRequestHeaderMap();
getRequestParameterMap();
getResponseHeaderMap();
getLocalPort();
getMethod();
getProtocol();
getRemoteAddr();
getRemoteHost();
getRemoteUser();
getRequestURI();
getRequestURL();
getServerName();
getTimeStamp();
getElapsedTime();
getStatusCode();
getContentLength();
getRequestContent();
getResponseContent();
copyAttributeMap();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy