Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
 package org.apache.sling.engine.impl.log;
 
 import java.util.Date;
 import java.util.List;
 
 
The CustomLogFormat class implements the support for log format strings similar to the Apache httpd CustomLog configuration.

See also:
Client Request Logging for documentation of supported formats.
 
 class CustomLogFormat {
 
     /*
      * NOTE: Documentation at
      * https://cwiki.apache.org/confluence/display/SLINGxSITE
      * /Client+Request+Logging should be kept in sync with this class !
      */

    
The parsed list of log format parts whose print method is called when building the log message line.
 
     Parameter[] logParameters;

    
Creates a new instance from of this class parsing the log format pattern.

Parameters:
pattern The pattern to be parsed.
 
     CustomLogFormat(String pattern) {
         this. = this.parse(pattern);
         if (this..length == 0) {
             this. = null;
         }
     }

    
Creates a log message from the given request and response objects according to the log format from which this instance has been created.

Parameters:
request The RequestLoggerRequest used to extract values for the log message.
response The RequestLoggerResponse used to extract values for the log message.
Returns:
The formatted log message or null if this log formatter has not been initialized with a valid log format pattern.
 
     String format(RequestLoggerRequest requestRequestLoggerResponse response) {
         if (this. != null) {
             StringBuilder buf = new StringBuilder();
             for (int i = 0; i < this..lengthi++) {
                 this.[i].print(bufrequestresponse);
             }
             return buf.toString();
         }
 
         return null;
     }

    
Returns a string representation of this log format instance. The returned String is actually rebuilt from the parsed format string and may be used to create another instance of this class with the same format string.

Returns:
String representation of this instance.
    public String toString() {
        StringBuilder buf = new StringBuilder();
        for (int i = 0; this. != null && i < this..lengthi++) {
            buf.append(this.[i]);
        }
        return buf.toString();
    }
    // ---------- Parsing the format pattern -----------------------------------
    private Parameter[] parse(String pattern) {
        List<ParameterparameterList = new ArrayList<Parameter>();
        StringBuilder buf = new StringBuilder();
        CharacterIterator sr = new StringCharacterIterator(pattern);
        for (int c = sr.first(); c != .c = sr.next()) {
            if (c == '%') {
                int c1 = sr.next();
                if (c1 != '%') {
                    if (buf.length() > 0) {
                        Parameter text = new PlainTextParameter(buf.toString());
                        parameterList.add(text);
                        buf.setLength(0);
                    }
                    Parameter param = this.parseFormatString(src1);
                    if (param != null) {
                        parameterList.add(param);
                    }
                    continue;
                }
            }
            buf.append((charc);
        }
        // append any remaining plain text
        if (buf.length() > 0) {
            Parameter text = new PlainTextParameter(buf.toString());
            parameterList.add(text);
            buf.setLength(0);
        }
        return parameterList.toArray(new Parameter[parameterList.size()]);
    }
    private Parameter parseFormatString(CharacterIterator srint c) {
        // read all modifiers
        boolean required = true;
        int[] statCodes = null;
        while (c != .) {
            if (c == '!') {
                required = false;
            } else if (c >= '0' && c <= '9') {
                statCodes = this.parseStatusCodes(src);
            } else if (c == '>' || c == '<') {
                // ignore first/last modifiers
            } else {
                break;
            }
            c = sr.next();
        }
        // read name
        String name;
        if (c == '{') {
            StringBuilder nameBuf = new StringBuilder();
            for (c = sr.next(); c != . && c != '}'c = sr.next()) {
                nameBuf.append((charc);
            }
            name = (nameBuf.length() > 0) ? nameBuf.toString() : null;
            // get the format indicator
            c = sr.next();
        } else {
            name = null;
        }
        Parameter param;
        switch (c) {
            case 'a':
                param = new RemoteIPParameter();
                break;
            case 'A':
                param = new LocalIPParameter();
                break;
            case 'b':
            case 'B':
                param = new ByteCountParameter();
                break;
            case 'C':
                param = (name == null) ? null : new CookieParameter(nametrue);
                break;
            case 'D':
                param = new DurationParameter(false);
                break;
            case 'f':
                // we assume the path to the content the request resolved to
                param = new ContentPathParameter();
                break;
            case 'h':
                param = new RemoteHostParameter();
                break;
            case 'H':
                param = new ProtocolParameter();
                break;
            case 'i':
                param = (name == null) ? null : new HeaderParameter(nametrue);
                break;
            case 'm':
                param = new MethodParameter();
                break;
            case 'M':
                param = new ParamParameter(name);
                break;
            case 'o':
                param = (name == null) ? null : new HeaderParameter(namefalse);
                break;
            case 'p':
                param = new LocalPortParameter();
                break;
            case 'P':
                // %{format}P form is not currently supported
                param = new ThreadParameter(name);
                break;
            case 'q':
                param = new QueryParameter();
                break;
            case 'r':
                param = new FirstRequestLineParameter();
                break;
            case 'R':
                param = new IdParameter();
                break;
            case 's':
                param = new StatusParameter();
                break;
            case 't':
                // %{format}t form is not currently supported
                param = new TimeParameter(name);
                break;
            case 'T':
                param = new DurationParameter(true);
                break;
            case 'u':
                param = new UserParameter();
                break;
            case 'U':
                param = new RequestParameter();
                break;
            case 'v':
            case 'V':
                param = new ServerNameParameter();
                break;
            case 'y':
                param = new AuthTypeParameter();
                break;
            case 'X'// no supported fall through to default
            case 'I'// no supported fall through to default
            case 'O'// no supported fall through to default
            case 'n'// no supported fall through to default
            case 'l'// no supported fall through to default
            case 'e'// no supported fall through to default
            default:
                param = new NonImplementedParameter(name);
                break;
        }
        if (param instanceof BaseParameter) {
            BaseParameter baseParam = (BaseParameterparam;
            baseParam.setParName((charc);
            baseParam.setRequired(required);
            baseParam.setStatusLimits(statCodes);
        }
        return param;
    }
    private int[] parseStatusCodes(CharacterIterator srint c) {
        StringBuilder buf = new StringBuilder();
        buf.append((charc);
        List<Integernumbers = new ArrayList<Integer>();
        for (c = sr.next(); c != .c = sr.next()) {
            if (c == ',') {
                int num = 0;
                try {
                    num = Integer.parseInt(buf.toString());
                } catch (NumberFormatException nfe) {
                    // don't care
                }
                if (num >= 100 && num <= 999) {
                    numbers.add(num);
                }
                buf.setLength(0);
            } else if (c >= '0' && c <= '9') {
                buf.append((charc);
            } else {
                // end of number list
                break;
            }
        }
        // reset to the last mark
        sr.previous();
        // get the last number
        int num = 0;
        try {
            num = Integer.parseInt(buf.toString());
        } catch (NumberFormatException nfe) {
            // don't care
        }
        if (num >= 100 && num <= 999) {
            numbers.add(new Integer(num));
        }
        if (numbers.isEmpty()) {
            return null;
        }
        int[] statusCodes = new int[numbers.size()];
        for (int i = 0; i < numbers.size(); i++) {
            statusCodes[i] = (numbers.get(i)).intValue();
        }
        return statusCodes;
    }
    // ---------- Parameter support --------------------------------------------
    static interface Parameter {
        void print(StringBuilder destRequestLoggerRequest requestRequestLoggerResponse response);
    }
    static class PlainTextParameter implements Parameter {
        private String value;
        PlainTextParameter(String value) {
            this. = value;
        }
        public void print(StringBuilder destRequestLoggerRequest requestRequestLoggerResponse response) {
            dest.append(this.);
        }
        public String toString() {
            return this.;
        }
    }
    abstract static class BaseParameter implements Parameter {
        private int[] statusLimits;
        private boolean required;
        private char parName;
        private final String parParam;
        private final boolean isRequest;
        protected BaseParameter(String parParamboolean isRequest) {
            this. = parParam;
            this. = isRequest;
        }
        public void setParName(char parName) {
            this. = parName;
        }
        public void setStatusLimits(int[] statusLimits) {
            this. = statusLimits;
        }
        public void setRequired(boolean required) {
            this. = required;
        }
        protected abstract String getValue(RequestLoggerRequest request);
        protected abstract String getValue(RequestLoggerResponse response);
        public final void print(StringBuilder destRequestLoggerRequest requestRequestLoggerResponse response) {
            if (this.printOk(response.getStatus())) {
                String value = this. ? this.getValue(request) : this.getValue(response);
                dest.append((value == null) ? "-" : value);
            }
        }
        protected boolean printOk(int status) {
            if (this. == null) {
                return true;
            }
            for (int i = 0; i < this..lengthi++) {
                if (status == this.[i]) {
                    return this.;
                }
            }
            return !this.;
        }
        protected char getParName() {
            return this.;
        }
        protected String getParParam() {
            return this.;
        }
        public String toString() {
            StringBuilder result = new StringBuilder("%");
            if (this. != null) {
                if (!this.) {
                    result.append('!');
                }
                for (int i = 0; i < this..lengthi++) {
                    if (i > 0) {
                        result.append(',');
                    }
                    result.append(this.[i]);
                }
            }
            if (this. != null) {
                result.append('{').append(this.).append('}');
            }
            result.append(this.);
            return result.toString();
        }
        // --------- helper ----------------------------------------------------
        private static boolean isPrint(char c) {
            return c >= 0x20 && c < 0x7f && c != '\\' && c != '"';
        }
        static String escape(String value) {
            // nothing to do for empty values
            if (value == null || value.length() == 0) {
                return value;
            }
            // find the first non-printable
            int i = 0;
            while (i < value.length() && isPrint(value.charAt(i))) {
                i++;
            }
            // if none has been found, just return the value
            if (i >= value.length()) {
                return value;
            }
            // otherwise copy the printable first part in a string buffer
            // and start encoding
            StringBuilder buf = new StringBuilder(value.substring(0, i));
            while (i < value.length()) {
                char c = value.charAt(i);
                if (isPrint(c)) {
                    buf.append(c);
                } else if (c == '\n') { // LF
                    buf.append("\\n");
                } else if (c == '\r') { // CR
                    buf.append("\\r");
                } else if (c == '\t') { // HTAB
                    buf.append("\\t");
                } else if (c == '\f') { // VTAB
                    buf.append("\\f");
                } else if (c == '\b') { // BSP
                    buf.append("\\b");
                } else if (c == '"') { // "
                    buf.append("\\\"");
                } else if (c == '\\') { // \
                    buf.append("\\\\");
                } else { // encode
                    buf.append("\\u");
                    if (c < 0x10) {
                        buf.append('0'); // leading zero
                    }
                    if (c < 0x100) {
                        buf.append('0'); // leading zero
                    }
                    if (c < 0x1000) {
                        buf.append('0'); // leading zero
                    }
                    buf.append(Integer.toHexString(c));
                }
                i++;
            }
            // return the encoded string value
            return buf.toString();
        }
    }
    static class NonImplementedParameter extends BaseParameter {
        NonImplementedParameter(String parParam) {
            super(parParamtrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return null;
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class ThreadParameter extends BaseParameter {
        public ThreadParameter(String parParam) {
            super(parParamtrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return Thread.currentThread().getName();
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class ParamParameter extends BaseParameter {
        public ParamParameter(String parParam) {
            super(parParamtrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return request.getParameter(this.getParParam());
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class IdParameter extends BaseParameter {
        public IdParameter() {
            super(nullfalse);
        }
        protected String getValue(RequestLoggerRequest request) {
            return null;
        }
        protected String getValue(RequestLoggerResponse response) {
            return String.valueOf(response.getRequestId());
        }
    }
    static class ByteCountParameter extends BaseParameter {
        public ByteCountParameter() {
            super(nullfalse);
        }
        protected String getValue(RequestLoggerRequest request) {
            return null;
        }
        protected String getValue(RequestLoggerResponse response) {
            int count = response.getCount();
            if (count == 0) {
                return (this.getParName() == 'b') ? "-" : "0";
            }
            return String.valueOf(count);
        }
    }
    static class TimeParameter extends BaseParameter {

        
date format - see access logging in service()
        private static final SimpleDateFormat accessLogFmt = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss ".);

        
time format for GMT offset - see access logging in service()
        private static final DecimalFormat dfmt = new DecimalFormat("+0000;-0000");

        
the timezone for the timezone offset calculation
        private static final Calendar calendar = Calendar.getInstance();

        
last zone offset (cached by hours)
        private static String lastZoneOffset = "";
        private static long lastZoneOffsetHour = -1;

        
last formatted time (cached in seconds)
        private static String lastTimeFormatted = "";
        private static long lastTimeFormattedSeconds = -1;
        private final boolean requestStart;
        public TimeParameter(String parParam) {
            super(parParamfalse);
            this. = parParam == null || !parParam.equals("end");
        }
        protected String getValue(RequestLoggerRequest request) {
            return null;
        }
        protected String getValue(RequestLoggerResponse response) {
            long time = this. ? response.getRequestStart() : response.getRequestEnd();
            return timeFormatted(time);
        }
        // ---------- internal
        // -----------------------------------------------------
        static String timeFormatted(long time) {
            if (time / 1000 != ) {
                 = time / 1000;
                Date date = new Date(time);
                StringBuilder buf = new StringBuilder(.format(date));
                if (time / 3600000 != ) {
                     = time / 3600000;
                    .setTime(date);
                    int tzOffset = .get(.) + .get(.);
                    tzOffset /= (60 * 1000);
                    tzOffset = ((tzOffset / 60) * 100) + (tzOffset % 60);
                     = .format(tzOffset);
                }
                buf.append();
                 = buf.toString();
            }
            return ;
        }
    }
    static class DurationParameter extends BaseParameter {
        private final boolean seconds;
        public DurationParameter(boolean seconds) {
            super(nullfalse);
            this. = seconds;
        }
        protected String getValue(RequestLoggerRequest request) {
            return null;
        }
        protected String getValue(RequestLoggerResponse response) {
            long time = response.getRequestDuration();
            if (this.) {
                time /= 1000;
            }
            return String.valueOf(time);
        }
    }
    static class RemoteIPParameter extends BaseParameter {
        public RemoteIPParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return request.getRemoteAddr();
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class RemoteHostParameter extends BaseParameter {
        public RemoteHostParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return request.getRemoteHost();
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class LocalIPParameter extends BaseParameter {
        public LocalIPParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return request.getLocalAddr();
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class LocalPortParameter extends BaseParameter {
        public LocalPortParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return String.valueOf(request.getServerPort());
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class ServerNameParameter extends BaseParameter {
        public ServerNameParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return request.getServerName();
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class ContentPathParameter extends BaseParameter {
        public ContentPathParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            final Object resourcePath = request.getAttribute(.);
            if (resourcePath instanceof String) {
                return (StringresourcePath;
            }
            return null;
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class FirstRequestLineParameter extends BaseParameter {
        public FirstRequestLineParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            String query = request.getQueryString();
            query = (query == null || query.length() == 0) ? "" : "?" + query;
            return request.getMethod() + " " + request.getRequestURI() + query + " " + request.getProtocol();
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class ProtocolParameter extends BaseParameter {
        public ProtocolParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return request.getProtocol();
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class MethodParameter extends BaseParameter {
        public MethodParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return request.getMethod();
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class RequestParameter extends BaseParameter {
        public RequestParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            return request.getRequestURI();
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class QueryParameter extends BaseParameter {
        public QueryParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            String query = request.getQueryString();
            return (query == null || query.length() == 0) ? "" : "?" + query;
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class UserParameter extends BaseParameter {
        public UserParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            final String user = request.getRemoteUser();
            return (user == null) ? null : escape(user);
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class AuthTypeParameter extends BaseParameter {
        public AuthTypeParameter() {
            super(nulltrue);
        }
        protected String getValue(RequestLoggerRequest request) {
            final String authType = request.getAuthType();
            return (authType == null) ? null : escape(authType);
        }
        protected String getValue(RequestLoggerResponse response) {
            return null;
        }
    }
    static class StatusParameter extends BaseParameter {
        public StatusParameter() {
            super(nullfalse);
        }
        protected String getValue(RequestLoggerRequest request) {
            return null;
        }
        protected String getValue(RequestLoggerResponse response) {
            return String.valueOf(response.getStatus());
        }
    }
    static class CookieParameter extends BaseParameter {
        private String cookieName;
        CookieParameter(String cookieNameboolean isRequest) {
            super(cookieNameisRequest);
            this. = cookieName;
        }
        protected String getValue(RequestLoggerRequest request) {
            return getValue(request.getCookie(this.));
        }
        protected String getValue(RequestLoggerResponse response) {
            return getValue(response.getCookie(this.));
        }
        private String getValue(final Cookie cookie) {
            return (cookie == null) ? null : escape(cookie.getValue());
        }
    }
    static class HeaderParameter extends BaseParameter {
        private String headerName;
        HeaderParameter(String headerNameboolean isRequest) {
            super(headerNameisRequest);
            this. = headerName;
        }
        protected String getValue(RequestLoggerRequest request) {
            Enumeration<?> values = request.getHeaders(this.);
            if (values == null || !values.hasMoreElements()) {
                return null;
            }
            String value = (Stringvalues.nextElement();
            while (values.hasMoreElements()) {
                value += "," + values.nextElement();
            }
            return escape(value);
        }
        protected String getValue(RequestLoggerResponse response) {
            return escape(response.getHeadersString(this.));
        }
    }