blob: cfc1986358d4074add630c524cff954bfee560f0 [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.drill.exec.compile;
import java.io.IOException;
import java.io.Writer;
import com.google.common.base.Preconditions;
import org.apache.log4j.Level;
import org.slf4j.Logger;
/**
* A simple Writer that will forward whole lines (lines ending with a newline) to
* a Logger. The newlines themselves are not forwarded.
*/
public class LogWriter extends Writer {
private final Logger logger; // the underlying logger to write to
private final int level; // the debug level to write at
private final StringBuilder stringBuilder; // a buffer for incomplete lines
private boolean isClosed; // close() has been called
/**
* Constructor.
*
* @param logger the logger this Writer should write to
* @param level the debug level to write to the logger with
*/
public LogWriter(final Logger logger, final Level level) {
Preconditions.checkNotNull(logger);
Preconditions.checkArgument((level == Level.DEBUG) || (level == Level.ERROR) ||
(level == Level.INFO) || (level == Level.TRACE) || (level == Level.WARN),
"level must be a logging level");
this.logger = logger;
this.level = level.toInt();
stringBuilder = new StringBuilder(80);
isClosed = false;
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
checkNotClosed();
stringBuilder.append(cbuf, off, len);
// log all of the whole lines we have
do {
final int newlinePos = stringBuilder.indexOf("\n");
if (newlinePos < 0) {
break;
}
final String oneLine = stringBuilder.substring(0, newlinePos); // leaves out the newline
writeToLog(oneLine);
stringBuilder.delete(0, newlinePos + 1); // removes the newline as well
} while (stringBuilder.length() > 0);
}
@Override
public void flush() throws IOException {
checkNotClosed();
flushToLog();
}
@Override
public void close() throws IOException {
checkNotClosed();
isClosed = true;
flushToLog();
}
/*
* Assumes there are no newlines.
*/
private void flushToLog() {
writeToLog(stringBuilder.toString());
stringBuilder.setLength(0);
}
private void writeToLog(final String s) {
if ((s == null) || s.isEmpty()) {
return;
}
switch(level) {
case Level.DEBUG_INT:
logger.debug(s);
break;
case Level.ERROR_INT:
logger.error(s);
break;
case Level.INFO_INT:
logger.info(s);
break;
case Level.TRACE_INT:
logger.trace(s);
break;
case Level.WARN_INT:
logger.warn(s);
break;
default:
throw new IllegalStateException();
}
}
private void checkNotClosed() throws IOException {
if (isClosed) {
throw new IOException("LogWriter is already closed()");
}
}
}