PageRenderTime 53ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/tomcat-7.0.2/java/org/apache/catalina/valves/ExtendedAccessLogValve.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 855 lines | 705 code | 25 blank | 125 comment | 13 complexity | 6f04d877d3de23d6af57ca6acfa70f17 MD5 | raw file
  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. package org.apache.catalina.valves;
  18. import java.io.IOException;
  19. import java.io.StringReader;
  20. import java.net.InetAddress;
  21. import java.net.URLEncoder;
  22. import java.text.SimpleDateFormat;
  23. import java.util.ArrayList;
  24. import java.util.Date;
  25. import java.util.Iterator;
  26. import java.util.List;
  27. import java.util.TimeZone;
  28. import javax.servlet.http.Cookie;
  29. import javax.servlet.http.HttpSession;
  30. import org.apache.catalina.connector.Request;
  31. import org.apache.catalina.connector.Response;
  32. import org.apache.catalina.util.ServerInfo;
  33. import org.apache.juli.logging.Log;
  34. import org.apache.juli.logging.LogFactory;
  35. /**
  36. * An implementation of the W3c Extended Log File Format. See
  37. * http://www.w3.org/TR/WD-logfile.html for more information about the format.
  38. *
  39. * The following fields are supported:
  40. * <ul>
  41. * <li><code>c-dns</code>: Client hostname</li>
  42. * <li><code>c-ip</code>: Client ip address</li>
  43. * <li><code>bytes</code>: bytes served</li>
  44. * <li><code>cs-method</code>: request method</li>
  45. * <li><code>cs-uri</code>: The full uri requested</li>
  46. * <li><code>cs-uri-query</code>: The query string</li>
  47. * <li><code>cs-uri-stem</code>: The uri without query string</li>
  48. * <li><code>date</code>: The date in yyyy-mm-dd format for GMT</li>
  49. * <li><code>s-dns</code>: The server dns entry </li>
  50. * <li><code>s-ip</code>: The server ip address</li>
  51. * <li><code>cs(XXX)</code>: The value of header XXX from client to server</li>
  52. * <li><code>sc(XXX)</code>: The value of header XXX from server to client </li>
  53. * <li><code>sc-status</code>: The status code</li>
  54. * <li><code>time</code>: Time the request was served</li>
  55. * <li><code>time-taken</code>: Time (in seconds) taken to serve the request</li>
  56. * <li><code>x-A(XXX)</code>: Pull XXX attribute from the servlet context </li>
  57. * <li><code>x-C(XXX)</code>: Pull the first cookie of the name XXX </li>
  58. * <li><code>x-O(XXX)</code>: Pull the all response header values XXX </li>
  59. * <li><code>x-R(XXX)</code>: Pull XXX attribute from the servlet request </li>
  60. * <li><code>x-S(XXX)</code>: Pull XXX attribute from the session </li>
  61. * <li><code>x-P(...)</code>: Call request.getParameter(...)
  62. * and URLencode it. Helpful to capture
  63. * certain POST parameters.
  64. * </li>
  65. * <li>For any of the x-H(...) the following method will be called from the
  66. * HttpServletRequestObject </li>
  67. * <li><code>x-H(authType)</code>: getAuthType </li>
  68. * <li><code>x-H(characterEncoding)</code>: getCharacterEncoding </li>
  69. * <li><code>x-H(contentLength)</code>: getContentLength </li>
  70. * <li><code>x-H(locale)</code>: getLocale</li>
  71. * <li><code>x-H(protocol)</code>: getProtocol </li>
  72. * <li><code>x-H(remoteUser)</code>: getRemoteUser</li>
  73. * <li><code>x-H(requestedSessionId)</code>: getGequestedSessionId</li>
  74. * <li><code>x-H(requestedSessionIdFromCookie)</code>:
  75. * isRequestedSessionIdFromCookie </li>
  76. * <li><code>x-H(requestedSessionIdValid)</code>:
  77. * isRequestedSessionIdValid</li>
  78. * <li><code>x-H(scheme)</code>: getScheme</li>
  79. * <li><code>x-H(secure)</code>: isSecure</li>
  80. * </ul>
  81. *
  82. *
  83. *
  84. * <p>
  85. * Log rotation can be on or off. This is dictated by the rotatable
  86. * property.
  87. * </p>
  88. *
  89. * <p>
  90. * For UvNIX users, another field called <code>checkExists</code>is also
  91. * available. If set to true, the log file's existence will be checked before
  92. * each logging. This way an external log rotator can move the file
  93. * somewhere and tomcat will start with a new file.
  94. * </p>
  95. *
  96. * <p>
  97. * For JMX junkies, a public method called </code>rotate</code> has
  98. * been made available to allow you to tell this instance to move
  99. * the existing log file to somewhere else start writing a new log file.
  100. * </p>
  101. *
  102. * <p>
  103. * Conditional logging is also supported. This can be done with the
  104. * <code>condition</code> property.
  105. * If the value returned from ServletRequest.getAttribute(condition)
  106. * yields a non-null value. The logging will be skipped.
  107. * </p>
  108. *
  109. * <p>
  110. * For extended attributes coming from a getAttribute() call,
  111. * it is you responsibility to ensure there are no newline or
  112. * control characters.
  113. * </p>
  114. *
  115. *
  116. * @author Tim Funk
  117. * @author Peter Rossbach
  118. *
  119. * @version $Id: ExtendedAccessLogValve.java 939305 2010-04-29 13:43:39Z kkolinko $
  120. */
  121. public class ExtendedAccessLogValve extends AccessLogValve {
  122. private static final Log log = LogFactory.getLog(ExtendedAccessLogValve.class);
  123. // ----------------------------------------------------- Instance Variables
  124. /**
  125. * The descriptive information about this implementation.
  126. */
  127. protected static final String extendedAccessLogInfo =
  128. "org.apache.catalina.valves.ExtendedAccessLogValve/2.1";
  129. // ------------------------------------------------------------- Properties
  130. /**
  131. * Return descriptive information about this implementation.
  132. */
  133. @Override
  134. public String getInfo() {
  135. return (extendedAccessLogInfo);
  136. }
  137. // --------------------------------------------------------- Public Methods
  138. // -------------------------------------------------------- Private Methods
  139. /**
  140. * Wrap the incoming value into quotes and escape any inner
  141. * quotes with double quotes.
  142. *
  143. * @param value - The value to wrap quotes around
  144. * @return '-' if empty of null. Otherwise, toString() will
  145. * be called on the object and the value will be wrapped
  146. * in quotes and any quotes will be escaped with 2
  147. * sets of quotes.
  148. */
  149. private String wrap(Object value) {
  150. String svalue;
  151. // Does the value contain a " ? If so must encode it
  152. if (value == null || "-".equals(value))
  153. return "-";
  154. try {
  155. svalue = value.toString();
  156. if ("".equals(svalue))
  157. return "-";
  158. } catch (Throwable e) {
  159. /* Log error */
  160. return "-";
  161. }
  162. /* Wrap all quotes in double quotes. */
  163. StringBuilder buffer = new StringBuilder(svalue.length() + 2);
  164. buffer.append('\'');
  165. int i = 0;
  166. while (i < svalue.length()) {
  167. int j = svalue.indexOf('\'', i);
  168. if (j == -1) {
  169. buffer.append(svalue.substring(i));
  170. i = svalue.length();
  171. } else {
  172. buffer.append(svalue.substring(i, j + 1));
  173. buffer.append('"');
  174. i = j + 2;
  175. }
  176. }
  177. buffer.append('\'');
  178. return buffer.toString();
  179. }
  180. /**
  181. * Open the new log file for the date specified by <code>dateStamp</code>.
  182. */
  183. @Override
  184. protected synchronized void open() {
  185. super.open();
  186. if (currentLogFile.length()==0) {
  187. writer.println("#Fields: " + pattern);
  188. writer.println("#Version: 2.0");
  189. writer.println("#Software: " + ServerInfo.getServerInfo());
  190. }
  191. }
  192. // ------------------------------------------------------ Lifecycle Methods
  193. protected static class DateElement implements AccessLogElement {
  194. // Milli-seconds in 24 hours
  195. private static final long INTERVAL = (1000 * 60 * 60 * 24);
  196. private static final ThreadLocal<ElementTimestampStruct> currentDate =
  197. new ThreadLocal<ElementTimestampStruct>() {
  198. @Override
  199. protected ElementTimestampStruct initialValue() {
  200. return new ElementTimestampStruct("yyyy-MM-dd");
  201. }
  202. };
  203. public void addElement(StringBuilder buf, Date date, Request request,
  204. Response response, long time) {
  205. ElementTimestampStruct eds = currentDate.get();
  206. long millis = eds.currentTimestamp.getTime();
  207. if (date.getTime() > (millis + INTERVAL -1) ||
  208. date.getTime() < millis) {
  209. eds.currentTimestamp.setTime(
  210. date.getTime() - (date.getTime() % INTERVAL));
  211. eds.currentTimestampString =
  212. eds.currentTimestampFormat.format(eds.currentTimestamp);
  213. }
  214. buf.append(eds.currentTimestampString);
  215. }
  216. }
  217. protected static class TimeElement implements AccessLogElement {
  218. // Milli-seconds in a second
  219. private static final long INTERVAL = 1000;
  220. private static final ThreadLocal<ElementTimestampStruct> currentTime =
  221. new ThreadLocal<ElementTimestampStruct>() {
  222. @Override
  223. protected ElementTimestampStruct initialValue() {
  224. return new ElementTimestampStruct("HH:mm:ss");
  225. }
  226. };
  227. public void addElement(StringBuilder buf, Date date, Request request,
  228. Response response, long time) {
  229. ElementTimestampStruct eds = currentTime.get();
  230. long millis = eds.currentTimestamp.getTime();
  231. if (date.getTime() > (millis + INTERVAL -1) ||
  232. date.getTime() < millis) {
  233. eds.currentTimestamp.setTime(
  234. date.getTime() - (date.getTime() % INTERVAL));
  235. eds.currentTimestampString =
  236. eds.currentTimestampFormat.format(eds.currentTimestamp);
  237. }
  238. buf.append(eds.currentTimestampString);
  239. }
  240. }
  241. protected class RequestHeaderElement implements AccessLogElement {
  242. private String header;
  243. public RequestHeaderElement(String header) {
  244. this.header = header;
  245. }
  246. public void addElement(StringBuilder buf, Date date, Request request,
  247. Response response, long time) {
  248. buf.append(wrap(request.getHeader(header)));
  249. }
  250. }
  251. protected class ResponseHeaderElement implements AccessLogElement {
  252. private String header;
  253. public ResponseHeaderElement(String header) {
  254. this.header = header;
  255. }
  256. public void addElement(StringBuilder buf, Date date, Request request,
  257. Response response, long time) {
  258. buf.append(wrap(response.getHeader(header)));
  259. }
  260. }
  261. protected class ServletContextElement implements AccessLogElement {
  262. private String attribute;
  263. public ServletContextElement(String attribute) {
  264. this.attribute = attribute;
  265. }
  266. public void addElement(StringBuilder buf, Date date, Request request,
  267. Response response, long time) {
  268. buf.append(wrap(request.getContext().getServletContext()
  269. .getAttribute(attribute)));
  270. }
  271. }
  272. protected class CookieElement implements AccessLogElement {
  273. private String name;
  274. public CookieElement(String name) {
  275. this.name = name;
  276. }
  277. public void addElement(StringBuilder buf, Date date, Request request,
  278. Response response, long time) {
  279. Cookie[] c = request.getCookies();
  280. for (int i = 0; c != null && i < c.length; i++) {
  281. if (name.equals(c[i].getName())) {
  282. buf.append(wrap(c[i].getValue()));
  283. }
  284. }
  285. }
  286. }
  287. /**
  288. * write a specific response header - x-O(xxx)
  289. */
  290. protected class ResponseAllHeaderElement implements AccessLogElement {
  291. private String header;
  292. public ResponseAllHeaderElement(String header) {
  293. this.header = header;
  294. }
  295. public void addElement(StringBuilder buf, Date date, Request request,
  296. Response response, long time) {
  297. if (null != response) {
  298. Iterator<String> iter = response.getHeaders(header).iterator();
  299. if (iter.hasNext()) {
  300. StringBuilder buffer = new StringBuilder();
  301. boolean first = true;
  302. while (iter.hasNext()) {
  303. if (!first) {
  304. buffer.append(",");
  305. }
  306. buffer.append(iter.next());
  307. }
  308. buf.append(wrap(buffer.toString()));
  309. }
  310. return ;
  311. }
  312. buf.append("-");
  313. }
  314. }
  315. protected class RequestAttributeElement implements AccessLogElement {
  316. private String attribute;
  317. public RequestAttributeElement(String attribute) {
  318. this.attribute = attribute;
  319. }
  320. public void addElement(StringBuilder buf, Date date, Request request,
  321. Response response, long time) {
  322. buf.append(wrap(request.getAttribute(attribute)));
  323. }
  324. }
  325. protected class SessionAttributeElement implements AccessLogElement {
  326. private String attribute;
  327. public SessionAttributeElement(String attribute) {
  328. this.attribute = attribute;
  329. }
  330. public void addElement(StringBuilder buf, Date date, Request request,
  331. Response response, long time) {
  332. HttpSession session = null;
  333. if (request != null) {
  334. session = request.getSession(false);
  335. if (session != null)
  336. buf.append(wrap(session.getAttribute(attribute)));
  337. }
  338. }
  339. }
  340. protected class RequestParameterElement implements AccessLogElement {
  341. private String parameter;
  342. public RequestParameterElement(String parameter) {
  343. this.parameter = parameter;
  344. }
  345. /**
  346. * urlEncode the given string. If null or empty, return null.
  347. */
  348. private String urlEncode(String value) {
  349. if (null==value || value.length()==0) {
  350. return null;
  351. }
  352. return URLEncoder.encode(value);
  353. }
  354. public void addElement(StringBuilder buf, Date date, Request request,
  355. Response response, long time) {
  356. buf.append(wrap(urlEncode(request.getParameter(parameter))));
  357. }
  358. }
  359. protected class PatternTokenizer {
  360. private StringReader sr = null;
  361. private StringBuilder buf = new StringBuilder();
  362. private boolean ended = false;
  363. private boolean subToken;
  364. private boolean parameter;
  365. public PatternTokenizer(String str) {
  366. sr = new StringReader(str);
  367. }
  368. public boolean hasSubToken() {
  369. return subToken;
  370. }
  371. public boolean hasParameter() {
  372. return parameter;
  373. }
  374. public String getToken() throws IOException {
  375. if(ended)
  376. return null ;
  377. String result = null;
  378. subToken = false;
  379. parameter = false;
  380. int c = sr.read();
  381. while (c != -1) {
  382. switch (c) {
  383. case ' ':
  384. result = buf.toString();
  385. buf = new StringBuilder();
  386. buf.append((char) c);
  387. return result;
  388. case '-':
  389. result = buf.toString();
  390. buf = new StringBuilder();
  391. subToken = true;
  392. return result;
  393. case '(':
  394. result = buf.toString();
  395. buf = new StringBuilder();
  396. parameter = true;
  397. return result;
  398. case ')':
  399. result = buf.toString();
  400. buf = new StringBuilder();
  401. break;
  402. default:
  403. buf.append((char) c);
  404. }
  405. c = sr.read();
  406. }
  407. ended = true;
  408. if (buf.length() != 0) {
  409. return buf.toString();
  410. } else {
  411. return null;
  412. }
  413. }
  414. public String getParameter()throws IOException {
  415. String result;
  416. if (!parameter) {
  417. return null;
  418. }
  419. parameter = false;
  420. int c = sr.read();
  421. while (c != -1) {
  422. if (c == ')') {
  423. result = buf.toString();
  424. buf = new StringBuilder();
  425. return result;
  426. }
  427. buf.append((char) c);
  428. c = sr.read();
  429. }
  430. return null;
  431. }
  432. public String getWhiteSpaces() throws IOException {
  433. if(isEnded())
  434. return "" ;
  435. StringBuilder whiteSpaces = new StringBuilder();
  436. if (buf.length() > 0) {
  437. whiteSpaces.append(buf);
  438. buf = new StringBuilder();
  439. }
  440. int c = sr.read();
  441. while (Character.isWhitespace((char) c)) {
  442. whiteSpaces.append((char) c);
  443. c = sr.read();
  444. }
  445. if (c == -1) {
  446. ended = true;
  447. } else {
  448. buf.append((char) c);
  449. }
  450. return whiteSpaces.toString();
  451. }
  452. public boolean isEnded() {
  453. return ended;
  454. }
  455. public String getRemains() throws IOException {
  456. StringBuilder remains = new StringBuilder();
  457. for(int c = sr.read(); c != -1; c = sr.read()) {
  458. remains.append((char) c);
  459. }
  460. return remains.toString();
  461. }
  462. }
  463. @Override
  464. protected AccessLogElement[] createLogElements() {
  465. if (log.isDebugEnabled()) {
  466. log.debug("decodePattern, pattern =" + pattern);
  467. }
  468. List<AccessLogElement> list = new ArrayList<AccessLogElement>();
  469. PatternTokenizer tokenizer = new PatternTokenizer(pattern);
  470. try {
  471. // Ignore leading whitespace.
  472. tokenizer.getWhiteSpaces();
  473. if (tokenizer.isEnded()) {
  474. log.info("pattern was just empty or whitespace");
  475. return null;
  476. }
  477. String token = tokenizer.getToken();
  478. while (token != null) {
  479. if (log.isDebugEnabled()) {
  480. log.debug("token = " + token);
  481. }
  482. AccessLogElement element = getLogElement(token, tokenizer);
  483. if (element == null) {
  484. break;
  485. }
  486. list.add(element);
  487. String whiteSpaces = tokenizer.getWhiteSpaces();
  488. if (whiteSpaces.length() > 0) {
  489. list.add(new StringElement(whiteSpaces));
  490. }
  491. if (tokenizer.isEnded()) {
  492. break;
  493. }
  494. token = tokenizer.getToken();
  495. }
  496. if (log.isDebugEnabled()) {
  497. log.debug("finished decoding with element size of: " + list.size());
  498. }
  499. return list.toArray(new AccessLogElement[0]);
  500. } catch (IOException e) {
  501. log.error("parse error", e);
  502. return null;
  503. }
  504. }
  505. protected AccessLogElement getLogElement(String token, PatternTokenizer tokenizer) throws IOException {
  506. if ("date".equals(token)) {
  507. return new DateElement();
  508. } else if ("time".equals(token)) {
  509. if (tokenizer.hasSubToken()) {
  510. String nextToken = tokenizer.getToken();
  511. if ("taken".equals(nextToken)) {
  512. return new ElapsedTimeElement(false);
  513. }
  514. } else {
  515. return new TimeElement();
  516. }
  517. } else if ("bytes".equals(token)) {
  518. return new ByteSentElement(true);
  519. } else if ("cached".equals(token)) {
  520. /* I don't know how to evaluate this! */
  521. return new StringElement("-");
  522. } else if ("c".equals(token)) {
  523. String nextToken = tokenizer.getToken();
  524. if ("ip".equals(nextToken)) {
  525. return new RemoteAddrElement();
  526. } else if ("dns".equals(nextToken)) {
  527. return new HostElement();
  528. }
  529. } else if ("s".equals(token)) {
  530. String nextToken = tokenizer.getToken();
  531. if ("ip".equals(nextToken)) {
  532. return new LocalAddrElement();
  533. } else if ("dns".equals(nextToken)) {
  534. return new AccessLogElement() {
  535. public void addElement(StringBuilder buf, Date date,
  536. Request request, Response response, long time) {
  537. String value;
  538. try {
  539. value = InetAddress.getLocalHost().getHostName();
  540. } catch (Throwable e) {
  541. value = "localhost";
  542. }
  543. buf.append(value);
  544. }
  545. };
  546. }
  547. } else if ("cs".equals(token)) {
  548. return getClientToServerElement(tokenizer);
  549. } else if ("sc".equals(token)) {
  550. return getServerToClientElement(tokenizer);
  551. } else if ("sr".equals(token) || "rs".equals(token)) {
  552. return getProxyElement(tokenizer);
  553. } else if ("x".equals(token)) {
  554. return getXParameterElement(tokenizer);
  555. }
  556. log.error("unable to decode with rest of chars starting: " + token);
  557. return null;
  558. }
  559. protected AccessLogElement getClientToServerElement(
  560. PatternTokenizer tokenizer) throws IOException {
  561. if (tokenizer.hasSubToken()) {
  562. String token = tokenizer.getToken();
  563. if ("method".equals(token)) {
  564. return new MethodElement();
  565. } else if ("uri".equals(token)) {
  566. if (tokenizer.hasSubToken()) {
  567. token = tokenizer.getToken();
  568. if ("stem".equals(token)) {
  569. return new RequestURIElement();
  570. } else if ("query".equals(token)) {
  571. return new AccessLogElement() {
  572. public void addElement(StringBuilder buf, Date date,
  573. Request request, Response response,
  574. long time) {
  575. String query = request.getQueryString();
  576. if (query != null) {
  577. buf.append(query);
  578. } else {
  579. buf.append('-');
  580. }
  581. }
  582. };
  583. }
  584. } else {
  585. return new AccessLogElement() {
  586. public void addElement(StringBuilder buf, Date date,
  587. Request request, Response response, long time) {
  588. String query = request.getQueryString();
  589. if (query == null) {
  590. buf.append(request.getRequestURI());
  591. } else {
  592. buf.append(request.getRequestURI());
  593. buf.append('?');
  594. buf.append(request.getQueryString());
  595. }
  596. }
  597. };
  598. }
  599. }
  600. } else if (tokenizer.hasParameter()) {
  601. String parameter = tokenizer.getParameter();
  602. if (parameter == null) {
  603. log.error("No closing ) found for in decode");
  604. return null;
  605. }
  606. return new RequestHeaderElement(parameter);
  607. }
  608. log.error("The next characters couldn't be decoded: "
  609. + tokenizer.getRemains());
  610. return null;
  611. }
  612. protected AccessLogElement getServerToClientElement(
  613. PatternTokenizer tokenizer) throws IOException {
  614. if (tokenizer.hasSubToken()) {
  615. String token = tokenizer.getToken();
  616. if ("status".equals(token)) {
  617. return new HttpStatusCodeElement();
  618. } else if ("comment".equals(token)) {
  619. return new StringElement("?");
  620. }
  621. } else if (tokenizer.hasParameter()) {
  622. String parameter = tokenizer.getParameter();
  623. if (parameter == null) {
  624. log.error("No closing ) found for in decode");
  625. return null;
  626. }
  627. return new ResponseHeaderElement(parameter);
  628. }
  629. log.error("The next characters couldn't be decoded: "
  630. + tokenizer.getRemains());
  631. return null;
  632. }
  633. protected AccessLogElement getProxyElement(PatternTokenizer tokenizer)
  634. throws IOException {
  635. String token = null;
  636. if (tokenizer.hasSubToken()) {
  637. token = tokenizer.getToken();
  638. return new StringElement("-");
  639. } else if (tokenizer.hasParameter()) {
  640. tokenizer.getParameter();
  641. return new StringElement("-");
  642. }
  643. log.error("The next characters couldn't be decoded: " + token);
  644. return null;
  645. }
  646. protected AccessLogElement getXParameterElement(PatternTokenizer tokenizer)
  647. throws IOException {
  648. if (!tokenizer.hasSubToken()) {
  649. log.error("x param in wrong format. Needs to be 'x-#(...)' read the docs!");
  650. return null;
  651. }
  652. String token = tokenizer.getToken();
  653. if (!tokenizer.hasParameter()) {
  654. log.error("x param in wrong format. Needs to be 'x-#(...)' read the docs!");
  655. return null;
  656. }
  657. String parameter = tokenizer.getParameter();
  658. if (parameter == null) {
  659. log.error("No closing ) found for in decode");
  660. return null;
  661. }
  662. if ("A".equals(token)) {
  663. return new ServletContextElement(parameter);
  664. } else if ("C".equals(token)) {
  665. return new CookieElement(parameter);
  666. } else if ("R".equals(token)) {
  667. return new RequestAttributeElement(parameter);
  668. } else if ("S".equals(token)) {
  669. return new SessionAttributeElement(parameter);
  670. } else if ("H".equals(token)) {
  671. return getServletRequestElement(parameter);
  672. } else if ("P".equals(token)) {
  673. return new RequestParameterElement(parameter);
  674. } else if ("O".equals(token)) {
  675. return new ResponseAllHeaderElement(parameter);
  676. }
  677. log.error("x param for servlet request, couldn't decode value: "
  678. + token);
  679. return null;
  680. }
  681. protected AccessLogElement getServletRequestElement(String parameter) {
  682. if ("authType".equals(parameter)) {
  683. return new AccessLogElement() {
  684. public void addElement(StringBuilder buf, Date date,
  685. Request request, Response response, long time) {
  686. buf.append(wrap(request.getAuthType()));
  687. }
  688. };
  689. } else if ("remoteUser".equals(parameter)) {
  690. return new AccessLogElement() {
  691. public void addElement(StringBuilder buf, Date date,
  692. Request request, Response response, long time) {
  693. buf.append(wrap(request.getRemoteUser()));
  694. }
  695. };
  696. } else if ("requestedSessionId".equals(parameter)) {
  697. return new AccessLogElement() {
  698. public void addElement(StringBuilder buf, Date date,
  699. Request request, Response response, long time) {
  700. buf.append(wrap(request.getRequestedSessionId()));
  701. }
  702. };
  703. } else if ("requestedSessionIdFromCookie".equals(parameter)) {
  704. return new AccessLogElement() {
  705. public void addElement(StringBuilder buf, Date date,
  706. Request request, Response response, long time) {
  707. buf.append(wrap(""
  708. + request.isRequestedSessionIdFromCookie()));
  709. }
  710. };
  711. } else if ("requestedSessionIdValid".equals(parameter)) {
  712. return new AccessLogElement() {
  713. public void addElement(StringBuilder buf, Date date,
  714. Request request, Response response, long time) {
  715. buf.append(wrap("" + request.isRequestedSessionIdValid()));
  716. }
  717. };
  718. } else if ("contentLength".equals(parameter)) {
  719. return new AccessLogElement() {
  720. public void addElement(StringBuilder buf, Date date,
  721. Request request, Response response, long time) {
  722. buf.append(wrap("" + request.getContentLength()));
  723. }
  724. };
  725. } else if ("characterEncoding".equals(parameter)) {
  726. return new AccessLogElement() {
  727. public void addElement(StringBuilder buf, Date date,
  728. Request request, Response response, long time) {
  729. buf.append(wrap(request.getCharacterEncoding()));
  730. }
  731. };
  732. } else if ("locale".equals(parameter)) {
  733. return new AccessLogElement() {
  734. public void addElement(StringBuilder buf, Date date,
  735. Request request, Response response, long time) {
  736. buf.append(wrap(request.getLocale()));
  737. }
  738. };
  739. } else if ("protocol".equals(parameter)) {
  740. return new AccessLogElement() {
  741. public void addElement(StringBuilder buf, Date date,
  742. Request request, Response response, long time) {
  743. buf.append(wrap(request.getProtocol()));
  744. }
  745. };
  746. } else if ("scheme".equals(parameter)) {
  747. return new AccessLogElement() {
  748. public void addElement(StringBuilder buf, Date date,
  749. Request request, Response response, long time) {
  750. buf.append(request.getScheme());
  751. }
  752. };
  753. } else if ("secure".equals(parameter)) {
  754. return new AccessLogElement() {
  755. public void addElement(StringBuilder buf, Date date,
  756. Request request, Response response, long time) {
  757. buf.append(wrap("" + request.isSecure()));
  758. }
  759. };
  760. }
  761. log.error("x param for servlet request, couldn't decode value: "
  762. + parameter);
  763. return null;
  764. }
  765. private static class ElementTimestampStruct {
  766. private Date currentTimestamp = new Date(0);
  767. private SimpleDateFormat currentTimestampFormat;
  768. private String currentTimestampString;
  769. ElementTimestampStruct(String format) {
  770. currentTimestampFormat = new SimpleDateFormat(format);
  771. currentTimestampFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
  772. }
  773. }
  774. }