class Docker::Template::Logger
Attributes
Public Class Methods
–
# File lib/docker/template/logger.rb, line 27 def initialize(repo = nil, stdout = nil, stderr = nil) @stdout = stdout || self.class.stdout @stderr = stderr || self.class.stderr @repo = repo @lines = { 0 => 0 } end
–
# File lib/docker/template/logger.rb, line 20 def stderr return @stderr || $stderr end
–
# File lib/docker/template/logger.rb, line 14 def stdout return @stdout || $stdout end
Public Instance Methods
– A more complex streamer designed for the actual output of the Docker
. – This method will save parts into a buffer until it can either parse that buffer or it parses the actual part itself, if it can parse the part itself, it will first dump the buffer as errors and then parse. – This method has to buffer because Docker-API (or Excon, it's depend) gives us no indication of whether or not this is part of a larger chunk it just dumps it on us, so we have to blindly work around that. –
# File lib/docker/template/logger.rb, line 84 def api(part, *args) part = encode_str(part).each_line.to_a if part.one? && part = part.first chunked_part = @chunks.push(part).join if @chunks && !@chunks.empty? chunked_part = part if !@chunks stream = JSON.parse( chunked_part ) if chunked_part == part && @chunks && !@chunks.empty? then @chunks.each do |chunk| @stderr.puts format("Unparsable JSON: %s", chunk ) end end @chunks = nil return progress_bar(stream) if stream.any_key?("progress", "progressDetail") return output(stream["status"] || stream["stream"]) if stream.any_key?("status", "stream") return progress_error(stream) if stream.any_key?("errorDetail", "error") warn Simple::Ansi.red("Unhandled Stream.") @stdout.puts(part) @output = true else part.each do |v| api(v, *args) end end # -- # Sometimes we get undetectable chunks. # When we do, we try to keep them passed along. # That way we can throw them out later. # -- rescue JSON::ParserError => e (@chunks ||= []).push( part ) end
–
# File lib/docker/template/logger.rb, line 44 def increment @lines.update({ @lines.size => @lines.size }) end
–
# File lib/docker/template/logger.rb, line 126 def output(msg) unless filter_matches?(msg) @stdout.puts msg increment end @output = true end
–
# File lib/docker/template/logger.rb, line 38 def output? return !!@output end
–
# File lib/docker/template/logger.rb, line 137 def progress_error(stream) abort Object::Simple::Ansi.red( stream["errorDetail"]["message"] ) end
– A simple logger that accepts a multi-type stream. –
# File lib/docker/template/logger.rb, line 66 def simple(type, str) str = encode_str(str ||= "") type == :stderr ? @stderr.print(str) : \ @stdout.print(str) end
– A simple TTY stream that just prints out the data that it is given. This is the logger that most will use for most of their building. –
# File lib/docker/template/logger.rb, line 55 def tty(stream) @output = true @stdout.print(encode_str( stream )) end
Private Instance Methods
– Some applications return some invalid ASCII so we need to work around that so that no errors happen. This mostly happens with Node.js NPM. –
# File lib/docker/template/logger.rb, line 150 def encode_str(str) str.encode("utf-8", { :invalid => :replace, :undef => :replace, :replace => "" }) end
–
# File lib/docker/template/logger.rb, line 191 def filter_matches?(msg) return false unless @repo @repo.meta["log_filters"].any? do |filter| filter.is_a?(Regexp) && msg =~ filter || msg == filter end end
–
# File lib/docker/template/logger.rb, line 159 def progress_bar(stream) if ENV["CI"] != "true" id = stream["id"] return unless id before, diff = progress_diff(id) @stderr.print before if before str = stream["progress"] || stream["status"] str = "#{id}: #{str}\r" @stderr.print(Object::Simple::Ansi.jump( str, diff )) end end
–
# File lib/docker/template/logger.rb, line 178 def progress_diff(id) if @lines.key?(id) return nil, @lines.size - @lines[id] end @lines[id] = @lines.size before = "\n" unless @lines.one? return before, 0 end