org.glassfish.web.admin.monitor.HttpServiceStatsProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project for IBM JDK
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2017 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2016] [Payara Foundation]
package org.glassfish.web.admin.monitor;
import org.glassfish.internal.api.Globals;
import com.sun.enterprise.v3.services.impl.GrizzlyService;
import com.sun.enterprise.v3.services.impl.monitor.GrizzlyMonitoring;
import com.sun.enterprise.v3.services.impl.monitor.stats.ConnectionQueueStatsProvider;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.enterprise.util.StringUtils;
import org.glassfish.external.statistics.CountStatistic;
import org.glassfish.external.statistics.StringStatistic;
import org.glassfish.external.statistics.annotations.Reset;
import org.glassfish.external.statistics.impl.CountStatisticImpl;
import org.glassfish.external.statistics.impl.StatisticImpl;
import org.glassfish.external.statistics.impl.StringStatisticImpl;
import org.glassfish.external.statistics.impl.TimeStatisticImpl;
import org.glassfish.external.probe.provider.annotations.*;
import org.glassfish.gmbal.Description;
import org.glassfish.gmbal.AMXMetadata;
import org.glassfish.gmbal.ManagedAttribute;
import org.glassfish.gmbal.ManagedObject;
import org.glassfish.grizzly.config.dom.NetworkConfig;
import org.glassfish.grizzly.config.dom.NetworkListener;
import org.glassfish.hk2.api.PostConstruct;
import org.glassfish.web.admin.LogFacade;
/**
* Provides the monitoring data at the Web container level
*
* @author Prashanth Abbagani
* @author Amy Roh
*/
@AMXMetadata(type="request-mon", group="monitoring")
@ManagedObject
@Description( "Web Container HTTP Service Statistics" )
public class HttpServiceStatsProvider implements PostConstruct {
private NetworkConfig networkConfig;
private static final Logger logger = LogFacade.getLogger();
private static final String ERROR_COUNT_DESCRIPTION =
"Cumulative value of the error count, with error count representing the number of cases where the response code was greater than or equal to 400";
private static final String MAX_TIME_DESCRIPTION =
"Longest response time for a request; not a cumulative value, but the largest response time from among the response times";
private static final String PROCESSING_TIME_DESCRIPTION =
"Average request processing time";
private static final String COUNT_BYTES_RECEIVED_DESCRIPTION =
"The number of bytes received";
private static final String COUNT_BYTES_TRANSMITTED_DESCRIPTION =
"The number of bytes transmitted";
private static final String COUNT_OPEN_CONNECTIONS_DESCRIPTION =
"The number of open connections";
private static final String COUNT_REQUESTS_DESCRIPTION =
"The number of requests received";
private static final String MAX_OPEN_CONNECTIONS_DESCRIPTION =
"The maximum number of open connections";
private static final String METHOD_DESCRIPTION =
"The method of the last request serviced";
private static final String URI_DESCRIPTION =
"The URI of the last request serviced";
private static final String COUNT_200_DESCRIPTION =
"Number of responses with a status code equal to 200";
private static final String COUNT_2xx_DESCRIPTION =
"Number of responses with a status code in the 2xx range";
private static final String COUNT_302_DESCRIPTION =
"Number of responses with a status code equal to 302";
private static final String COUNT_304_DESCRIPTION =
"Number of responses with a status code equal to 304";
private static final String COUNT_3xx_DESCRIPTION =
"Number of responses with a status code in the 3xx range";
private static final String COUNT_400_DESCRIPTION =
"Number of responses with a status code equal to 400";
private static final String COUNT_401_DESCRIPTION =
"Number of responses with a status code equal to 401";
private static final String COUNT_403_DESCRIPTION =
"Number of responses with a status code equal to 403";
private static final String COUNT_404_DESCRIPTION =
"Number of responses with a status code equal to 404";
private static final String COUNT_4xx_DESCRIPTION =
"Number of responses with a status code in the 4xx range";
private static final String COUNT_503_DESCRIPTION =
"Number of responses with a status code equal to 503";
private static final String COUNT_5xx_DESCRIPTION =
"Number of responses with a status code in the 5xx range";
private static final String COUNT_OTHER_DESCRIPTION =
"Number of responses with a status code outside the 2xx, 3xx, 4xx, and 5xx range";
private CountStatisticImpl errorCount = new CountStatisticImpl("ErrorCount",
StatisticImpl.UNIT_COUNT, ERROR_COUNT_DESCRIPTION);
private CountStatisticImpl maxTime = new CountStatisticImpl("MaxTime",
StatisticImpl.UNIT_MILLISECOND, MAX_TIME_DESCRIPTION);
private CountStatisticImpl processingTime = new CountStatisticImpl("ProcessingTime",
StatisticImpl.UNIT_MILLISECOND, PROCESSING_TIME_DESCRIPTION);
private CountStatisticImpl countBytesReceived = new CountStatisticImpl("CountBytesReceived",
StatisticImpl.UNIT_COUNT, COUNT_BYTES_RECEIVED_DESCRIPTION);
private CountStatisticImpl countBytesTransmitted = new CountStatisticImpl("CountBytesTransmitted",
StatisticImpl.UNIT_COUNT, COUNT_BYTES_TRANSMITTED_DESCRIPTION);
private CountStatisticImpl countOpenConnections = new CountStatisticImpl("CountOpenConnections",
StatisticImpl.UNIT_COUNT, COUNT_OPEN_CONNECTIONS_DESCRIPTION);
private CountStatisticImpl countRequests = new CountStatisticImpl("CountRequests",
StatisticImpl.UNIT_COUNT, COUNT_REQUESTS_DESCRIPTION);
private CountStatisticImpl maxOpenConnections = new CountStatisticImpl("MaxOpenConnections",
StatisticImpl.UNIT_COUNT, MAX_OPEN_CONNECTIONS_DESCRIPTION);
private StringStatisticImpl method = new StringStatisticImpl("Method",
"String", METHOD_DESCRIPTION);
private StringStatisticImpl uri = new StringStatisticImpl("Uri",
"String", URI_DESCRIPTION);
private CountStatisticImpl count200 = new CountStatisticImpl("Count200",
StatisticImpl.UNIT_COUNT, COUNT_200_DESCRIPTION);
private CountStatisticImpl count2xx = new CountStatisticImpl("Count2xx",
StatisticImpl.UNIT_COUNT, COUNT_2xx_DESCRIPTION);
private CountStatisticImpl count302 = new CountStatisticImpl("Count302",
StatisticImpl.UNIT_COUNT, COUNT_302_DESCRIPTION);
private CountStatisticImpl count304 = new CountStatisticImpl("Count304",
StatisticImpl.UNIT_COUNT, COUNT_304_DESCRIPTION);
private CountStatisticImpl count3xx = new CountStatisticImpl("Count3xx",
StatisticImpl.UNIT_COUNT, COUNT_3xx_DESCRIPTION);
private CountStatisticImpl count400 = new CountStatisticImpl("Count400",
StatisticImpl.UNIT_COUNT, COUNT_400_DESCRIPTION);
private CountStatisticImpl count401 = new CountStatisticImpl("Count401",
StatisticImpl.UNIT_COUNT, COUNT_401_DESCRIPTION);
private CountStatisticImpl count403 = new CountStatisticImpl("Count403",
StatisticImpl.UNIT_COUNT, COUNT_403_DESCRIPTION);
private CountStatisticImpl count404 = new CountStatisticImpl("Count404",
StatisticImpl.UNIT_COUNT, COUNT_404_DESCRIPTION);
private CountStatisticImpl count4xx = new CountStatisticImpl("Count4xx",
StatisticImpl.UNIT_COUNT, COUNT_4xx_DESCRIPTION);
private CountStatisticImpl count503 = new CountStatisticImpl("Count503",
StatisticImpl.UNIT_COUNT, COUNT_503_DESCRIPTION);
private CountStatisticImpl count5xx = new CountStatisticImpl("Count5xx",
StatisticImpl.UNIT_COUNT, COUNT_5xx_DESCRIPTION);
private CountStatisticImpl countOther = new CountStatisticImpl("CountOther",
StatisticImpl.UNIT_COUNT, COUNT_OTHER_DESCRIPTION);
private TimeStatisticImpl requestProcessTime = new TimeStatisticImpl(0L, 0L, 0L, 0L,
"", "", "", System.currentTimeMillis(), -1L);
private String virtualServerName = null;
private String [] networkListeners = null;
private ThreadLocal individualData = new ThreadLocal (){
TimeStatData tsd;
protected TimeStatData initialValue (){
tsd = new TimeStatData ();
return tsd;
}
public TimeStatData get (){
if (tsd == null)
tsd = new TimeStatData();
return tsd;
}
};
public HttpServiceStatsProvider(String vsName, String listeners, NetworkConfig networkConfig) {
this.virtualServerName = vsName;
List listenerList = StringUtils.parseStringList(listeners, ",");
this.networkListeners = listenerList == null ? new String[0] :listenerList.toArray(new String[listenerList.size()]);
this.networkConfig = networkConfig;
}
public void postConstruct() {
}
private long getInitialOpenConnections(){
long initialCount = 0;
GrizzlyMonitoring monitoring = Globals.get(GrizzlyService.class).getMonitoring();
if (monitoring != null) {
for (String networkListener : networkListeners) {
ConnectionQueueStatsProvider connectionQueueStats = monitoring.getConnectionQueueStatsProvider(networkListener);
initialCount += connectionQueueStats.getOpenConnectionsCount().getCount();
}
} else {
logger.log(Level.FINER, "Tried to get monitoring service connections before service started");
}
return initialCount;
}
@ManagedAttribute(id="maxtime")
@Description(MAX_TIME_DESCRIPTION)
public CountStatistic getMaxTime() {
maxTime.setCount(requestProcessTime.getMaxTime());
return maxTime;
}
@ManagedAttribute(id="processingtime")
@Description(PROCESSING_TIME_DESCRIPTION)
public CountStatistic getTime() {
processingTime.setCount(this.getProcessTime());
return processingTime;
}
@ManagedAttribute(id="countbytesreceived")
@Description(COUNT_BYTES_RECEIVED_DESCRIPTION)
public CountStatistic getCountBytesReceived() {
return countBytesReceived;
}
@ManagedAttribute(id="countbytestransmitted")
@Description(COUNT_BYTES_TRANSMITTED_DESCRIPTION)
public CountStatistic getCountBytesTransmitted() {
return countBytesTransmitted;
}
@ManagedAttribute(id="countopenconnections")
@Description(COUNT_OPEN_CONNECTIONS_DESCRIPTION)
public CountStatistic getCountOpenConnections() {
return countOpenConnections;
}
@ManagedAttribute(id="countrequests")
@Description(COUNT_REQUESTS_DESCRIPTION)
public CountStatistic getCountRequests() {
return countRequests;
}
@ManagedAttribute(id="maxopenconnections")
@Description(MAX_OPEN_CONNECTIONS_DESCRIPTION)
public CountStatistic getMaxOpenConnections() {
return maxOpenConnections;
}
@ManagedAttribute(id="method")
@Description(METHOD_DESCRIPTION)
public StringStatistic getMethod() {
return method;
}
@ManagedAttribute(id="uri")
@Description(URI_DESCRIPTION)
public StringStatistic getUri() {
return uri;
}
@ManagedAttribute(id="errorcount")
@Description(ERROR_COUNT_DESCRIPTION)
public CountStatistic getErrorCount() {
return errorCount;
}
@ManagedAttribute(id="count200")
@Description(COUNT_200_DESCRIPTION)
public CountStatistic getCount200() {
return count200;
}
@ManagedAttribute(id="count2xx")
@Description(COUNT_2xx_DESCRIPTION)
public CountStatistic getCount2xx() {
return count2xx;
}
@ManagedAttribute(id="count302")
@Description(COUNT_302_DESCRIPTION)
public CountStatistic getCount302() {
return count302;
}
@ManagedAttribute(id="count304")
@Description(COUNT_304_DESCRIPTION)
public CountStatistic getCount304() {
return count304;
}
@ManagedAttribute(id="count3xx")
@Description(COUNT_3xx_DESCRIPTION)
public CountStatistic getCount3xxt() {
return count3xx;
}
@ManagedAttribute(id="count400")
@Description(COUNT_400_DESCRIPTION)
public CountStatistic getCount400() {
return count400;
}
@ManagedAttribute(id="count401")
@Description(COUNT_401_DESCRIPTION)
public CountStatistic getCount401() {
return count401;
}
@ManagedAttribute(id="count403")
@Description(COUNT_403_DESCRIPTION)
public CountStatistic getCount403() {
return count403;
}
@ManagedAttribute(id="count404")
@Description(COUNT_404_DESCRIPTION)
public CountStatistic getCount404() {
return count404;
}
@ManagedAttribute(id="count4xx")
@Description(COUNT_4xx_DESCRIPTION)
public CountStatistic getCount4xx() {
return count4xx;
}
@ManagedAttribute(id="count503")
@Description(COUNT_503_DESCRIPTION)
public CountStatistic getCount503() {
return count503;
}
@ManagedAttribute(id="count5xx")
@Description(COUNT_5xx_DESCRIPTION)
public CountStatistic getCount5xx() {
return this.count5xx;
}
@ManagedAttribute(id="countother")
@Description(COUNT_OTHER_DESCRIPTION)
public CountStatistic getCountOther() {
return this.countOther;
}
@ProbeListener("glassfish:web:http-service:dataReceivedEvent")
public void dataReceivedEvent(
@ProbeParam("size") int size,
@ProbeParam("hostName") String hostName) {
if ((hostName != null) && (hostName.equals(virtualServerName))) {
countBytesReceived.increment(size);
}
}
@ProbeListener("glassfish:web:http-service:dataSentEvent")
public void dataSentEvent(
@ProbeParam("size") long size,
@ProbeParam("hostName") String hostName) {
if ((hostName != null) && (hostName.equals(virtualServerName))) {
countBytesTransmitted.increment(size);
}
}
@ProbeListener("glassfish:web:http-service:requestStartEvent")
public void requestStartEvent(
@ProbeParam("appName") String appName,
@ProbeParam("hostName") String hostName,
@ProbeParam("serverName") String serverName,
@ProbeParam("serverPort") int serverPort,
@ProbeParam("contextPath") String contextPath,
@ProbeParam("servletPath") String servletPath) {
if ((hostName != null) && (hostName.equals(virtualServerName))) {
individualData.get().setEntryTime(System.currentTimeMillis());
countRequests.increment();
if (logger.isLoggable(Level.FINEST)) {
logger.finest(
"[TM]requestStartEvent received - virtual-server = " +
hostName + " : port = " + serverPort);
}
}
}
@ProbeListener("glassfish:web:http-service:requestEndEvent")
public void requestEndEvent(
@ProbeParam("appName") String appName,
@ProbeParam("hostName") String hostName,
@ProbeParam("serverName") String serverName,
@ProbeParam("serverPort") int serverPort,
@ProbeParam("contextPath") String contextPath,
@ProbeParam("servletPath") String servletPath,
@ProbeParam("statusCode") int statusCode,
@ProbeParam("method") String method,
@ProbeParam("uri") String uri) {
if ((hostName != null) && (hostName.equals(virtualServerName))) {
TimeStatData tsd = individualData.get();
tsd.setExitTime(System.currentTimeMillis());
requestProcessTime.incrementCount(tsd.getTotalTime());
incrementStatsCounter(statusCode);
if (logger.isLoggable(Level.FINEST)) {
logger.finest(
"[TM]requestEndEvent received - virtual-server = " +
hostName + ": application = " +
contextPath + " : servlet = " +
servletPath + " :Response code = " +
statusCode + " :Response time = " +
tsd.getTotalTime());
}
}
this.method.setCurrent(method);
this.uri.setCurrent(uri);
}
// ---------------- Connection related listeners -----------
@ProbeListener("glassfish:kernel:connection-queue:connectionAcceptedEvent")
public void connectionAcceptedEvent(
@ProbeParam("listenerName") String listenerName,
@ProbeParam("connection") int connectionId,
@ProbeParam("address") String address) {
for (String listener : networkListeners) {
if (listener.equals(listenerName)) {
countOpenConnections.increment();
}
NetworkListener networkListener = networkConfig.getNetworkListener(listenerName);
if (networkListener != null) {
maxOpenConnections.setCount(
Integer.parseInt(networkListener.findProtocol().getHttp().getMaxConnections()));
}
}
if (logger.isLoggable(Level.FINEST)) {
logger.finest(
"[TM]connectionAcceptedEvent received - virtual-server = " + listenerName);
}
}
@ProbeListener("glassfish:kernel:connection-queue:connectionClosedEvent")
public void connectionClosedEvent(
@ProbeParam("listenerName") String listenerName,
@ProbeParam("connection") int connectionId) {
for (String listener : networkListeners) {
if (listener.equals(listenerName)) {
countOpenConnections.decrement();
}
}
if (logger.isLoggable(Level.FINEST)) {
logger.finest(
"[TM]connectionClosedEvent received - virtual-server = " + listenerName);
}
}
public long getProcessTime() {
long count = requestProcessTime.getCount();
long processTime = 0L;
if (count != 0) {
processTime = requestProcessTime.getTotalTime()/count;
}
return processTime;
}
private void incrementStatsCounter(int statusCode) {
switch (statusCode) {
case 200:
count200.increment();
break;
case 302:
count302.increment();
break;
case 304:
count304.increment();
break;
case 400:
count400.increment();
break;
case 401:
count401.increment();
break;
case 403:
count403.increment();
break;
case 404:
count404.increment();
break;
case 503:
count503.increment();
break;
default:
break;
}
if (200 <= statusCode && statusCode <=299) {
count2xx.increment();
} else if (300 <= statusCode && statusCode <=399) {
count3xx.increment();
} else if (400 <= statusCode && statusCode <=499) {
count4xx.increment();
} else if (500 <= statusCode && statusCode <=599) {
count5xx.increment();
} else {
countOther.increment();
}
if (statusCode >= 400)
errorCount.increment();
}
//Need to add this because requestProcessTime needs to be reset.
//Since it is not exposed as public statistic the reset() would not get
//called on its TimeStatisticImpl object so we need to use @Reset instead.
//If @Reset is used then reset() won't be called on the statistic impl objects
//so all the stats need to reset here as well.
@Reset
public void reset() {
this.requestProcessTime.reset();
this.count200.reset();
this.count2xx.reset();
this.count302.reset();
this.count304.reset();
this.count3xx.reset();
this.count400.reset();
this.count401.reset();
this.count403.reset();
this.count404.reset();
this.count4xx.reset();
this.count503.reset();
this.count5xx.reset();
this.countOther.reset();
this.errorCount.reset();
this.maxTime.reset();
this.processingTime.reset();
this.countBytesReceived.reset();
this.countBytesTransmitted.reset();
this.countOpenConnections.reset();
this.countRequests.reset();
this.maxOpenConnections.reset();
this.method.reset();
this.uri.reset();
//set initial value
countOpenConnections.increment(getInitialOpenConnections());
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy