blob: 71950f741478ac4d4ea0493cddd0e7211ae74de6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache license, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the license for the specific language governing permissions and
* limitations under the license.
*/
package org.apache.logging.log4j.server;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.LogEventListener;
import org.apache.logging.log4j.core.parser.ParseException;
import org.apache.logging.log4j.core.parser.TextLogEventParser;
import org.apache.logging.log4j.util.Strings;
/**
* Reads and logs {@link LogEvent}s from an {@link InputStream}.
*/
public abstract class InputStreamLogEventBridge extends AbstractLogEventBridge<InputStream> {
private final int bufferSize;
private final Charset charset;
private final String eventEndMarker;
private final TextLogEventParser parser;
public InputStreamLogEventBridge(final TextLogEventParser parser, final int bufferSize, final Charset charset, final String eventEndMarker) {
this.bufferSize = bufferSize;
this.charset = charset;
this.eventEndMarker = eventEndMarker;
this.parser = parser;
}
abstract protected int[] getEventIndices(final String text, int beginIndex);
@Override
public void logEvents(final InputStream inputStream, final LogEventListener logEventListener)
throws IOException, ParseException {
String workingText = Strings.EMPTY;
try {
// Allocate buffer once
final byte[] buffer = new byte[bufferSize];
String textRemains = workingText = Strings.EMPTY;
while (true) {
// Process until the stream is EOF.
final int streamReadLength = inputStream.read(buffer);
if (streamReadLength == END) {
// The input stream is EOF
break;
}
final String text = workingText = textRemains + new String(buffer, 0, streamReadLength, charset);
int beginIndex = 0;
while (true) {
// Extract and log all XML events in the buffer
final int[] pair = getEventIndices(text, beginIndex);
final int eventStartMarkerIndex = pair[0];
if (eventStartMarkerIndex < 0) {
// No more events or partial XML only in the buffer.
// Save the unprocessed string part
textRemains = text.substring(beginIndex);
break;
}
final int eventEndMarkerIndex = pair[1];
if (eventEndMarkerIndex > 0) {
final int eventEndXmlIndex = eventEndMarkerIndex + eventEndMarker.length();
final String textEvent = workingText = text.substring(eventStartMarkerIndex, eventEndXmlIndex);
final LogEvent logEvent = unmarshal(textEvent);
logEventListener.log(logEvent);
beginIndex = eventEndXmlIndex;
} else {
// No more events or partial XML only in the buffer.
// Save the unprocessed string part
textRemains = text.substring(beginIndex);
break;
}
}
}
} catch (final IOException ex) {
logger.error(workingText, ex);
}
}
protected LogEvent unmarshal(final String jsonEvent) throws ParseException {
return this.parser.parseFrom(jsonEvent);
}
@Override
public String toString() {
return getClass().getName() + " [bufferSize=" + bufferSize + ", charset=" + charset + ", eventEndMarker="
+ eventEndMarker + ", parser=" + parser + "]";
}
}