1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.spi;
18
19 import org.apache.logging.log4j.Level;
20 import org.apache.logging.log4j.Marker;
21 import org.apache.logging.log4j.message.Message;
22
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.io.PrintStream;
26 import java.util.Locale;
27
28
29
30
31
32
33
34
35
36 public class LoggerStream extends PrintStream {
37
38 final PrintStream stream;
39
40 public LoggerStream(final AbstractLogger logger, final Level level) {
41 super(System.out);
42 stream = new PrintStream(new HelperStream(logger, null, level), true);
43 }
44
45 public LoggerStream(final AbstractLogger logger, final Marker marker, final Level level) {
46 super(System.out);
47 stream = new PrintStream(new HelperStream(logger, marker, level), true);
48 }
49
50 @Override
51 public void write(int b) {
52 stream.write(b);
53 }
54
55 @Override
56 public void write(byte[] b) throws IOException {
57 stream.write(b);
58 }
59
60 @Override
61 public void write(byte[] b, int off, int len) {
62 stream.write(b, off, len);
63 }
64
65 @Override
66 public void flush() {
67 stream.flush();
68 }
69
70 @Override
71 public void close() {
72 stream.close();
73 }
74
75 @Override
76 public void print(boolean b) {
77 stream.print(b);
78 }
79
80 @Override
81 public void print(char c) {
82 stream.print(c);
83 }
84
85 @Override
86 public void print(int i) {
87 stream.print(i);
88 }
89
90 @Override
91 public void print(long l) {
92 stream.print(l);
93 }
94
95 @Override
96 public void print(float f) {
97 stream.print(f);
98 }
99
100 @Override
101 public void print(double d) {
102 stream.print(d);
103 }
104
105 @Override
106 public void print(char[] s) {
107 stream.print(s);
108 }
109
110 @Override
111 public void print(String s) {
112 stream.print(s);
113 }
114
115 @Override
116 public void print(Object obj) {
117 stream.print(obj);
118 }
119
120 @Override
121 public void println() {
122 stream.println();
123 }
124
125 @Override
126 public void println(boolean x) {
127 stream.println(x);
128 }
129
130 @Override
131 public void println(char x) {
132 stream.println(x);
133 }
134
135 @Override
136 public void println(int x) {
137 stream.println(x);
138 }
139
140 @Override
141 public void println(long x) {
142 stream.println(x);
143 }
144
145 @Override
146 public void println(float x) {
147 stream.println(x);
148 }
149
150 @Override
151 public void println(double x) {
152 stream.println(x);
153 }
154
155 @Override
156 public void println(char[] x) {
157 stream.println(x);
158 }
159
160 @Override
161 public void println(String x) {
162 stream.println(x);
163 }
164
165 @Override
166 public void println(Object x) {
167 stream.println(x);
168 }
169
170 @Override
171 public LoggerStream printf(String format, Object... args) {
172 stream.printf(format, args);
173 return this;
174 }
175
176 @Override
177 public LoggerStream printf(Locale l, String format, Object... args) {
178 stream.printf(l, format, args);
179 return this;
180 }
181
182 @Override
183 public LoggerStream append(char c) {
184 stream.append(c);
185 return this;
186 }
187
188 @Override
189 public LoggerStream append(CharSequence csq) {
190 stream.append(csq);
191 return this;
192 }
193
194 @Override
195 public LoggerStream append(CharSequence csq, int start, int end) {
196 stream.append(csq, start, end);
197 return this;
198 }
199
200 @Override
201 public LoggerStream format(String format, Object... args) {
202 stream.format(format, args);
203 return this;
204 }
205
206 @Override
207 public LoggerStream format(Locale l, String format, Object... args) {
208 stream.format(l, format, args);
209 return this;
210 }
211
212 @Override
213 public boolean checkError() {
214 return stream.checkError();
215 }
216
217 @Override
218 public String toString() {
219 return "LoggerStream{" +
220 "stream=" + stream +
221 '}';
222 }
223
224 @Override
225 public boolean equals(Object other) {
226 return this == other
227 || !(other == null || getClass() != other.getClass())
228 && stream.equals(((LoggerStream) other).stream);
229 }
230
231 @Override
232 public int hashCode() {
233 return stream.hashCode();
234 }
235
236 private static class HelperStream extends ByteArrayOutputStream {
237 private static final String FQCN = LoggerStream.class.getName();
238 private final AbstractLogger logger;
239 private final Level level;
240 private final Marker marker;
241
242 private HelperStream(AbstractLogger logger, Marker marker, Level level) {
243 this.logger = logger;
244 this.marker = marker;
245 this.level = level;
246 }
247
248 private void log(int upTo) {
249 if (upTo < 0 || upTo >= count) {
250 throw new IndexOutOfBoundsException();
251 }
252 final Message message = logger.getMessageFactory().newMessage(extractLine(upTo));
253 logger.log(marker, FQCN, level, message, null);
254 }
255
256 private String extractLine(int upTo) {
257 final String line = new String(buf, 0, upTo);
258 leftShiftBuffer(upTo + 1);
259 return line;
260 }
261
262 private void leftShiftBuffer(int numBytes) {
263 int remaining = count - numBytes;
264 if (remaining > 0) {
265 System.arraycopy(buf, numBytes, buf, 0, remaining);
266 count = remaining + 1;
267 } else {
268 reset();
269 }
270 }
271
272 @Override
273 public synchronized void write(int b) {
274 if (b == '\r') {
275 return;
276 }
277 super.write(b);
278 if (b == '\n') {
279 log(count - 1);
280 }
281 }
282
283 @Override
284 public synchronized void write(byte[] b, int off, int len) {
285 for (int i = 0; i < len; ++i) {
286 write(b[off + i]);
287 }
288 }
289 }
290 }