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