1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.coyote;
19
20 import javax.management.ObjectName;
21
22
23 /**
24 * Structure holding the Request and Response objects. It also holds statistical
25 * informations about request processing and provide management informations
26 * about the requests beeing processed.
27 *
28 * Each thread uses a Request/Response pair that is recycled on each request.
29 * This object provides a place to collect global low-level statistics - without
30 * having to deal with synchronization ( since each thread will have it's own
31 * RequestProcessorMX ).
32 *
33 * TODO: Request notifications will be registered here.
34 *
35 * @author Costin Manolache
36 */
37 public class RequestInfo {
38 RequestGroupInfo global=null;
39
40 // ----------------------------------------------------------- Constructors
41
42 public RequestInfo( Request req) {
43 this.req=req;
44 }
45
46 public RequestGroupInfo getGlobalProcessor() {
47 return global;
48 }
49
50 public void setGlobalProcessor(RequestGroupInfo global) {
51 if( global != null) {
52 this.global=global;
53 global.addRequestProcessor( this );
54 } else {
55 if (this.global != null) {
56 this.global.removeRequestProcessor( this );
57 this.global = null;
58 }
59 }
60 }
61
62
63 // ----------------------------------------------------- Instance Variables
64 Request req;
65 Response res;
66 int stage = Constants.STAGE_NEW;
67 String workerThreadName;
68 ObjectName rpName;
69
70 // -------------------- Information about the current request -----------
71 // This is usefull for long-running requests only
72
73 public String getMethod() {
74 return req.method().toString();
75 }
76
77 public String getCurrentUri() {
78 return req.requestURI().toString();
79 }
80
81 public String getCurrentQueryString() {
82 return req.queryString().toString();
83 }
84
85 public String getProtocol() {
86 return req.protocol().toString();
87 }
88
89 public String getVirtualHost() {
90 return req.serverName().toString();
91 }
92
93 public int getServerPort() {
94 return req.getServerPort();
95 }
96
97 public String getRemoteAddr() {
98 req.action(ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE, null);
99 return req.remoteAddr().toString();
100 }
101
102 public int getContentLength() {
103 return req.getContentLength();
104 }
105
106 public long getRequestBytesReceived() {
107 return req.getBytesRead();
108 }
109
110 public long getRequestBytesSent() {
111 return req.getResponse().getBytesWritten();
112 }
113
114 public long getRequestProcessingTime() {
115 if ( getStage() == org.apache.coyote.Constants.STAGE_ENDED ) return 0;
116 else return (System.currentTimeMillis() - req.getStartTime());
117 }
118
119 // -------------------- Statistical data --------------------
120 // Collected at the end of each request.
121 private long bytesSent;
122 private long bytesReceived;
123
124 // Total time = divide by requestCount to get average.
125 private long processingTime;
126 // The longest response time for a request
127 private long maxTime;
128 // URI of the request that took maxTime
129 private String maxRequestUri;
130
131 private int requestCount;
132 // number of response codes >= 400
133 private int errorCount;
134
135 //the time of the last request
136 private long lastRequestProcessingTime = 0;
137
138
139 /** Called by the processor before recycling the request. It'll collect
140 * statistic information.
141 */
142 void updateCounters() {
143 bytesReceived+=req.getBytesRead();
144 bytesSent+=req.getResponse().getBytesWritten();
145
146 requestCount++;
147 if( req.getResponse().getStatus() >=400 )
148 errorCount++;
149 long t0=req.getStartTime();
150 long t1=System.currentTimeMillis();
151 long time=t1-t0;
152 this.lastRequestProcessingTime = time;
153 processingTime+=time;
154 if( maxTime < time ) {
155 maxTime=time;
156 maxRequestUri=req.requestURI().toString();
157 }
158 }
159
160 public int getStage() {
161 return stage;
162 }
163
164 public void setStage(int stage) {
165 this.stage = stage;
166 }
167
168 public long getBytesSent() {
169 return bytesSent;
170 }
171
172 public void setBytesSent(long bytesSent) {
173 this.bytesSent = bytesSent;
174 }
175
176 public long getBytesReceived() {
177 return bytesReceived;
178 }
179
180 public void setBytesReceived(long bytesReceived) {
181 this.bytesReceived = bytesReceived;
182 }
183
184 public long getProcessingTime() {
185 return processingTime;
186 }
187
188 public void setProcessingTime(long processingTime) {
189 this.processingTime = processingTime;
190 }
191
192 public long getMaxTime() {
193 return maxTime;
194 }
195
196 public void setMaxTime(long maxTime) {
197 this.maxTime = maxTime;
198 }
199
200 public String getMaxRequestUri() {
201 return maxRequestUri;
202 }
203
204 public void setMaxRequestUri(String maxRequestUri) {
205 this.maxRequestUri = maxRequestUri;
206 }
207
208 public int getRequestCount() {
209 return requestCount;
210 }
211
212 public void setRequestCount(int requestCount) {
213 this.requestCount = requestCount;
214 }
215
216 public int getErrorCount() {
217 return errorCount;
218 }
219
220 public void setErrorCount(int errorCount) {
221 this.errorCount = errorCount;
222 }
223
224 public String getWorkerThreadName() {
225 return workerThreadName;
226 }
227
228 public ObjectName getRpName() {
229 return rpName;
230 }
231
232 public long getLastRequestProcessingTime() {
233 return lastRequestProcessingTime;
234 }
235
236 public void setWorkerThreadName(String workerThreadName) {
237 this.workerThreadName = workerThreadName;
238 }
239
240 public void setRpName(ObjectName rpName) {
241 this.rpName = rpName;
242 }
243
244 public void setLastRequestProcessingTime(long lastRequestProcessingTime) {
245 this.lastRequestProcessingTime = lastRequestProcessingTime;
246 }
247 }