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