Java tutorial
/* * Copyright (c) 2014-2015 Globo.com - ATeam * All rights reserved. * * This source is subject to the Apache License, Version 2.0. * Please see the LICENSE file for more information. * * Authors: See AUTHORS file * * 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 io.galeb.undertow.handlers; import io.galeb.core.statsd.NullStatsdClient; import io.galeb.core.statsd.StatsdClient; import io.undertow.attribute.ResponseTimeAttribute; import io.undertow.server.ExchangeCompletionListener; import io.undertow.server.HttpServerExchange; import io.undertow.util.HttpString; import org.apache.http.HttpStatus; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.concurrent.TimeUnit; class HeaderMetricsListener implements ExchangeCompletionListener, ProcessorLocalStatusCode { private static final Logger LOGGER = LogManager.getLogger(); private final ResponseTimeAttribute responseTimeAttribute = new ResponseTimeAttribute(TimeUnit.MILLISECONDS); private StatsdClient statsdClient = new NullStatsdClient(); private int maxRequestTime = Integer.MAX_VALUE - 1; private boolean forceChangeStatus = false; @Override public void exchangeEvent(final HttpServerExchange exchange, final NextListener nextListener) { try { final String realDest = exchange.getAttachment(BackendSelector.REAL_DEST); String virtualhost = exchange.getHostName(); String backend = realDest != null ? realDest : "UNKNOWN@" + virtualhost; int statusCode = exchange.getStatusCode(); long responseBytesSent = exchange.getResponseBytesSent(); final HttpString method = exchange.getRequestMethod(); final Integer responseTime = getResponseTime(exchange); int fakeStatusCode = getFakeStatusCode(realDest, statusCode, responseBytesSent, responseTime, maxRequestTime); int statusCodeLogged = statusCode; if (fakeStatusCode != NOT_MODIFIED) { statusCodeLogged = fakeStatusCode - ProcessorLocalStatusCode.OFFSET_LOCAL_ERROR; if (statusCodeLogged != statusCode) { exchange.setStatusCode(statusCodeLogged); } statusCode = fakeStatusCode; } String httpStatus = String.valueOf(HttpStatus.SC_OK); if (forceChangeStatus || statusCodeLogged != HttpStatus.SC_BAD_GATEWAY) { httpStatus = String.valueOf(statusCode); } sendHttpStatusCount(virtualhost, backend, httpStatus); sendRequestTime(virtualhost, backend, responseTime); if (method != null) { sendHttpMethodCount(virtualhost, backend, method.toString()); } } catch (Exception e) { LOGGER.error(e); } finally { nextListener.proceed(); } } public int getResponseTime(HttpServerExchange exchange) { return Math.round(Float.parseFloat(responseTimeAttribute.readAttribute(exchange))); } public HeaderMetricsListener setMaxRequestTime(int maxRequestTime) { this.maxRequestTime = maxRequestTime; return this; } public HeaderMetricsListener forceChangeStatus(boolean forceChangeStatus) { this.forceChangeStatus = forceChangeStatus; return this; } public HeaderMetricsListener setStatsd(StatsdClient statsdClient) { this.statsdClient = statsdClient; return this; } private void sendHttpMethodCount(String virtualhostId, String backendId, String method) { final String virtualhost = StatsdClient.cleanUpKey(virtualhostId); final String backend = StatsdClient.cleanUpKey(backendId); final String key = virtualhost + StatsdClient.STATSD_SEP + backend + StatsdClient.STATSD_SEP + StatsdClient.PROP_METHOD_PREFIX + StatsdClient.STATSD_SEP + method; statsdClient.incr(key); } private void sendHttpStatusCount(String virtualhostId, String backendId, String httpStatus) { final String virtualhost = StatsdClient.cleanUpKey(virtualhostId); final String backend = StatsdClient.cleanUpKey(backendId); final String key = virtualhost + StatsdClient.STATSD_SEP + backend + StatsdClient.STATSD_SEP + StatsdClient.PROP_HTTPCODE_PREFIX + httpStatus; statsdClient.incr(key); } private void sendRequestTime(String virtualhostId, String backendId, long requestTime) { final String virtualhost = StatsdClient.cleanUpKey(virtualhostId); final String backend = StatsdClient.cleanUpKey(backendId); final String key = virtualhost + StatsdClient.STATSD_SEP + backend + StatsdClient.STATSD_SEP + StatsdClient.PROP_REQUESTTIME; statsdClient.timing(key, requestTime); } }