accesslog.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 788 行 · 第 1/2 页

JAVA
788
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.server.log;import com.caucho.config.ConfigException;import com.caucho.config.types.Bytes;import com.caucho.config.types.CronType;import com.caucho.config.types.Period;import com.caucho.loader.CloseListener;import com.caucho.loader.Environment;import com.caucho.server.connection.AbstractHttpRequest;import com.caucho.server.connection.AbstractHttpResponse;import com.caucho.server.util.CauchoSystem;import com.caucho.util.*;import com.caucho.vfs.Path;import javax.annotation.PostConstruct;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.net.InetAddress;import java.util.ArrayList;import java.util.logging.Logger;import java.util.regex.*;/** * Represents an log of every top-level request to the server. */public class AccessLog extends AbstractAccessLog implements AlarmListener{  protected static final L10N L = new L10N(AccessLog.class);  protected static final Logger log    = Logger.getLogger(AccessLog.class.getName());    // Default maximum log size = 1G  private static final long ROLLOVER_SIZE = 1024L * 1024L * 1024L;  // Milliseconds in a day  private static final long DAY = 24L * 3600L * 1000L;  // How often to check size  private static final long ROLLOVER_CHECK_TIME = 600L * 1000L;  public static final int BUFFER_SIZE = 65536;  private static final int BUFFER_GAP = 8 * 1024;    private QDate _calendar = QDate.createLocal();  private String _timeFormat;  private int _timeFormatSecondOffset = -1;  private final AccessLogWriter _logWriter = new AccessLogWriter(this);    // AccessStream  private Object _streamLock = new Object();  private String _format;  private Segment []_segments;  private ArrayList<Pattern> _excludeList = new ArrayList<Pattern>();  private Pattern []_excludes = new Pattern[0];  private boolean _isAutoFlush;    private boolean _isSharedBuffer = false;  private Object _sharedBufferLock;  private long _autoFlushTime = 60000;  private final CharBuffer _cb = new CharBuffer();    private final CharBuffer _timeCharBuffer = new CharBuffer();  private final ByteBuffer _timeBuffer = new ByteBuffer();  private long _lastTime;  private Alarm _alarm = new Alarm(this);  private boolean _isActive;  public AccessLog()  {    setRolloverSize(new Bytes(ROLLOVER_SIZE));  }    /**   * Sets the access log format.   */  public void setFormat(String format)  {    _format = format;  }  /**   * Sets the log path   */  public void setPath(Path path)  {    super.setPath(path);        _logWriter.setPath(path);  }  /**   * Sets the formatted path.   */  public void setPathFormat(String pathFormat)    throws ConfigException  {    super.setPathFormat(pathFormat);        _logWriter.setPathFormat(pathFormat);  }  /**   * Sets the archive name format   */  public void setArchiveFormat(String format)  {    _logWriter.setArchiveFormat(format);  }  /**   * Sets the maximum number of rolled logs.   *   * @param count maximum count of the log file   */  public void setRolloverCount(int count)  {    _logWriter.setRolloverCount(count);  }  /**   * Sets the log rollover cron   *   * @param cron the cron string for rollover times   */  public void setRolloverCron(CronType cron)  {    _logWriter.setRolloverCron(cron);  }  /**   * Sets the log rollover period, rounded up to the nearest hour.   *   * @param period the new rollover period in milliseconds.   */  public void setRolloverPeriod(Period period)  {    _logWriter.setRolloverPeriod(period);  }  /**   * Sets the log rollover size, rounded up to the megabyte.   *   * @param size maximum size of the log file   */  public void setRolloverSize(Bytes bytes)  {    _logWriter.setRolloverSize(bytes);  }  /**   * Sets how often the log rollover will be checked.   *   * @param period how often the log rollover will be checked.   */  public void setRolloverCheckTime(long period)  {    _logWriter.setRolloverCheckPeriod(period);  }  /**   * Sets the auto-flush attribute.   */  public void setAutoFlush(boolean isAutoFlush)  {    _isAutoFlush =  isAutoFlush;  }  /**   * Sets the autoFlushTime   */  public void setAutoFlushTime(Period period)  {    _autoFlushTime = period.getPeriod();  }  /**   * Sets the shared buffer attribute.   */  public void setSharedBuffer(boolean isSharedBuffer)  {    _isSharedBuffer = isSharedBuffer;  }  /**   * Adds an exclusion pattern.   */  public void addExclude(Pattern pattern)  {    _excludeList.add(pattern);    _excludes = new Pattern[_excludeList.size()];    _excludeList.toArray(_excludes);  }    /**   * Initialize the log.   */  @PostConstruct  public void init()    throws ServletException, IOException  {    _isActive = true;        Environment.addClassLoaderListener(new CloseListener(this));        if (_format == null)      _format = "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"";    ArrayList<Segment> segments = parseFormat(_format);    _segments = new Segment[segments.size()];    segments.toArray(_segments);        if (_timeFormat == null || _timeFormat.equals("")) {      _timeFormat = "[%d/%b/%Y:%H:%M:%S %z]";      _timeFormatSecondOffset = 0;    }    _logWriter.init();    _sharedBufferLock = _logWriter.getBufferLock();    if (_autoFlushTime > 0)      _alarm.queue(_autoFlushTime);  }  /**   * Parses the access log string.   */  private ArrayList<Segment> parseFormat(String format)  {    ArrayList<Segment> segments = new ArrayList<Segment>();    CharBuffer cb = new CharBuffer();    int i = 0;    while (i < _format.length()) {      char ch = _format.charAt(i++);      if (ch != '%' || i >= _format.length()) {	cb.append((char) ch);	continue;      }            String arg = null;      ch = _format.charAt(i++);      if (ch == '>')	ch = _format.charAt(i++);      else if (ch == '{') {	if (cb.length() > 0)	  segments.add(new Segment(this, Segment.TEXT, cb.toString()));	cb.clear();	while (i < _format.length() && _format.charAt(i++) != '}')	  cb.append(_format.charAt(i - 1));	arg = cb.toString();	cb.clear();	ch = _format.charAt(i++);      }      switch (ch) {      case 'b': case 'c':      case 'h': case 'i': case 'l': case 'n':      case 'r': case 's':      case 'T': case 'D': case 'o':      case 'u': case 'U':	if (cb.length() > 0)	  segments.add(new Segment(this, Segment.TEXT, cb.toString()));	cb.clear();	segments.add(new Segment(this, ch, arg));	break;      case 't':	if (cb.length() > 0)	  segments.add(new Segment(this, Segment.TEXT, cb.toString()));	cb.clear();	if (arg != null)	  _timeFormat = arg;	segments.add(new Segment(this, ch, arg));	break;              default:	cb.append('%');	i--;	break;      }    }    cb.append(CauchoSystem.getNewlineString());    segments.add(new Segment(this, Segment.TEXT, cb.toString()));    return segments;  }  /**   * Logs a request using the current format.   */  public void log(HttpServletRequest req,		  HttpServletResponse res,		  ServletContext application)    throws IOException  {    AbstractHttpRequest request = (AbstractHttpRequest) req;    AbstractHttpResponse response = (AbstractHttpResponse) res;    // skip excluded urls    if (_excludes.length > 0) {      byte []data = request.getUriBuffer();      int sublen = request.getUriLength();      String uri = new String(data, 0, sublen);      for (Pattern pattern : _excludes) {	if (pattern.matcher(uri).find()) {	  return;	}      }    }    if (_isSharedBuffer && (! _isAutoFlush || _autoFlushTime <= 0)) {      synchronized (_sharedBufferLock) {	byte []buffer = _logWriter.getBuffer(BUFFER_GAP);	int length = _logWriter.getLength();	length = log(request, response,		     buffer, length, buffer.length - length);	_logWriter.setLength(length);      }    }    else {      byte []buffer = request.getLogBuffer();      int length = log(request, response, buffer, 0, buffer.length);      if (_isAutoFlush && _autoFlushTime > 0)	_logWriter.writeThrough(buffer, 0, length);      else	_logWriter.writeBuffer(buffer, 0, length);    }  }    /**   * Logs a request using the current format.   *   * @param request the servlet request.   * @param response the servlet response.   * @param buffer byte buffer containing the response   * @param offset buffer starting offset   * @param length length allowed in the buffer   *   * @return the new tail of the buffer   */  private int log(AbstractHttpRequest request,                  AbstractHttpResponse response,                  byte []buffer, int offset, int length)    throws IOException  {    int len = _segments.length;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?