Package com.sonian.elasticsearch.http.filter.logging

Source Code of com.sonian.elasticsearch.http.filter.logging.LoggingFilterHttpServerAdapter

/*
* Copyright 2011 Sonian Inc.
*
* 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 com.sonian.elasticsearch.http.filter.logging;

import com.sonian.elasticsearch.http.filter.FilterChain;
import com.sonian.elasticsearch.http.filter.FilterHttpServerAdapter;
import com.sonian.elasticsearch.http.jetty.JettyHttpServerRestRequest;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.common.Classes;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.assistedinject.Assisted;
import org.elasticsearch.common.joda.time.DateTime;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.http.HttpChannel;
import org.elasticsearch.http.HttpRequest;
import org.elasticsearch.rest.RestResponse;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;

/**
* @author imotov
*/
public class LoggingFilterHttpServerAdapter implements FilterHttpServerAdapter {
    protected volatile ESLogger logger;

    private final RequestLoggingLevelSettings requestLoggingLevelSettings;

    private final String logFormat;

    private final String clusterName;

    @Inject
    public LoggingFilterHttpServerAdapter(Settings settings, @Assisted String name, @Assisted Settings filterSettings,
                                          RequestLoggingLevelSettings requestLoggingLevelSettings, ClusterName clusterName) {
        String loggerName = filterSettings.get("logger", Classes.getPackageName(getClass()));
        this.logFormat = filterSettings.get("format", "text");
        if (logFormat.equals("json")) {
            this.logger = Loggers.getLogger(loggerName);
        } else {
            this.logger = Loggers.getLogger(loggerName, settings);
        }

        this.clusterName = clusterName.value();

        this.requestLoggingLevelSettings = requestLoggingLevelSettings;
        requestLoggingLevelSettings.updateSettings(filterSettings);
    }

    public RequestLoggingLevelSettings requestLoggingLevelSettings() {
        return requestLoggingLevelSettings;
    }

    @Override
    public void doFilter(HttpRequest request, HttpChannel channel, FilterChain filterChain) {
        RequestLoggingLevel level = requestLoggingLevelSettings.getLoggingLevel(request.method(), request.path());
        if (level.shouldLog(logger)) {
            filterChain.doFilter(request, new LoggingHttpChannel(request, channel, this.logFormat, level.logBody()));
        } else {
            filterChain.doFilter(request, channel);
        }
    }

    private StringBuilder mapToString(Map<String, String> params) {
        StringBuilder buf = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> param : params.entrySet()) {
            if (first) {
                first = false;
            } else {
                buf.append("&");
            }

            buf.append(param.getKey());
            buf.append("=");
            try {
                buf.append(URLEncoder.encode(param.getValue(), "UTF-8"));
            } catch (UnsupportedEncodingException ex) {
                logger.error("UnsupportedEncodingException", ex);
            }
        }
        if (first) {
            buf.append("-");
        }
        return buf;
    }

    private class LoggingHttpChannel extends HttpChannel {
        private final HttpRequest request;
       
        private final HttpChannel channel;

        private final String method;

        private final String path;

        private final StringBuilder params;

        private final long timestamp;

        private final String format;

        private final String content;

        private final String localaddr;

        private final long localport;

        private final String remoteaddr;

        private final long remoteport;

        private final String scheme;

        private final String remoteuser;

        private final String opaqueId;

        public LoggingHttpChannel(HttpRequest request, HttpChannel channel, String format, boolean logBody) {
            super(request);
            this.channel = channel;
            this.request = request;

            this.format = format;
            method = request.method().name();
            path = request.rawPath();
            params = mapToString(request.params());
            timestamp = System.currentTimeMillis();
            if(logBody) {
                content = request.content().toUtf8();
            } else {
                content = null;
            }

            JettyHttpServerRestRequest req = (JettyHttpServerRestRequest) request;
            localaddr = req.localAddr();
            localport = req.localPort();
            remoteaddr = req.remoteAddr();
            remoteport = req.remotePort();
            scheme = req.scheme();
            remoteuser = req.remoteUser();
            opaqueId = req.opaqueId();
        }

        public void logText(RestResponse response, long contentLength, long now) {
            long latency = now - timestamp;
            if(content != null) {
                logger.info("{} {} {} {} {} {} {} [{}]",
                        method,
                        path,
                        params,
                        response.status().getStatus(),
                        response.status(),
                        contentLength >= 0 ? contentLength : "-",
                        latency,
                        content);
            } else {
                logger.info("{} {} {} {} {} {} {}",
                        method,
                        path,
                        params,
                        response.status().getStatus(),
                        response.status(),
                        contentLength >= 0 ? contentLength : "-",
                        latency);
            }
        }

        public void logJson(RestResponse response, long contentLength, long now) {
            long latency = now - timestamp;
            DateTime nowdt = new DateTime(now);
            DateTime startdt = new DateTime(timestamp);
            try {
                XContentBuilder json = XContentFactory.jsonBuilder().startObject();
                json.field("time", nowdt.toDateTimeISO().toString());
                json.field("starttime", startdt.toDateTimeISO().toString());
                json.field("localaddr", localaddr);
                json.field("localport", localport);
                json.field("remoteaddr", remoteaddr);
                json.field("remoteport", remoteport);
                json.field("scheme", scheme);
                json.field("method", method);
                json.field("path", path);
                json.field("querystr", params);
                json.field("code", response.status().getStatus());
                json.field("status", response.status());
                json.field("size", contentLength);
                json.field("duration", latency);
                json.field("year", nowdt.toString("yyyy"));
                json.field("month", nowdt.toString("MM"));
                json.field("day", nowdt.toString("dd"));
                json.field("hour", nowdt.toString("HH"));
                json.field("minute", nowdt.toString("mm"));
                json.field("dow", nowdt.toString("EEE"));
                json.field("cluster", clusterName);
                if (remoteuser != null) {
                    json.field("user", remoteuser);
                }
                if (opaqueId != null) {
                    json.field("opaque-id", opaqueId);
                }
                if (content != null) {
                    json.field("data", content);
                }
                json.endObject();
                logger.info(json.string());
            } catch (IOException e) {
                logger.info("## Could not serialize to json: {} {} {} {} {} {} {} {} [{}]",
                        nowdt.toDateTimeISO().toString(),
                        method,
                        path,
                        params,
                        response.status().getStatus(),
                        response.status(),
                        contentLength >= 0 ? contentLength : "-",
                        latency,
                        content);
            }
        }

        @Override
        public void sendResponse(RestResponse response) {
            int contentLength = -1;
            try {
                contentLength = response.content().length();
            } catch (RuntimeException ex) {
                // Ignore
            }
            channel.sendResponse(response);
            long now = System.currentTimeMillis();

            if (this.format.equals("json")) {
                logJson(response, contentLength, now);
            } else {
                logText(response, contentLength, now);
            }
        }
    }
}
TOP

Related Classes of com.sonian.elasticsearch.http.filter.logging.LoggingFilterHttpServerAdapter

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.