Package org.restlet.service

Source Code of org.restlet.service.LogService

/**
* Copyright 2005-2011 Noelios Technologies.
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL 1.0 (the
* "Licenses"). You can select the license that you prefer but you may not use
* this file except in compliance with one of these Licenses.
*
* You can obtain a copy of the LGPL 3.0 license at
* http://www.opensource.org/licenses/lgpl-3.0.html
*
* You can obtain a copy of the LGPL 2.1 license at
* http://www.opensource.org/licenses/lgpl-2.1.php
*
* You can obtain a copy of the CDDL 1.0 license at
* http://www.opensource.org/licenses/cddl1.php
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://www.noelios.com/products/restlet-engine
*
* Restlet is a registered trademark of Noelios Technologies.
*/

package org.restlet.service;

import java.util.logging.LogManager;

import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.Method;
import org.restlet.data.Reference;
import org.restlet.data.Status;
import org.restlet.engine.log.LogFilter;
import org.restlet.representation.Representation;
import org.restlet.resource.ClientResource;
import org.restlet.routing.Filter;
import org.restlet.routing.Template;

/**
* Service providing access logging service. The implementation is fully based
* on the standard logging mechanism introduced in JDK 1.4.<br>
* <br>
* The default access log format follows the <a
* href="http://www.w3.org/TR/WD-logfile.html"> W3C Extended Log File Format</a>
* with the following fields used: <br>
* <ol>
* <li>Date (YYYY-MM-DD)</li>
* <li>Time (HH:MM:SS)</li>
* <li>Client address (IP)</li>
* <li>Remote user identifier (see RFC 1413)</li>
* <li>Server address (IP)</li>
* <li>Server port</li>
* <li>Method (GET|POST|...)</li>
* <li>Resource reference path (including the leading slash)</li>
* <li>Resource reference query (excluding the leading question mark)</li>
* <li>Response status code</li>
* <li>Number of bytes sent</li>
* <li>Number of bytes received</li>
* <li>Time to serve the request (in milliseconds)</li>
* <li>Host reference</li>
* <li>Client agent name</li>
* <li>Referrer reference</li>
* </ol>
* <br>
* If you use <a href="http://www.analog.cx">Analog</a> to generate your log
* reports, and if you use the default log format, then you can simply specify
* this string as a value of the LOGFORMAT command:
* (%Y-%m-%d\t%h:%n:%j\t%S\t%u\t%j\t%j\t%j\t%r\t%q\t%c\t%b\t%j\t%T\t%v\t%B\t%f)<br>
* <br>
* For custom access log format, see the syntax to use and the list of available
* variable names in {@link org.restlet.routing.Template}. <br>
*
* @see <a href="http://wiki.restlet.org/docs_2.1/201-restlet.html">User Guide -
*      Access logging</a>
* @see <a
*      href="http://download.oracle.com/javase/1.5.0/docs/api/java/util/logging/package-summary.html">java.util.logging</a>
* @author Jerome Louvel
*/
public class LogService extends Service {

    /** Indicates if the debugging mode is enabled. */
    private volatile boolean debugging;

    /** Indicates if the identity check (as specified by RFC1413) is enabled. */
    private volatile boolean identityCheck;

    /** The URI template of loggable resource references. */
    private volatile Template loggableTemplate;

    /** The access logger name. */
    private volatile String loggerName;

    /** The URI reference of the log properties. */
    private volatile Reference logPropertiesRef;

    /** The response log entry format. */
    private volatile String responseLogFormat;

    /** The response log template to use. */
    protected volatile Template responseLogTemplate;

    /**
     * Constructor.
     */
    public LogService() {
        this(true);
    }

    /**
     * Constructor.
     *
     * @param enabled
     *            True if the service has been enabled.
     */
    public LogService(boolean enabled) {
        super(enabled);
        this.loggableTemplate = null;
        this.loggerName = null;
        this.responseLogFormat = null;
        this.logPropertiesRef = null;
        this.identityCheck = false;
    }

    @Override
    public Filter createInboundFilter(Context context) {
        return new LogFilter(context, this);
    }

