Search in sources :

Example 1 with LogMessage

use of com.spotify.docker.client.LogMessage in project helios by spotify.

the class LoggingLogStreamFollower method followLog.

@Override
public void followLog(final JobId jobId, final String containerId, final Iterator<LogMessage> logStream) throws IOException {
    final Map<LogMessage.Stream, Decoder> streamDecoders = createStreamDecoders();
    final StringBuilder stringBuilder = new StringBuilder();
    LogMessage.Stream lastStream = null;
    try {
        while (logStream.hasNext()) {
            final LogMessage message = logStream.next();
            final ByteBuffer content = message.content();
            final LogMessage.Stream stream = message.stream();
            if (lastStream != null && lastStream != stream && stringBuilder.length() > 0) {
                log(lastStream, containerId, jobId, stringBuilder);
            }
            final Decoder decoder = streamDecoders.get(stream);
            final CharsetDecoder charsetDecoder = decoder.charsetDecoder;
            final ByteBuffer byteBuffer = decoder.byteBuffer;
            final CharBuffer charBuffer = decoder.charBuffer;
            while (content.hasRemaining()) {
                // Transfer as much of content into byteBuffer that we have room for
                byteBuffer.put(content);
                byteBuffer.flip();
                // Decode as much of byteBuffer into charBuffer that we can
                charsetDecoder.decode(byteBuffer, charBuffer, false);
                // The decoder might have left some partial byte sequences in the byteBuffer... Since we
                // don't have a ring buffer we should compact the buffer to not overflow.
                // We MUST NOT clear the byteBuffer since then we can lose those partial byte sequences.
                byteBuffer.compact();
                // Now start consuming the charBuffer
                charBuffer.flip();
                // Heuristic to avoid allocations... this will allocate too much memory if the charBuffer
                // contains any newlines or other special chars
                stringBuilder.ensureCapacity(charBuffer.remaining());
                while (charBuffer.hasRemaining()) {
                    final char c = charBuffer.get();
                    switch(c) {
                        case '\n':
                            log(stream, containerId, jobId, stringBuilder);
                            break;
                        default:
                            stringBuilder.append(c);
                    }
                }
                // This buffer is completely drained so we can reset it
                charBuffer.clear();
            }
            lastStream = stream;
        }
    } finally {
        if (lastStream != null && stringBuilder.length() > 0) {
            // Yes, we are not checking for any trailing bytes in the decoder byteBuffers here.  That
            // means that if the container wrote partial UTF-8 sequences before EOF they will be
            // discarded.
            log(lastStream, containerId, jobId, stringBuilder);
        }
    }
}
Also used : CharsetDecoder(java.nio.charset.CharsetDecoder) LogMessage(com.spotify.docker.client.LogMessage) CharBuffer(java.nio.CharBuffer) CharsetDecoder(java.nio.charset.CharsetDecoder) ByteBuffer(java.nio.ByteBuffer)

Example 2 with LogMessage

use of com.spotify.docker.client.LogMessage in project helios by spotify.

the class InMemoryLogStreamFollower method followLog.

@Override
public void followLog(final JobId jobId, final String containerId, final Iterator<LogMessage> logStream) throws IOException {
    try (final ByteArrayOutputStream stdout = new ByteArrayOutputStream();
        final ByteArrayOutputStream stderr = new ByteArrayOutputStream()) {
        streamHolders.put(jobId, new StreamHolder(stdout, stderr));
        while (logStream.hasNext()) {
            final LogMessage message = logStream.next();
            final ByteBuffer content = message.content();
            switch(message.stream()) {
                case STDOUT:
                    writeAndFlush(content, stdout);
                    break;
                case STDERR:
                    writeAndFlush(content, stderr);
                    break;
                case STDIN:
                default:
                    break;
            }
        }
    }
}
Also used : LogMessage(com.spotify.docker.client.LogMessage) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ByteBuffer(java.nio.ByteBuffer)

Aggregations

LogMessage (com.spotify.docker.client.LogMessage)2 ByteBuffer (java.nio.ByteBuffer)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 CharBuffer (java.nio.CharBuffer)1 CharsetDecoder (java.nio.charset.CharsetDecoder)1