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