    /**
     * Format a log entry using the default IIS log format.
     *
     * @param response
     *            The response to log.
     * @param duration
     *            The call duration (in milliseconds).
     * @return The formatted log entry.
     */
    protected String getDefaultResponseLogMessage(Response response,
            int duration) {
        StringBuilder sb = new StringBuilder();
        Request request = response.getRequest();

        if (isDebugging()) {

        } else {
            long currentTime = System.currentTimeMillis();

            // Append the date of the request
            sb.append(String.format("%tF", currentTime));
            sb.append('\t');

            // Append the time of the request
            sb.append(String.format("%tT", currentTime));
            sb.append('\t');

            // Append the client IP address
            String clientAddress = request.getClientInfo().getUpstreamAddress();
            sb.append((clientAddress == null) ? "-" : clientAddress);
            sb.append('\t');

            // Append the user name (via IDENT protocol)
            if (isIdentityCheck()) {
                org.restlet.engine.log.IdentClient ic = new org.restlet.engine.log.IdentClient(
                        request.getClientInfo().getUpstreamAddress(), request
                                .getClientInfo().getPort(), response
                                .getServerInfo().getPort());
                sb.append((ic.getUserIdentifier() == null) ? "-" : ic
                        .getUserIdentifier());
            } else if ((request.getChallengeResponse() != null)
                    && (request.getChallengeResponse().getIdentifier() != null)) {
                sb.append(request.getChallengeResponse().getIdentifier());
            } else {
                sb.append('-');
            }

            sb.append('\t');

            // Append the server IP address
            String serverAddress = response.getServerInfo().getAddress();
            sb.append((serverAddress == null) ? "-" : serverAddress);
            sb.append('\t');

            // Append the server port
            Integer serverport = response.getServerInfo().getPort();
            sb.append((serverport == null) ? "-" : serverport.toString());
            sb.append('\t');

            // Append the method name
            String methodName = (request.getMethod() == null) ? "-" : request
                    .getMethod().getName();
            sb.append((methodName == null) ? "-" : methodName);

            // Append the resource path
            sb.append('\t');
            String resourcePath = (request.getResourceRef() == null) ? "-"
                    : request.getResourceRef().getPath();
            sb.append((resourcePath == null) ? "-" : resourcePath);

            // Append the resource query
            sb.append('\t');
            String resourceQuery = (request.getResourceRef() == null) ? "-"
                    : request.getResourceRef().getQuery();
            sb.append((resourceQuery == null) ? "-" : resourceQuery);

            // Append the status code
            sb.append('\t');
            sb.append((response.getStatus() == null) ? "-" : Integer
                    .toString(response.getStatus().getCode()));

            // Append the returned size
            sb.append('\t');

            if (!response.isEntityAvailable()
                    || Status.REDIRECTION_NOT_MODIFIED.equals(response
                            .getStatus())
                    || Status.SUCCESS_NO_CONTENT.equals(response.getStatus())
                    || Method.HEAD.equals(request.getMethod())) {
                sb.append('0');
            } else {
                sb.append((response.getEntity().getSize() == -1) ? "-" : Long
                        .toString(response.getEntity().getSize()));
            }

            // Append the received size
            sb.append('\t');

            if (request.getEntity() == null) {
                sb.append('0');
            } else {
                sb.append((request.getEntity().getSize() == -1) ? "-" : Long
                        .toString(request.getEntity().getSize()));
            }

            // Append the duration
            sb.append('\t');
            sb.append(duration);

            // Append the host reference
            sb.append('\t');
            sb.append((request.getHostRef() == null) ? "-" : request
                    .getHostRef().toString());

            // Append the agent name
            sb.append('\t');
            String agentName = request.getClientInfo().getAgent();
            sb.append((agentName == null) ? "-" : agentName);

            // Append the referrer
            sb.append('\t');
            sb.append((request.getReferrerRef() == null) ? "-" : request
                    .getReferrerRef().getIdentifier());
        }

        return sb.toString();
    }

    /**
     * Returns the format used.
     *
     * @return The format used, or null if the default one is used.
     * @see org.restlet.routing.Template for format syntax and variables.
     * @deprecated Use the {@link #getResponseLogFormat()} method instead.
     */
    @Deprecated
    public String getLogFormat() {
        return getResponseLogFormat();
    }

    /**
     * Returns the URI template of loggable resource references. Returns null by
     * default, meaning the all requests are loggable, independant of their
     * target resource URI reference.
     *
     * @return The URI template of loggable resource references.
     * @see Request#getResourceRef()
     */
    public Template getLoggableTemplate() {
        return loggableTemplate;
    }

    /**
     * Returns the name of the JDK's logger to use when logging access calls.
     * The default name will follow this pattern:
     * "org.restlet.MyComponent.LogService", where "MyComponent" will correspond
     * to the simple class name of your component subclass or to the base
     * "Component" class.
     *
     * @return The name of the JDK's logger to use when logging access calls.
     */
    public String getLoggerName() {
        return this.loggerName;
    }

    /**
     * Returns the URI reference of the log properties.
     *
     * @return The URI reference of the log properties.
     */
    public Reference getLogPropertiesRef() {
        return logPropertiesRef;
    }

    /**
     * Returns the format used when logging responses.
     *
     * @return The format used, or null if the default one is used.
     * @see org.restlet.routing.Template for format syntax and variables.
     */
    public String getResponseLogFormat() {
        return this.responseLogFormat;
    }

