16
16
import java .io .IOException ;
17
17
import java .io .OutputStream ;
18
18
import java .io .Writer ;
19
- import java .lang .ref .SoftReference ;
20
19
import java .util .ServiceConfigurationError ;
21
20
22
21
import net .logstash .logback .decorate .JsonFactoryDecorator ;
23
22
import net .logstash .logback .decorate .JsonGeneratorDecorator ;
24
23
import net .logstash .logback .decorate .NullJsonFactoryDecorator ;
25
24
import net .logstash .logback .decorate .NullJsonGeneratorDecorator ;
26
- import ch .qos .logback .access .spi .IAccessEvent ;
27
- import ch .qos .logback .classic .spi .ILoggingEvent ;
28
- import ch .qos .logback .core .spi .ContextAware ;
29
- import ch .qos .logback .core .spi .ContextAwareBase ;
30
- import ch .qos .logback .core .spi .DeferredProcessingAware ;
31
- import ch .qos .logback .core .spi .LifeCycle ;
32
25
33
26
import com .fasterxml .jackson .core .JsonEncoding ;
34
27
import com .fasterxml .jackson .core .JsonFactory ;
35
28
import com .fasterxml .jackson .core .JsonGenerator ;
36
- import com .fasterxml .jackson .core .io .SegmentedStringWriter ;
37
- import com .fasterxml .jackson .core .util .BufferRecycler ;
38
- import com .fasterxml .jackson .core .util .ByteArrayBuilder ;
39
29
import com .fasterxml .jackson .databind .ObjectMapper ;
40
30
import com .fasterxml .jackson .databind .SerializationFeature ;
41
31
32
+ import ch .qos .logback .access .spi .IAccessEvent ;
33
+ import ch .qos .logback .classic .spi .ILoggingEvent ;
34
+ import ch .qos .logback .core .spi .ContextAware ;
35
+ import ch .qos .logback .core .spi .ContextAwareBase ;
36
+ import ch .qos .logback .core .spi .DeferredProcessingAware ;
37
+ import ch .qos .logback .core .spi .LifeCycle ;
38
+
42
39
/**
43
40
* Formats logstash Events as JSON using {@link JsonProvider}s.
44
41
* <p>
52
49
public abstract class CompositeJsonFormatter <Event extends DeferredProcessingAware >
53
50
extends ContextAwareBase implements LifeCycle {
54
51
55
- /**
56
- * This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftReference}
57
- * to a {@link BufferRecycler} used to provide a low-cost
58
- * buffer recycling between writer instances.
59
- */
60
- private final ThreadLocal <SoftReference <BufferRecycler >> recycler = new ThreadLocal <SoftReference <BufferRecycler >>() {
61
- protected SoftReference <BufferRecycler > initialValue () {
62
- final BufferRecycler bufferRecycler = new BufferRecycler ();
63
- return new SoftReference <BufferRecycler >(bufferRecycler );
64
- }
65
- };
66
-
67
52
/**
68
53
* Used to create the necessary {@link JsonGenerator}s for generating JSON.
69
54
*/
@@ -134,35 +119,7 @@ private JsonFactory createJsonFactory() {
134
119
}
135
120
}
136
121
137
- JsonFactory jsonFactory = objectMapper
138
- .getFactory ()
139
- /*
140
- * When generators are flushed, don't flush the underlying outputStream.
141
- *
142
- * This allows some streaming optimizations when using an encoder.
143
- *
144
- * The encoder generally determines when the stream should be flushed
145
- * by an 'immediateFlush' property.
146
- *
147
- * The 'immediateFlush' property of the encoder can be set to false
148
- * when the appender performs the flushes at appropriate times
149
- * (such as the end of a batch in the AbstractLogstashTcpSocketAppender).
150
- */
151
- .disable (JsonGenerator .Feature .FLUSH_PASSED_TO_STREAM );
152
-
153
- return this .jsonFactoryDecorator .decorate (jsonFactory );
154
- }
155
-
156
- public byte [] writeEventAsBytes (Event event ) throws IOException {
157
- ByteArrayBuilder outputStream = new ByteArrayBuilder (getBufferRecycler ());
158
-
159
- try {
160
- writeEventToOutputStream (event , outputStream );
161
- outputStream .flush ();
162
- return outputStream .toByteArray ();
163
- } finally {
164
- outputStream .release ();
165
- }
122
+ return this .jsonFactoryDecorator .decorate (objectMapper .getFactory ());
166
123
}
167
124
168
125
public void writeEventToOutputStream (Event event , OutputStream outputStream ) throws IOException {
@@ -177,13 +134,9 @@ public void writeEventToOutputStream(Event event, OutputStream outputStream) thr
177
134
*/
178
135
}
179
136
180
- public String writeEventAsString (Event event ) throws IOException {
181
- SegmentedStringWriter writer = new SegmentedStringWriter (getBufferRecycler ());
182
-
137
+ public void writeEventToWriter (Event event , Writer writer ) throws IOException {
183
138
try (JsonGenerator generator = createGenerator (writer )) {
184
139
writeEventToGenerator (generator , event );
185
- writer .flush ();
186
- return writer .getAndClear ();
187
140
}
188
141
}
189
142
@@ -203,23 +156,36 @@ protected void prepareForDeferredProcessing(Event event) {
203
156
}
204
157
205
158
private JsonGenerator createGenerator (OutputStream outputStream ) throws IOException {
206
- return this . jsonGeneratorDecorator . decorate (jsonFactory .createGenerator (outputStream , encoding ));
159
+ return decorateGenerator (jsonFactory .createGenerator (outputStream , encoding ));
207
160
}
208
-
161
+
209
162
private JsonGenerator createGenerator (Writer writer ) throws IOException {
210
- return this .jsonGeneratorDecorator .decorate (jsonFactory .createGenerator (writer ));
211
- }
212
-
213
- private BufferRecycler getBufferRecycler () {
214
- SoftReference <BufferRecycler > bufferRecyclerReference = recycler .get ();
215
- BufferRecycler bufferRecycler = bufferRecyclerReference .get ();
216
- if (bufferRecycler == null ) {
217
- recycler .remove ();
218
- return getBufferRecycler ();
219
- }
220
- return bufferRecycler ;
221
- }
222
-
163
+ return decorateGenerator (jsonFactory .createGenerator (writer ));
164
+ }
165
+
166
+ private JsonGenerator decorateGenerator (JsonGenerator generator ) {
167
+ return this .jsonGeneratorDecorator .decorate (generator )
168
+ /*
169
+ * When generators are flushed, don't flush the underlying outputStream.
170
+ *
171
+ * This allows some streaming optimizations when using an encoder.
172
+ *
173
+ * The encoder generally determines when the stream should be flushed
174
+ * by an 'immediateFlush' property.
175
+ *
176
+ * The 'immediateFlush' property of the encoder can be set to false
177
+ * when the appender performs the flushes at appropriate times
178
+ * (such as the end of a batch in the AbstractLogstashTcpSocketAppender).
179
+ */
180
+ .disable (JsonGenerator .Feature .FLUSH_PASSED_TO_STREAM )
181
+
182
+ /*
183
+ * Don't let the json generator close the underlying outputStream and let the
184
+ * encoder managed it.
185
+ */
186
+ .disable (JsonGenerator .Feature .AUTO_CLOSE_TARGET );
187
+ }
188
+
223
189
public JsonFactory getJsonFactory () {
224
190
return jsonFactory ;
225
191
}
0 commit comments