# encoding: utf-8 require "logstash/codecs/base" require "logstash/codecs/plain" require "logstash/json" # This codec will read cloudfront encoded content class LogStash::Codecs::Cloudfront < LogStash::Codecs::Base config_name "cloudfront" # The character encoding used in this codec. Examples include "UTF-8" and # "CP1252" # # JSON requires valid UTF-8 strings, but in some cases, software that # emits JSON does so in another encoding (nxlog, for example). In # weird cases like this, you can set the charset setting to the # actual encoding of the text and logstash will convert it for you. # # For nxlog users, you'll want to set this to "CP1252" config :charset, :validate => ::Encoding.name_list, :default => "UTF-8" public def initialize(params={}) super(params) @converter = LogStash::Util::Charset.new(@charset) @converter.logger = @logger end public def decode(data) begin @gzip = Zlib::GzipReader.new(data) metadata = extract_metadata(@gzip) @logger.debug("Cloudfront: Extracting metadata", :metadata => metadata) @gzip.each_line do |line| yield create_event(line, metadata) end rescue Zlib::Error, Zlib::GzipFile::Error=> e file = data.is_a?(String) ? data : data.class @logger.error("Cloudfront codec: We cannot uncompress the gzip file", :filename => file) raise e end end # def decode public def create_event(line, metadata) event = LogStash::Event.new("message" => @converter.convert(line)) event.set("cloudfront_version", metadata["cloudfront_version"]) event.set("cloudfront_fields", metadata["cloudfront_fields"]) event end def extract_metadata(io) version = extract_version(io.gets) fields = extract_fields(io.gets) return { "cloudfront_version" => version, "cloudfront_fields" => fields, } end def extract_version(line) if /^#Version: .+/.match(line) junk, version = line.strip().split(/#Version: (.+)/) version unless version.nil? end end def extract_fields(line) if /^#Fields: .+/.match(line) junk, format = line.strip().split(/#Fields: (.+)/) format unless format.nil? end end end # class LogStash::Codecs::Cloudfront