    /**
     * Format an access log entry. If the log template property isn't provided,
     * then a default IIS like format is used.
     *
     * @param response
     *            The response to log.
     * @param duration
     *            The call duration.
     * @return The formatted log entry.
     */
    public String getResponseLogMessage(Response response, int duration) {
        String result = null;

        // Format the call into a log entry
        if (this.responseLogTemplate != null) {
            result = this.responseLogTemplate.format(response.getRequest(),
                    response);
        } else {
            result = getDefaultResponseLogMessage(response, duration);
        }

        return result;
    }

    /**
     * Indicates if the debugging mode is enabled. False by default.
     *
     * @return True if the debugging mode is enabled.
     */
    protected boolean isDebugging() {
        return debugging;
    }

    /**
     * Indicates if the identity check (as specified by RFC1413) is enabled.
     * Default value is false.
     *
     * @return True if the identity check is enabled.
     */
    public boolean isIdentityCheck() {
        return this.identityCheck;
    }

    /**
     * Indicates if the call should be logged during the processing chain. By
     * default, it tries to match the request URI with the
     * {@link #getLoggableTemplate()} URI template otherwise is returns true.
     *
     * @param request
     *            The request to log.
     * @return True if the call should be logged during the processing chain.
     */
    public boolean isLoggable(Request request) {
        return (getLoggableTemplate() == null) ? true : getLoggableTemplate()
                .match(request.getResourceRef().getTargetRef().toString()) > 0;
    }

    /**
     * Indicates if the debugging mode is enabled.
     *
     * @param debugging
     *            True if the debugging mode is enabled.
     */
    protected void setDebugging(boolean debugging) {
        this.debugging = debugging;
    }

    /**
     * Indicates if the identity check (as specified by RFC1413) is enabled.
     *
     * @param identityCheck
     *            True if the identity check is enabled.
     */
    public void setIdentityCheck(boolean identityCheck) {
        this.identityCheck = identityCheck;
    }

    /**
     * Sets the format to use when logging responses. The default format matches
     * the one of IIS 6.
     *
     * @param responseLogFormat
     *            The format to use when logging responses.
     * @see org.restlet.routing.Template for format syntax and variables.
     * @deprecated Use {@link #setResponseLogFormat(String)} instead.
     */
    @Deprecated
    public void setLogFormat(String responseLogFormat) {
        setResponseLogFormat(responseLogFormat);
    }

    /**
     * Sets the URI template of loggable resource references.
     *
     * @param loggableTemplateRef
     *            The URI template of loggable resource references.
     * @see #setLoggableTemplate(Template)
     */
    public void setLoggableTemplate(String loggableTemplateRef) {
        if (loggableTemplateRef != null) {
            this.loggableTemplate = new Template(loggableTemplateRef);
        } else {
            this.loggableTemplate = null;
        }
    }

    /**
     * Sets the URI template of loggable resource references.
     *
     * @param loggableTemplate
     *            The URI template of loggable resource references.
     */
    public void setLoggableTemplate(Template loggableTemplate) {
        this.loggableTemplate = loggableTemplate;
    }

    /**
     * Sets the name of the JDK's logger to use when logging access calls.
     *
     * @param name
     *            The name of the JDK's logger to use when logging access calls.
     */
    public void setLoggerName(String name) {
        this.loggerName = name;
    }

    /**
     * Sets the URI reference of the log properties.
     *
     * @param logPropertiesRef
     *            The URI reference of the log properties.
     */
    public void setLogPropertiesRef(Reference logPropertiesRef) {
        this.logPropertiesRef = logPropertiesRef;
    }

    /**
     * Sets the URI reference of the log properties.
     *
     * @param logPropertiesUri
     *            The URI reference of the log properties.
     */
    public void setLogPropertiesRef(String logPropertiesUri) {
        setLogPropertiesRef(new Reference(logPropertiesUri));
    }

    /**
     * Sets the format to use when logging responses. The default format matches
     * the one of IIS 6.
     *
     * @param responseLogFormat
     *            The format to use when logging responses.
     * @see org.restlet.routing.Template for format syntax and variables.
     */
    public void setResponseLogFormat(String responseLogFormat) {
        this.responseLogFormat = responseLogFormat;
    }

    /**
     * Starts the log service by attempting to read the log properties if the
     * {@link #getLogPropertiesRef()} returns a non null URI reference.
     */
    @Override
    public synchronized void start() throws Exception {
        super.start();

        this.responseLogTemplate = (getLogFormat() == null) ? null
                : new Template(getLogFormat());

        if (getLogPropertiesRef() != null) {
            Representation logProperties = new ClientResource(getContext(),
                    getLogPropertiesRef()).get();

            if (logProperties != null) {
                LogManager.getLogManager().readConfiguration(
                        logProperties.getStream());
            }
        }
    }
}
TOP

Related Classes of org.restlet.service.LogService

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.