1
2
3
4
5
6
7
8
9
10
11 package chapter4;
12
13 import org.slf4j.Logger;
14
15 import ch.qos.logback.classic.LoggerContext;
16 import ch.qos.logback.classic.PatternLayout;
17 import ch.qos.logback.classic.spi.LoggingEvent;
18 import ch.qos.logback.core.FileAppender;
19 import ch.qos.logback.core.layout.EchoLayout;
20
21 public class IO extends Thread {
22 static String msgLong = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
23 static String msgShort = "Hello";
24 static boolean scarceCPU;
25 static int numThreads;
26 static long l;
27 static boolean longMessage;
28 long len;
29 boolean buffered;
30 boolean immediateFlush;
31 Logger logger;
32 LoggerContext context;
33 double throughput;
34
35 public IO(boolean _buffered, boolean _immediateFlush, long _len) {
36 this.len = _len;
37 this.buffered = _buffered;
38 this.immediateFlush = _immediateFlush;
39 context = new LoggerContext();
40 logger = context.getLogger("logger-" + getName());
41
42
43
44 FileAppender<LoggingEvent> fa = new FileAppender<LoggingEvent>();
45
46 if (longMessage) {
47 PatternLayout pa = new PatternLayout();
48 pa.setPattern("%r %5p %c [%t] - %m%n");
49 fa.setLayout(pa);
50 } else {
51 fa.setLayout(new EchoLayout<LoggingEvent>());
52 }
53
54 fa.setFile(getName() + ".log");
55 fa.setAppend(false);
56 fa.setImmediateFlush(immediateFlush);
57 fa.setBufferedIO(buffered);
58 fa.setContext(context);
59 fa.start();
60
61 }
62
63 public static void main(String[] argv) throws Exception {
64 if (argv.length != 4) {
65 usage("Wrong number of arguments.");
66 }
67
68 l = Integer.parseInt(argv[0]);
69 numThreads = Integer.parseInt(argv[1]);
70 scarceCPU = "true".equalsIgnoreCase(argv[2]);
71 longMessage = "long".equalsIgnoreCase(argv[3]);
72
73
74
75 perfCase(false, true, l);
76
77
78
79 perfCase(false, false, l);
80
81
82
83 perfCase(true, false, l);
84
85
86
87 }
88
89 static void usage(String msg) {
90 System.err.println(msg);
91 System.err.println("Usage: java " + IO.class.getName() +
92 " runLength numThreads scarceCPU (short|long)\n" +
93 " runLength (integer) the number of logs to generate perthread\n" +
94 " numThreads (integer) the number of threads.\n" +
95 " scarceCPU (boolean) if true an additional CPU intensive thread is created\n" +
96 " (short|long) length of log messages.");
97 System.exit(1);
98 }
99
100 static void perfCase(boolean buffered, boolean immediateFlush, long len)
101 throws Exception {
102 IO[] threads = new IO[numThreads];
103 Counter counterThread = null;
104
105 if (scarceCPU) {
106 counterThread = new Counter();
107 counterThread.start();
108 }
109
110
111 for (int i = 0; i < numThreads; i++) {
112 threads[i] = new IO(buffered, immediateFlush, len);
113 }
114
115
116 for (int i = 0; i < numThreads; i++) {
117 threads[i].start();
118 }
119
120
121 double sum = 0;
122
123 for (int i = 0; i < numThreads; i++) {
124 threads[i].join();
125 sum += threads[i].throughput;
126 }
127
128 if (scarceCPU) {
129
130 counterThread.interrupted = true;
131 counterThread.join();
132 }
133
134 System.out.println("On average throughput of " + (sum / numThreads) +
135 " logs per millisecond.");
136 System.out.println("------------------------------------------------");
137 }
138
139 public void run() {
140 String msg = msgShort;
141
142 if (longMessage) {
143 msg = msgLong;
144 }
145
146 long before = System.currentTimeMillis();
147
148 for (int i = 0; i < len; i++) {
149 logger.debug(msg);
150 }
151
152 throughput = (len * 1.0) / (System.currentTimeMillis() - before);
153 System.out.println(getName() + ", buffered: " + buffered +
154 ", immediateFlush: " + immediateFlush + ", throughput: " + throughput +
155 " logs per millisecond.");
156 }
157 }
158
159
160 class Counter extends Thread {
161 public boolean interrupted = false;
162 public double counter = 0;
163
164 public void run() {
165 long before = System.currentTimeMillis();
166
167 while (!interrupted) {
168 counter += 0.001;
169 }
170
171 double tput = (counter * 1.0) / (System.currentTimeMillis() - before);
172 System.out.println("Counter thread " + getName() +
173 " incremented counter by " + tput + " per millisecond.");
174 }
175 }