1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.filter.statistic;
21
22 import java.util.HashSet;
23 import java.util.Set;
24 import java.util.concurrent.TimeUnit;
25 import java.util.concurrent.atomic.AtomicLong;
26
27 import org.apache.mina.core.filterchain.IoFilterAdapter;
28 import org.apache.mina.core.session.IdleStatus;
29 import org.apache.mina.core.session.IoEventType;
30 import org.apache.mina.core.session.IoSession;
31 import org.apache.mina.core.write.WriteRequest;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public class ProfilerTimerFilter extends IoFilterAdapter {
62
63 private volatile TimeUnit timeUnit;
64
65
66 private TimerWorker messageReceivedTimerWorker;
67
68
69 private boolean profileMessageReceived = false;
70
71
72 private TimerWorker messageSentTimerWorker;
73
74
75 private boolean profileMessageSent = false;
76
77
78 private TimerWorker sessionCreatedTimerWorker;
79
80
81 private boolean profileSessionCreated = false;
82
83
84 private TimerWorker sessionOpenedTimerWorker;
85
86
87 private boolean profileSessionOpened = false;
88
89
90 private TimerWorker sessionIdleTimerWorker;
91
92
93 private boolean profileSessionIdle = false;
94
95
96 private TimerWorker sessionClosedTimerWorker;
97
98
99 private boolean profileSessionClosed = false;
100
101
102
103
104
105
106
107 public ProfilerTimerFilter() {
108 this(
109 TimeUnit.MILLISECONDS,
110 IoEventType.MESSAGE_RECEIVED, IoEventType.MESSAGE_SENT);
111 }
112
113
114
115
116
117
118
119
120 public ProfilerTimerFilter(TimeUnit timeUnit) {
121 this(
122 timeUnit,
123 IoEventType.MESSAGE_RECEIVED, IoEventType.MESSAGE_SENT);
124 }
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 public ProfilerTimerFilter(TimeUnit timeUnit, IoEventType... eventTypes) {
143 this.timeUnit = timeUnit;
144
145 setProfilers(eventTypes);
146 }
147
148
149
150
151
152
153 private void setProfilers(IoEventType... eventTypes) {
154 for (IoEventType type : eventTypes) {
155 switch (type) {
156 case MESSAGE_RECEIVED :
157 messageReceivedTimerWorker = new TimerWorker();
158 profileMessageReceived = true;
159 break;
160
161 case MESSAGE_SENT :
162 messageSentTimerWorker = new TimerWorker();
163 profileMessageSent = true;
164 break;
165
166 case SESSION_CREATED :
167 sessionCreatedTimerWorker = new TimerWorker();
168 profileSessionCreated = true;
169 break;
170
171 case SESSION_OPENED :
172 sessionOpenedTimerWorker = new TimerWorker();
173 profileSessionOpened = true;
174 break;
175
176 case SESSION_IDLE :
177 sessionIdleTimerWorker = new TimerWorker();
178 profileSessionIdle = true;
179 break;
180
181 case SESSION_CLOSED :
182 sessionClosedTimerWorker = new TimerWorker();
183 profileSessionClosed = true;
184 break;
185 }
186 }
187 }
188
189
190
191
192
193
194 public void setTimeUnit(TimeUnit timeUnit) {
195 this.timeUnit = timeUnit;
196 }
197
198
199
200
201
202
203 public void profile(IoEventType type) {
204 switch (type) {
205 case MESSAGE_RECEIVED :
206 profileMessageReceived = true;
207
208 if (messageReceivedTimerWorker == null) {
209 messageReceivedTimerWorker = new TimerWorker();
210 }
211
212 return;
213
214 case MESSAGE_SENT :
215 profileMessageSent = true;
216
217 if (messageSentTimerWorker == null) {
218 messageSentTimerWorker = new TimerWorker();
219 }
220
221 return;
222
223 case SESSION_CREATED :
224 profileSessionCreated = true;
225
226 if (sessionCreatedTimerWorker == null) {
227 sessionCreatedTimerWorker = new TimerWorker();
228 }
229
230 case SESSION_OPENED :
231 profileSessionOpened = true;
232
233 if (sessionOpenedTimerWorker == null) {
234 sessionOpenedTimerWorker = new TimerWorker();
235 }
236
237 case SESSION_IDLE :
238 profileSessionIdle = true;
239
240 if (sessionIdleTimerWorker == null) {
241 sessionIdleTimerWorker = new TimerWorker();
242 }
243
244 case SESSION_CLOSED :
245 profileSessionClosed = true;
246
247 if (sessionClosedTimerWorker == null) {
248 sessionClosedTimerWorker = new TimerWorker();
249 }
250 }
251 }
252
253
254
255
256
257
258 public void stopProfile(IoEventType type) {
259 switch (type) {
260 case MESSAGE_RECEIVED :
261 profileMessageReceived = false;
262 return;
263
264 case MESSAGE_SENT :
265 profileMessageSent = false;
266 return;
267
268 case SESSION_CREATED :
269 profileSessionCreated = false;
270 return;
271
272 case SESSION_OPENED :
273 profileSessionOpened = false;
274 return;
275
276 case SESSION_IDLE :
277 profileSessionIdle = false;
278 return;
279
280 case SESSION_CLOSED :
281 profileSessionClosed = false;
282 return;
283 }
284 }
285
286
287
288
289
290
291 public Set<IoEventType> getEventsToProfile() {
292 Set<IoEventType> set = new HashSet<IoEventType>();
293
294 if ( profileMessageReceived ) {
295 set.add(IoEventType.MESSAGE_RECEIVED);
296 }
297
298 if ( profileMessageSent) {
299 set.add(IoEventType.MESSAGE_SENT);
300 }
301
302 if ( profileSessionCreated ) {
303 set.add(IoEventType.SESSION_CREATED);
304 }
305
306 if ( profileSessionOpened ) {
307 set.add(IoEventType.SESSION_OPENED);
308 }
309
310 if ( profileSessionIdle ) {
311 set.add(IoEventType.SESSION_IDLE);
312 }
313
314 if ( profileSessionClosed ) {
315 set.add(IoEventType.SESSION_CLOSED);
316 }
317
318 return set;
319 }
320
321
322
323
324
325
326 public void setEventsToProfile(IoEventType... eventTypes) {
327 setProfilers(eventTypes);
328 }
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343 @Override
344 public void messageReceived(NextFilter nextFilter, IoSession session,
345 Object message) throws Exception {
346 if (profileMessageReceived) {
347 long start = timeNow();
348 nextFilter.messageReceived(session, message);
349 long end = timeNow();
350 messageReceivedTimerWorker.addNewDuration(end - start);
351 } else {
352 nextFilter.messageReceived(session, message);
353 }
354 }
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369 @Override
370 public void messageSent(NextFilter nextFilter, IoSession session,
371 WriteRequest writeRequest) throws Exception {
372 if (profileMessageSent) {
373 long start = timeNow();
374 nextFilter.messageSent(session, writeRequest);
375 long end = timeNow();
376 messageSentTimerWorker.addNewDuration(end - start);
377 } else {
378 nextFilter.messageSent(session, writeRequest);
379 }
380 }
381
382
383
384
385
386
387
388
389
390
391
392
393
394 @Override
395 public void sessionCreated(NextFilter nextFilter, IoSession session)
396 throws Exception {
397 if (profileSessionCreated) {
398 long start = timeNow();
399 nextFilter.sessionCreated(session);
400 long end = timeNow();
401 sessionCreatedTimerWorker.addNewDuration(end - start);
402 } else {
403 nextFilter.sessionCreated(session);
404 }
405 }
406
407
408
409
410
411
412
413
414
415
416
417
418
419 @Override
420 public void sessionOpened(NextFilter nextFilter, IoSession session)
421 throws Exception {
422 if (profileSessionOpened) {
423 long start = timeNow();
424 nextFilter.sessionOpened(session);
425 long end = timeNow();
426 sessionOpenedTimerWorker.addNewDuration(end - start);
427 } else {
428 nextFilter.sessionOpened(session);
429 }
430 }
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445 @Override
446 public void sessionIdle(NextFilter nextFilter, IoSession session,
447 IdleStatus status) throws Exception {
448 if (profileSessionIdle) {
449 long start = timeNow();
450 nextFilter.sessionIdle(session, status);
451 long end = timeNow();
452 sessionIdleTimerWorker.addNewDuration(end - start);
453 } else {
454 nextFilter.sessionIdle(session, status);
455 }
456 }
457
458
459
460
461
462
463
464
465
466
467
468
469
470 @Override
471 public void sessionClosed(NextFilter nextFilter, IoSession session)
472 throws Exception {
473 if (profileSessionClosed) {
474 long start = timeNow();
475 nextFilter.sessionClosed(session);
476 long end = timeNow();
477 sessionClosedTimerWorker.addNewDuration(end - start);
478 } else {
479 nextFilter.sessionClosed(session);
480 }
481 }
482
483
484
485
486
487
488
489
490
491 public double getAverageTime(IoEventType type) {
492 switch (type) {
493 case MESSAGE_RECEIVED :
494 if (profileMessageReceived) {
495 return messageReceivedTimerWorker.getAverage();
496 }
497
498 break;
499
500 case MESSAGE_SENT :
501 if (profileMessageSent) {
502 return messageSentTimerWorker.getAverage();
503 }
504
505 break;
506
507 case SESSION_CREATED :
508 if (profileSessionCreated) {
509 return sessionCreatedTimerWorker.getAverage();
510 }
511
512 break;
513
514 case SESSION_OPENED :
515 if (profileSessionOpened) {
516 return sessionOpenedTimerWorker.getAverage();
517 }
518
519 break;
520
521 case SESSION_IDLE :
522 if (profileSessionIdle) {
523 return sessionIdleTimerWorker.getAverage();
524 }
525
526 break;
527
528 case SESSION_CLOSED :
529 if (profileSessionClosed) {
530 return sessionClosedTimerWorker.getAverage();
531 }
532
533 break;
534 }
535
536 throw new IllegalArgumentException(
537 "You are not monitoring this event. Please add this event first.");
538 }
539
540
541
542
543
544
545
546
547
548
549 public long getTotalCalls(IoEventType type) {
550 switch (type) {
551 case MESSAGE_RECEIVED :
552 if (profileMessageReceived) {
553 return messageReceivedTimerWorker.getCallsNumber();
554 }
555
556 break;
557
558 case MESSAGE_SENT :
559 if (profileMessageSent) {
560 return messageSentTimerWorker.getCallsNumber();
561 }
562
563 break;
564
565 case SESSION_CREATED :
566 if (profileSessionCreated) {
567 return sessionCreatedTimerWorker.getCallsNumber();
568 }
569
570 break;
571
572 case SESSION_OPENED :
573 if (profileSessionOpened) {
574 return sessionOpenedTimerWorker.getCallsNumber();
575 }
576
577 break;
578
579 case SESSION_IDLE :
580 if (profileSessionIdle) {
581 return sessionIdleTimerWorker.getCallsNumber();
582 }
583
584 break;
585
586 case SESSION_CLOSED :
587 if (profileSessionClosed) {
588 return sessionClosedTimerWorker.getCallsNumber();
589 }
590
591 break;
592 }
593
594 throw new IllegalArgumentException(
595 "You are not monitoring this event. Please add this event first.");
596 }
597
598
599
600
601
602
603
604
605
606
607 public long getTotalTime(IoEventType type) {
608 switch (type) {
609 case MESSAGE_RECEIVED :
610 if (profileMessageReceived) {
611 return messageReceivedTimerWorker.getTotal();
612 }
613
614 break;
615
616 case MESSAGE_SENT :
617 if (profileMessageSent) {
618 return messageSentTimerWorker.getTotal();
619 }
620
621 break;
622
623 case SESSION_CREATED :
624 if (profileSessionCreated) {
625 return sessionCreatedTimerWorker.getTotal();
626 }
627
628 break;
629
630 case SESSION_OPENED :
631 if (profileSessionOpened) {
632 return sessionOpenedTimerWorker.getTotal();
633 }
634
635 break;
636
637 case SESSION_IDLE :
638 if (profileSessionIdle) {
639 return sessionIdleTimerWorker.getTotal();
640 }
641
642 break;
643
644 case SESSION_CLOSED :
645 if (profileSessionClosed) {
646 return sessionClosedTimerWorker.getTotal();
647 }
648
649 break;
650 }
651
652 throw new IllegalArgumentException(
653 "You are not monitoring this event. Please add this event first.");
654 }
655
656
657
658
659
660
661
662
663
664
665 public long getMinimumTime(IoEventType type) {
666 switch (type) {
667 case MESSAGE_RECEIVED :
668 if (profileMessageReceived) {
669 return messageReceivedTimerWorker.getMinimum();
670 }
671
672 break;
673
674 case MESSAGE_SENT :
675 if (profileMessageSent) {
676 return messageSentTimerWorker.getMinimum();
677 }
678
679 break;
680
681 case SESSION_CREATED :
682 if (profileSessionCreated) {
683 return sessionCreatedTimerWorker.getMinimum();
684 }
685
686 break;
687
688 case SESSION_OPENED :
689 if (profileSessionOpened) {
690 return sessionOpenedTimerWorker.getMinimum();
691 }
692
693 break;
694
695 case SESSION_IDLE :
696 if (profileSessionIdle) {
697 return sessionIdleTimerWorker.getMinimum();
698 }
699
700 break;
701
702 case SESSION_CLOSED :
703 if (profileSessionClosed) {
704 return sessionClosedTimerWorker.getMinimum();
705 }
706
707 break;
708 }
709
710 throw new IllegalArgumentException(
711 "You are not monitoring this event. Please add this event first.");
712 }
713
714
715
716
717
718
719
720
721
722
723 public long getMaximumTime(IoEventType type) {
724 switch (type) {
725 case MESSAGE_RECEIVED :
726 if (profileMessageReceived) {
727 return messageReceivedTimerWorker.getMaximum();
728 }
729
730 break;
731
732 case MESSAGE_SENT :
733 if (profileMessageSent) {
734 return messageSentTimerWorker.getMaximum();
735 }
736
737 break;
738
739 case SESSION_CREATED :
740 if (profileSessionCreated) {
741 return sessionCreatedTimerWorker.getMaximum();
742 }
743
744 break;
745
746 case SESSION_OPENED :
747 if (profileSessionOpened) {
748 return sessionOpenedTimerWorker.getMaximum();
749 }
750
751 break;
752
753 case SESSION_IDLE :
754 if (profileSessionIdle) {
755 return sessionIdleTimerWorker.getMaximum();
756 }
757
758 break;
759
760 case SESSION_CLOSED :
761 if (profileSessionClosed) {
762 return sessionClosedTimerWorker.getMaximum();
763 }
764
765 break;
766 }
767
768 throw new IllegalArgumentException(
769 "You are not monitoring this event. Please add this event first.");
770 }
771
772
773
774
775
776
777 private class TimerWorker {
778
779 private final AtomicLong total;
780
781
782 private final AtomicLong callsNumber;
783
784
785 private final AtomicLong minimum;
786
787
788 private final AtomicLong maximum;
789
790
791 private final Object lock = new Object();
792
793
794
795
796
797 public TimerWorker() {
798 total = new AtomicLong();
799 callsNumber = new AtomicLong();
800 minimum = new AtomicLong();
801 maximum = new AtomicLong();
802 }
803
804
805
806
807
808
809
810
811 public void addNewDuration(long duration) {
812 callsNumber.incrementAndGet();
813 total.addAndGet(duration);
814
815 synchronized (lock) {
816
817 if (duration < minimum.longValue()) {
818 minimum.set(duration);
819 }
820
821
822 if (duration > maximum.longValue()) {
823 maximum.set(duration);
824 }
825 }
826 }
827
828
829
830
831
832
833 public double getAverage() {
834 synchronized (lock) {
835
836 return total.longValue() / callsNumber.longValue();
837 }
838 }
839
840
841
842
843
844
845 public long getCallsNumber() {
846 return callsNumber.longValue();
847 }
848
849
850
851
852
853
854 public long getTotal() {
855 return total.longValue();
856 }
857
858
859
860
861
862
863 public long getMinimum() {
864 return minimum.longValue();
865 }
866
867
868
869
870
871
872 public long getMaximum() {
873 return maximum.longValue();
874 }
875 }
876
877
878
879
880 private long timeNow() {
881 switch (timeUnit) {
882 case SECONDS :
883 return System.currentTimeMillis()/1000;
884
885 case MICROSECONDS :
886 return System.nanoTime()/1000;
887
888 case NANOSECONDS :
889 return System.nanoTime();
890
891 default :
892 return System.currentTimeMillis();
893 }
894 }
895 }