Package utils

Source Code of utils.AccessLogger

/**
* Yobi, Project Hosting SW
*
* Copyright 2013 NAVER Corp.
* http://yobi.io
*
* @Author Yi EungJun
*
* Licensed 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 utils;

import controllers.UserApp;
import play.api.mvc.AsyncResult;
import play.api.mvc.PlainResult;
import play.libs.Akka;
import play.libs.F.Callback;
import play.libs.F.Promise;
import play.mvc.Http;
import play.mvc.Result;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class AccessLogger {

    /**
     * Return "-" if the given string is null or return itself.
     *
     * @param value - the String to be checked
     * @return the String itself, {@code "-"} if null String input
     */
    static private String orHyphen(String value) {
        if (value == null || value.isEmpty()) {
            return "-";
        } else {
            return value;
        }
    }

    /**
     * Double-quote the given string or return "-" if it is null.
     *
     * @param value - the String to be double-quoted
     * @return the double-quoted string, {@code "-"} if null String input
     */
    static private String quotedOrHyphen(String value) {
        if (value == null) {
            return "-";
        } else {
            return "\"" + value + "\"";
        }
    }

    /**
     * Log a message for an HTTP request.
     *
     * This method is called by
     * {@link Global#onRequest(play.mvc.Http.Request, java.lang.reflect.Method)}
     * after an HTTP request is processed.
     *
     * The format follows Combined Log Format of Apache HTTP Server, except these:
     *
     * 1. The third field is username. The value comes from the Yobi's
     *    authentication scheme.
     * 2. The unit-postfixed time taken to serve the request is added at the
     *    end of log entry.
     * 3. The ident field and size of response in bytes is always empty with "-",
     *    because of functional limitation of Yobi.
     *
     * Here is an example:
     *
     * 127.0.0.1 - eungjun [16/Oct/2013:18:31:31 +0900] "GET /messages.js HTTP/1.1" 200 - "http://yobi:9000/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36" 18ms
     *
     * @param request an HTTP request
     * @param startTimeMillis the time in milliseconds when the request is received
     * @see <a href="http://httpd.apache.org/docs/2.2/en/logs.html#combined">Combined Log Format - Apache HTTP Server</a>
     * @see <a href="http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#formats">Custom Log Formats - Apache HTTP Server</a>
     */
    public static Result log(final Http.Request request, final Result result,
            final Long startTimeMillis) {
        if (result.getWrappedResult() instanceof PlainResult) {
            int status = ((PlainResult) result.getWrappedResult()).header().status();
            log(request, UserApp.currentUser().loginId, status, startTimeMillis);
        } else if (result.getWrappedResult() instanceof AsyncResult) {
            AsyncResult asyncResult = (AsyncResult) result.getWrappedResult();
            Promise<play.api.mvc.Result> promise = Akka.asPromise(asyncResult.result());
            promise.onRedeem(new Callback<play.api.mvc.Result>() {
                @Override
                public void invoke(final play.api.mvc.Result result) throws Throwable {
                    log(request, wrapResult(result), startTimeMillis);
                }
            });
        }
        return result;
    }

    private static Result wrapResult(final play.api.mvc.Result result) {
        return new Result() {
            @Override
            public play.api.mvc.Result getWrappedResult() {
                return result;
            }
        };
    }

    /**
     * Log a message for an HTTP request.
     *
     * This method is used by
     * {@link Global#onError(play.mvc.Http.RequestHeader, Throwable)},
     * {@link Global#onBadRequest(play.mvc.Http.RequestHeader, String)} and
     * {@link Global#onHandlerNotFound(play.mvc.Http.RequestHeader)}, which are
     * called if an error occurs while processing an HTTP request, to log a
     * message.
     *
     * This method is similar with
     * {@link #log(play.mvc.Http.Request, play.mvc.Result, Long)}, except this
     * requires an username and a status code instead of an HTTP response.
     *
     * @param request HTTP request header
     * @param username an username of HTTP request from {@link play.mvc.Http.Request#username()}
     * @param status HTTP status code
     * @see <a href="http://httpd.apache.org/docs/2.2/logs.html">Log Files - Apache HTTP Server</a>
     */
    public static void log(Http.RequestHeader request, String username, int status) {
        log(request, username, status, null);
    }

    /**
     * Log a message for an HTTP request.
     *
     * This method is used by
     * {@link #log(play.mvc.Http.Request, play.mvc.Result, Long)} and
     * {@link #log(play.mvc.Http.RequestHeader, String, in} to log a message.
     *
     * @param request HTTP request header
     * @param username an username of HTTP request from {@link play.mvc.Http.Request#username()}
     * @param status HTTP status code
     * @param startTimeMillis the time in milliseconds when the request is received
     * @see <a href="http://httpd.apache.org/docs/2.2/logs.html">Log Files - Apache HTTP Server</a>
     */
    private static void log(Http.RequestHeader request, String username, int status,
                            Long startTimeMillis) {
        if (request == null) {
            return;
        }

        SimpleDateFormat format = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss Z", Locale.ENGLISH);

        String time = (startTimeMillis != null) ?
                ((System.currentTimeMillis() - startTimeMillis) + "ms") : "-";

        String uri = request.uri();
        String entry = String.format("%s - %s [%s] \"%s %s %s\" %d - %s %s %s",
                request.remoteAddress(), orHyphen(username),
                format.format(new Date()), request.method(), request.uri(),
                request.version(), status,
                quotedOrHyphen(request.getHeader("Referer")),
                quotedOrHyphen(request.getHeader("User-Agent")),
                time);

        play.Logger.of("access." + uri).info(entry);
    }
}
TOP

Related Classes of utils.AccessLogger

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.