001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.protocol.http; 018 019import org.apache.wicket.request.ILogData; 020import org.apache.wicket.request.ILoggableRequestHandler; 021import org.apache.wicket.request.IRequestHandler; 022import org.apache.wicket.request.handler.logger.NoLogData; 023import org.apache.wicket.session.ISessionStore; 024import org.apache.wicket.util.io.IClusterable; 025import org.apache.wicket.util.string.Strings; 026 027import java.util.ArrayList; 028import java.util.Date; 029import java.util.HashMap; 030import java.util.List; 031import java.util.Map; 032 033/** 034 * Interface for the request logger and viewer. 035 * 036 * @see org.apache.wicket.Application#newRequestLogger() 037 * 038 * @author jcompagner 039 */ 040public interface IRequestLogger 041{ 042 /** 043 * @return The total created sessions counter 044 */ 045 int getTotalCreatedSessions(); 046 047 /** 048 * @return The peak sessions counter 049 */ 050 int getPeakSessions(); 051 052 /** 053 * This method returns a List of the current requests that are in mem. This is a readonly list. 054 * 055 * @return Collection of the current requests 056 */ 057 List<RequestData> getRequests(); 058 059 /** 060 * @return Collection of live Sessions Data 061 */ 062 SessionData[] getLiveSessions(); 063 064 /** 065 * @return The current active requests 066 */ 067 int getCurrentActiveRequestCount(); 068 069 /** 070 * @return The {@link org.apache.wicket.protocol.http.IRequestLogger.RequestData} for the current request. 071 */ 072 RequestData getCurrentRequest(); 073 074 /** 075 * @return The peak active requests 076 */ 077 int getPeakActiveRequestCount(); 078 079 /** 080 * @return The number of requests per minute. 081 */ 082 long getRequestsPerMinute(); 083 084 /** 085 * @return The average request time. 086 */ 087 long getAverageRequestTime(); 088 089 /** 090 * called when the session is created and has an id. (for http it means that the http session is 091 * created) 092 * 093 * @param id 094 * the session id 095 */ 096 void sessionCreated(String id); 097 098 /** 099 * Method used to cleanup a livesession when the session was invalidated by the webcontainer 100 * 101 * @param sessionId 102 * the session id 103 */ 104 void sessionDestroyed(String sessionId); 105 106 /** 107 * This method is called when the request is over. This will set the total time a request takes 108 * and cleans up the current request data. 109 * 110 * @param timeTaken 111 * the time taken in milliseconds 112 */ 113 void requestTime(long timeTaken); 114 115 /** 116 * Called to monitor removals of objects out of the {@link ISessionStore} 117 * 118 * @param value 119 * the object being removed 120 */ 121 void objectRemoved(Object value); 122 123 /** 124 * Called to monitor updates of objects in the {@link ISessionStore} 125 * 126 * @param value 127 * the object being updated 128 */ 129 void objectUpdated(Object value); 130 131 /** 132 * Called to monitor additions of objects in the {@link ISessionStore} 133 * 134 * @param value 135 * the object being created/added 136 */ 137 void objectCreated(Object value); 138 139 /** 140 * Sets the target that was the response target for the current request 141 * 142 * @param target 143 * the response target 144 */ 145 void logResponseTarget(IRequestHandler target); 146 147 /** 148 * Sets the target that was the event target for the current request 149 * 150 * @param target 151 * the event target 152 */ 153 void logEventTarget(IRequestHandler target); 154 155 /** 156 * Logs the URL that was requested by the browser. 157 * 158 * @param url 159 * the requested URL 160 */ 161 void logRequestedUrl(String url); 162 163 /** 164 * Perform the actual logging 165 */ 166 void performLogging(); 167 168 /** 169 * This class hold the information one request of a session has. 170 * 171 * @author jcompagner 172 */ 173 class SessionData implements IClusterable, Comparable<SessionData> 174 { 175 private static final long serialVersionUID = 1L; 176 177 private final String sessionId; 178 private final long startDate; 179 private long lastActive; 180 private long numberOfRequests; 181 private long totalTimeTaken; 182 private long sessionSize; 183 private Object sessionInfo; 184 185 /** 186 * Construct. 187 * 188 * @param sessionId 189 */ 190 public SessionData(String sessionId) 191 { 192 this.sessionId = sessionId; 193 startDate = System.currentTimeMillis(); 194 numberOfRequests = 1; 195 } 196 197 /** 198 * @return The last active date. 199 */ 200 public Date getLastActive() 201 { 202 return new Date(lastActive); 203 } 204 205 /** 206 * @return The start date of this session 207 */ 208 public Date getStartDate() 209 { 210 return new Date(startDate); 211 } 212 213 /** 214 * @return The number of request for this session 215 */ 216 public long getNumberOfRequests() 217 { 218 return numberOfRequests; 219 } 220 221 /** 222 * @return Returns the session size. 223 */ 224 public long getSessionSize() 225 { 226 return sessionSize; 227 } 228 229 /** 230 * @return Returns the total time this session has spent in ms. 231 */ 232 public long getTotalTimeTaken() 233 { 234 return totalTimeTaken; 235 } 236 237 /** 238 * @return The session info object given by the {@link ISessionLogInfo#getSessionInfo()} 239 * session method. 240 */ 241 public Object getSessionInfo() 242 { 243 return sessionInfo; 244 } 245 246 /** 247 * @return The session id 248 */ 249 public String getSessionId() 250 { 251 return sessionId; 252 } 253 254 /** 255 * Adds {@code time} to the total server time. 256 * 257 * @param time 258 */ 259 public void addTimeTaken(long time) 260 { 261 lastActive = System.currentTimeMillis(); 262 numberOfRequests++; 263 totalTimeTaken += time; 264 } 265 266 /** 267 * Sets additional session info (e.g. logged in user). 268 * 269 * @param sessionInfo 270 */ 271 public void setSessionInfo(Object sessionInfo) 272 { 273 this.sessionInfo = sessionInfo; 274 } 275 276 /** 277 * Sets the recorded session size. 278 * 279 * @param size 280 */ 281 public void setSessionSize(long size) 282 { 283 sessionSize = size; 284 } 285 286 @Override 287 public int compareTo(SessionData sd) 288 { 289 if (sd.startDate > startDate) 290 { 291 return 1; 292 } 293 else if (sd.startDate < startDate) 294 { 295 return -1; 296 } 297 return 0; 298 } 299 } 300 301 302 /** 303 * This class hold the information one request of a session has. 304 * 305 * @author jcompagner 306 */ 307 class RequestData implements IClusterable 308 { 309 private static final long serialVersionUID = 1L; 310 311 private long startDate; 312 private long timeTaken; 313 private final List<String> entries = new ArrayList<>(5); 314 private Map<String, Object> userData; 315 private String requestedUrl; 316 private IRequestHandler eventTarget; 317 private IRequestHandler responseTarget; 318 private String sessionId; 319 private long totalSessionSize; 320 private Object sessionInfo; 321 private int activeRequest; 322 323 /** 324 * @return The time taken for this request 325 */ 326 public Long getTimeTaken() 327 { 328 return timeTaken; 329 } 330 331 /** 332 * @param activeRequest 333 * The number of active request when this request happened 334 */ 335 public void setActiveRequest(int activeRequest) 336 { 337 this.activeRequest = activeRequest; 338 } 339 340 /** 341 * @return The number of active request when this request happened 342 */ 343 public int getActiveRequest() 344 { 345 return activeRequest; 346 } 347 348 /** 349 * @return The session object info, created by {@link ISessionLogInfo#getSessionInfo()} 350 */ 351 public Object getSessionInfo() 352 { 353 return sessionInfo; 354 } 355 356 /** 357 * Set the session info object of the session for this request. 358 * 359 * @param sessionInfo 360 */ 361 public void setSessionInfo(Object sessionInfo) 362 { 363 this.sessionInfo = sessionInfo; 364 } 365 366 /** 367 * @param sizeInBytes 368 */ 369 public void setSessionSize(long sizeInBytes) 370 { 371 totalSessionSize = sizeInBytes; 372 } 373 374 /** 375 * @param id 376 */ 377 public void setSessionId(String id) 378 { 379 sessionId = id; 380 } 381 382 /** 383 * @return The time taken for this request 384 */ 385 public Date getStartDate() 386 { 387 return new Date(startDate); 388 } 389 390 /** 391 * @return The event target 392 */ 393 public IRequestHandler getEventTarget() 394 { 395 return eventTarget; 396 } 397 398 /** 399 * @return The class of the event target 400 */ 401 public Class<? extends IRequestHandler> getEventTargetClass() 402 { 403 return eventTarget == null ? null : eventTarget.getClass(); 404 } 405 406 /** 407 * @return The log data for the eventTarget, or {@link NoLogData} if the request handler is 408 * not loggable 409 */ 410 public ILogData getEventTargetLog() 411 { 412 if (eventTarget instanceof ILoggableRequestHandler) 413 return ((ILoggableRequestHandler)eventTarget).getLogData(); 414 return new NoLogData(); 415 } 416 417 /** 418 * @return The response target 419 */ 420 public IRequestHandler getResponseTarget() 421 { 422 return responseTarget; 423 } 424 425 /** 426 * @return The class of the response target 427 */ 428 public Class<? extends IRequestHandler> getResponseTargetClass() 429 { 430 return responseTarget == null ? null : responseTarget.getClass(); 431 } 432 433 /** 434 * @return The log data for the responseTarget, or {@link NoLogData} if the request handler 435 * is not loggable 436 */ 437 public ILogData getResponseTargetLog() 438 { 439 if (responseTarget instanceof ILoggableRequestHandler) 440 return ((ILoggableRequestHandler)responseTarget).getLogData(); 441 return new NoLogData(); 442 } 443 444 /** 445 * @return the requested URL by the browser 446 */ 447 public String getRequestedUrl() 448 { 449 return requestedUrl; 450 } 451 452 /** 453 * @param requestedUrl 454 */ 455 public void setRequestedUrl(String requestedUrl) 456 { 457 this.requestedUrl = requestedUrl; 458 } 459 460 /** 461 * @param target 462 */ 463 public void setResponseTarget(IRequestHandler target) 464 { 465 responseTarget = target; 466 } 467 468 /** 469 * @param target 470 */ 471 public void setEventTarget(IRequestHandler target) 472 { 473 eventTarget = target; 474 } 475 476 /** 477 * @param timeTaken 478 */ 479 public void setTimeTaken(long timeTaken) 480 { 481 this.timeTaken = timeTaken; 482 startDate = System.currentTimeMillis() - timeTaken; 483 } 484 485 /** 486 * @param string 487 */ 488 public void addEntry(String string) 489 { 490 entries.add(string); 491 } 492 493 /** 494 * @param key 495 * @param value 496 */ 497 public void addUserData(String key, Object value) 498 { 499 getUserData().put(key, value); 500 } 501 502 /** 503 * @param key 504 * @return 505 */ 506 public Object getUserData(String key) 507 { 508 return getUserData().get(key); 509 } 510 511 /** 512 * @return the userData Map 513 */ 514 public Map<String, Object> getUserData() 515 { 516 if (userData == null) { 517 userData = new HashMap<>(); 518 } 519 520 return userData; 521 } 522 523 /** 524 * @return All entries of the objects that are created/updated or removed in this request 525 */ 526 public String getAlteredObjects() 527 { 528 return Strings.join(", ", entries); 529 } 530 531 /** 532 * @return The session id for this request 533 */ 534 public String getSessionId() 535 { 536 return sessionId; 537 } 538 539 /** 540 * @return The total session size. 541 */ 542 public Long getSessionSize() 543 { 544 return totalSessionSize; 545 } 546 547 @Override 548 public String toString() 549 { 550 return "Request[timetaken=" + getTimeTaken() + ",sessioninfo=" + sessionInfo + 551 ",sessionid=" + sessionId + ",sessionsize=" + totalSessionSize + ",request=" + 552 eventTarget + ",response=" + responseTarget + ",alteredobjects=" + 553 getAlteredObjects() + ",activerequest=" + activeRequest + "]"; 554 } 555 } 556 557 /** 558 * This interface can be implemented in a custom session object. to give an object that has more 559 * information for the current session (state of session). 560 * 561 * @author jcompagner 562 */ 563 interface ISessionLogInfo 564 { 565 /** 566 * If you use the request logger log functionality then this object should have a nice 567 * String representation. So make sure that the toString() is implemented for the returned 568 * object. 569 * 570 * @return The custom object stored in the request loggers current request. 571 */ 572 Object getSessionInfo(); 573 } 574}