Skip to content

Instantly share code, notes, and snippets.

@steinybot
Last active September 13, 2017 03:25
Show Gist options
  • Save steinybot/028c12469f6f5590849d094ef9e889c6 to your computer and use it in GitHub Desktop.
Save steinybot/028c12469f6f5590849d094ef9e889c6 to your computer and use it in GitHub Desktop.
Convert a SBT Logger to an OutputStream
private object LoggerOutputStream {
def info(logger: Logger, charset: Charset = StandardCharsets.UTF_8, maxMessageSize: Int = 8192): OutputStream =
apply(logger, Level.Info, charset, maxMessageSize)
def error(logger: Logger, charset: Charset = StandardCharsets.UTF_8, maxMessageSize: Int = 8192): OutputStream =
apply(logger, Level.Error, charset, maxMessageSize)
def apply(logger: Logger, level: Level.Value, charset: Charset = StandardCharsets.UTF_8, maxMessageSize: Int = 8192): OutputStream =
new LoggerOutputStream(logger, level, charset, maxMessageSize)
private class LoggerOutputStream(logger: Logger, level: Level.Value, charset: Charset, maxMessageSize: Int) extends OutputStream {
private val decoder = charset.newDecoder()
private val in = ByteBuffer.allocate(maxMessageSize)
private val out = CharBuffer.allocate(maxMessageSize)
private var closed = false
override def write(b: Int): Unit = {
ensureOpen()
if (!in.hasRemaining) {
flush()
}
in.put(b.toByte)
}
@tailrec
override final def write(b: Array[Byte], off: Int, len: Int): Unit = {
ensureOpen()
val canFitLen = math.min(len, in.remaining)
in.put(b, off, canFitLen)
if (canFitLen < len) {
flush()
write(b, off + canFitLen, len - canFitLen)
}
}
override def flush(): Unit = flush(false)
def flush(closing: Boolean): Unit = {
ensureOpen()
in.flip()
val result = decoder.decode(in, out, closing)
if (result.isError) {
result.throwException()
}
in.compact()
out.flip()
if (out.hasRemaining) {
logger.log(level, StringUtils.chomp(out.toString))
out.position(out.limit)
}
out.compact()
}
private def ensureOpen(): Unit = {
if (closed) throw new IOException("LoggerOutputStream has been closed.")
}
override def close(): Unit = {
if (!closed) {
flush(true)
}
closed = true
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment