fluent-plugin-heroku-syslog 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/README.md +42 -5
- data/fluent-plugin-heroku-syslog.gemspec +3 -2
- data/lib/fluent/plugin/in_heroku_syslog.rb +22 -208
- data/lib/fluent/plugin/in_heroku_syslog_http.rb +37 -0
- data/lib/fluent/plugin/logplex.rb +55 -0
- data/test/helper.rb +1 -0
- data/test/plugin/test_in_heroku_syslog.rb +60 -10
- data/test/plugin/test_in_heroku_syslog_http.rb +181 -0
- metadata +23 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 45464deb9237a40a07e441e968af9c5b70fa3bce
         | 
| 4 | 
            +
              data.tar.gz: e4308639e7ccb688d490d81f6e2d47ff11b125fa
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 7f5051f8e44f95e6f6597e9a6c2c3be526396c0bf97e146d0d310d857f2d4676b524636209cb2b1df00376f44779fc1d6569547de5ec91320438b3cbb7432bc1
         | 
| 7 | 
            +
              data.tar.gz: a2037e66e3937285987c138091a7959e16e807ad328120d81d61a9f794d47c5a0dcd58b5d359a33ab98ce27eca09647294060e7d1b6d763b7ab60433f16edb48
         | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,16 +1,28 @@ | |
| 1 1 | 
             
            # fluent-plugin-heroku-syslog
         | 
| 2 2 |  | 
| 3 | 
            -
            fluent plugin to drain heroku syslog.
         | 
| 3 | 
            +
            [fluent](http://fluentd.org) plugin to drain heroku syslog.
         | 
| 4 4 |  | 
| 5 5 | 
             
            [](https://travis-ci.org/hakobera/fluent-plugin-heroku-syslog)
         | 
| 6 6 |  | 
| 7 | 
            +
            ## Installation
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Install with gem or fluent-gem command as:
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            ```
         | 
| 12 | 
            +
            # for fluentd
         | 
| 13 | 
            +
            $ gem install fluent-plugin-heroku-syslog
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            # for td-agent
         | 
| 16 | 
            +
            $ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-heroku-syslog
         | 
| 17 | 
            +
            ```
         | 
| 18 | 
            +
             | 
| 7 19 | 
             
            ## Component
         | 
| 8 20 |  | 
| 9 21 | 
             
            ### HerokuSyslogInput
         | 
| 10 22 |  | 
| 11 | 
            -
            Plugin to accept syslog input from [heroku syslog drains](https://devcenter.heroku.com/articles/ | 
| 23 | 
            +
            Plugin to accept syslog input from [heroku syslog drains](https://devcenter.heroku.com/articles/log-drains#syslog-drains).
         | 
| 12 24 |  | 
| 13 | 
            -
             | 
| 25 | 
            +
            #### Configuration
         | 
| 14 26 |  | 
| 15 27 | 
             
            ```
         | 
| 16 28 | 
             
            <source>
         | 
| @@ -21,9 +33,34 @@ Plugin to accept syslog input from [heroku syslog drains](https://devcenter.hero | |
| 21 33 | 
             
            </source>
         | 
| 22 34 | 
             
            ```
         | 
| 23 35 |  | 
| 24 | 
            -
             | 
| 36 | 
            +
            ### HerokuSyslogHttpInput
         | 
| 25 37 |  | 
| 26 | 
            -
             | 
| 38 | 
            +
            Plugin to accept syslog input from [heroku http(s) drains](https://devcenter.heroku.com/articles/log-drains#http-s-drains).
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            #### Configuration
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            ##### Basic
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            ```
         | 
| 45 | 
            +
            <source>
         | 
| 46 | 
            +
              type heroku_syslog_http
         | 
| 47 | 
            +
              port 9880
         | 
| 48 | 
            +
              bind 0.0.0.0
         | 
| 49 | 
            +
              tag  heroku
         | 
| 50 | 
            +
            </source>
         | 
| 51 | 
            +
            ```
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            ##### Filter by drain_ids
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            ```
         | 
| 56 | 
            +
            <source>
         | 
| 57 | 
            +
              type heroku_syslog_http
         | 
| 58 | 
            +
              port 9880
         | 
| 59 | 
            +
              bind 0.0.0.0
         | 
| 60 | 
            +
              tag  heroku
         | 
| 61 | 
            +
              drain_ids ["YOUR-HEROKU-DRAIN-ID"]
         | 
| 62 | 
            +
            </source>
         | 
| 63 | 
            +
            ```
         | 
| 27 64 |  | 
| 28 65 | 
             
            ## Copyright
         | 
| 29 66 |  | 
| @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            # -*- encoding: utf-8 -*-
         | 
| 2 2 | 
             
            Gem::Specification.new do |gem|
         | 
| 3 3 | 
             
              gem.name          = "fluent-plugin-heroku-syslog"
         | 
| 4 | 
            -
              gem.version       = "0.0 | 
| 4 | 
            +
              gem.version       = "0.1.0"
         | 
| 5 5 | 
             
              gem.authors       = ["Kazuyuki Honda"]
         | 
| 6 6 | 
             
              gem.email         = ["hakobera@gmail.com"]
         | 
| 7 7 | 
             
              gem.description   = %q{fluent plugin to drain heroku syslog}
         | 
| @@ -14,6 +14,7 @@ Gem::Specification.new do |gem| | |
| 14 14 | 
             
              gem.test_files    = gem.files.grep(%r{^(test|spec|features)/})
         | 
| 15 15 | 
             
              gem.require_paths = ["lib"]
         | 
| 16 16 |  | 
| 17 | 
            -
              gem.add_runtime_dependency "fluentd"
         | 
| 17 | 
            +
              gem.add_runtime_dependency "fluentd", ">= 0.10.55"
         | 
| 18 18 | 
             
              gem.add_development_dependency "rake"
         | 
| 19 | 
            +
              gem.add_development_dependency("test-unit", ["~> 3.0.2"])
         | 
| 19 20 | 
             
            end
         | 
| @@ -1,221 +1,35 @@ | |
| 1 | 
            +
            require 'fluent/plugin/in_tcp'
         | 
| 2 | 
            +
            require_relative 'logplex'
         | 
| 3 | 
            +
             | 
| 1 4 | 
             
            module Fluent
         | 
| 2 | 
            -
              class HerokuSyslogInput <  | 
| 5 | 
            +
              class HerokuSyslogInput < TcpInput
         | 
| 3 6 | 
             
                Plugin.register_input('heroku_syslog', self)
         | 
| 7 | 
            +
                include Logplex
         | 
| 4 8 |  | 
| 5 | 
            -
                 | 
| 6 | 
            -
                 | 
| 7 | 
            -
                SYSLOG_ALL_REGEXP = /^\<(?<pri>[0-9]+)\>[0-9]* (?<time>[^ ]*) (?<drain_id>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*) (?<pid>[a-zA-Z0-9\.]+)? *(?<message>.*)$/
         | 
| 8 | 
            -
                TIME_FORMAT = "%Y-%m-%dT%H:%M:%S%z"
         | 
| 9 | 
            -
             | 
| 10 | 
            -
                FACILITY_MAP = {
         | 
| 11 | 
            -
                  0   => 'kern',
         | 
| 12 | 
            -
                  1   => 'user',
         | 
| 13 | 
            -
                  2   => 'mail',
         | 
| 14 | 
            -
                  3   => 'daemon',
         | 
| 15 | 
            -
                  4   => 'auth',
         | 
| 16 | 
            -
                  5   => 'syslog',
         | 
| 17 | 
            -
                  6   => 'lpr',
         | 
| 18 | 
            -
                  7   => 'news',
         | 
| 19 | 
            -
                  8   => 'uucp',
         | 
| 20 | 
            -
                  9   => 'cron',
         | 
| 21 | 
            -
                  10  => 'authpriv',
         | 
| 22 | 
            -
                  11  => 'ftp',
         | 
| 23 | 
            -
                  12  => 'ntp',
         | 
| 24 | 
            -
                  13  => 'audit',
         | 
| 25 | 
            -
                  14  => 'alert',
         | 
| 26 | 
            -
                  15  => 'at',
         | 
| 27 | 
            -
                  16  => 'local0',
         | 
| 28 | 
            -
                  17  => 'local1',
         | 
| 29 | 
            -
                  18  => 'local2',
         | 
| 30 | 
            -
                  19  => 'local3',
         | 
| 31 | 
            -
                  20  => 'local4',
         | 
| 32 | 
            -
                  21  => 'local5',
         | 
| 33 | 
            -
                  22  => 'local6',
         | 
| 34 | 
            -
                  23  => 'local7'
         | 
| 35 | 
            -
                }
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                PRIORITY_MAP = {
         | 
| 38 | 
            -
                  0  => 'emerg',
         | 
| 39 | 
            -
                  1  => 'alert',
         | 
| 40 | 
            -
                  2  => 'crit',
         | 
| 41 | 
            -
                  3  => 'err',
         | 
| 42 | 
            -
                  4  => 'warn',
         | 
| 43 | 
            -
                  5  => 'notice',
         | 
| 44 | 
            -
                  6  => 'info',
         | 
| 45 | 
            -
                  7  => 'debug'
         | 
| 46 | 
            -
                }
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                def initialize
         | 
| 49 | 
            -
                  super
         | 
| 50 | 
            -
                  require 'cool.io'
         | 
| 51 | 
            -
                  require 'fluent/plugin/socket_util'
         | 
| 52 | 
            -
                end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                config_param :port, :integer, :default => 5140
         | 
| 55 | 
            -
                config_param :bind, :string, :default => '0.0.0.0'
         | 
| 56 | 
            -
                config_param :tag, :string
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                def configure(conf)
         | 
| 59 | 
            -
                  super
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                  parser = TextParser.new
         | 
| 62 | 
            -
                  if parser.configure(conf, false)
         | 
| 63 | 
            -
                    @parser = parser
         | 
| 64 | 
            -
                  else
         | 
| 65 | 
            -
                    @parser = nil
         | 
| 66 | 
            -
                    @time_parser = TextParser::TimeParser.new(TIME_FORMAT)
         | 
| 67 | 
            -
                  end
         | 
| 68 | 
            -
                end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                def start
         | 
| 71 | 
            -
                  if @parser
         | 
| 72 | 
            -
                    callback = method(:receive_data_parser)
         | 
| 73 | 
            -
                  else
         | 
| 74 | 
            -
                    callback = method(:receive_data)
         | 
| 75 | 
            -
                  end
         | 
| 76 | 
            -
             | 
| 77 | 
            -
                  @loop = Coolio::Loop.new
         | 
| 78 | 
            -
                  @handler = listen(callback)
         | 
| 79 | 
            -
                  @loop.attach(@handler)
         | 
| 80 | 
            -
             | 
| 81 | 
            -
                  @thread = Thread.new(&method(:run))
         | 
| 82 | 
            -
                end
         | 
| 83 | 
            -
             | 
| 84 | 
            -
                def shutdown
         | 
| 85 | 
            -
                  @loop.watchers.each {|w| w.detach }
         | 
| 86 | 
            -
                  @loop.stop
         | 
| 87 | 
            -
                  @handler.close
         | 
| 88 | 
            -
                  @thread.join
         | 
| 89 | 
            -
                end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                def run
         | 
| 92 | 
            -
                  @loop.run
         | 
| 93 | 
            -
                rescue
         | 
| 94 | 
            -
                  $log.error "unexpected error", :error=>$!.to_s
         | 
| 95 | 
            -
                  $log.error_backtrace
         | 
| 96 | 
            -
                end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                protected
         | 
| 99 | 
            -
                def receive_data_parser(data)
         | 
| 100 | 
            -
                  m = SYSLOG_REGEXP.match(data)
         | 
| 101 | 
            -
                  unless m
         | 
| 102 | 
            -
                    $log.debug "invalid syslog message: #{data.dump}"
         | 
| 103 | 
            -
                    return
         | 
| 104 | 
            -
                  end
         | 
| 105 | 
            -
                  pri = m[1].to_i
         | 
| 106 | 
            -
                  text = m[2]
         | 
| 107 | 
            -
             | 
| 108 | 
            -
                  time, record = @parser.parse(text)
         | 
| 109 | 
            -
                  unless time && record
         | 
| 110 | 
            -
                    return
         | 
| 111 | 
            -
                  end
         | 
| 112 | 
            -
             | 
| 113 | 
            -
                  emit(pri, time, record)
         | 
| 114 | 
            -
             | 
| 115 | 
            -
                rescue
         | 
| 116 | 
            -
                  $log.warn data.dump, :error=>$!.to_s
         | 
| 117 | 
            -
                  $log.debug_backtrace
         | 
| 118 | 
            -
                end
         | 
| 119 | 
            -
             | 
| 120 | 
            -
                def receive_data(data)
         | 
| 121 | 
            -
                  m = SYSLOG_ALL_REGEXP.match(data)
         | 
| 122 | 
            -
                  unless m
         | 
| 123 | 
            -
                    $log.debug "invalid syslog message", :data=>data
         | 
| 124 | 
            -
                    return
         | 
| 125 | 
            -
                  end
         | 
| 126 | 
            -
             | 
| 127 | 
            -
                  pri = nil
         | 
| 128 | 
            -
                  time = nil
         | 
| 129 | 
            -
                  record = {}
         | 
| 130 | 
            -
             | 
| 131 | 
            -
                  m.names.each {|name|
         | 
| 132 | 
            -
                    if value = m[name]
         | 
| 133 | 
            -
                      case name
         | 
| 134 | 
            -
                      when "pri"
         | 
| 135 | 
            -
                        pri = value.to_i
         | 
| 136 | 
            -
                      when "time"
         | 
| 137 | 
            -
                        time = @time_parser.parse(value.gsub(/ +/, ' ').gsub(/\.[0-9]+/, ''))
         | 
| 138 | 
            -
                      else
         | 
| 139 | 
            -
                        record[name] = value
         | 
| 140 | 
            -
                      end
         | 
| 141 | 
            -
                    end
         | 
| 142 | 
            -
                  }
         | 
| 143 | 
            -
             | 
| 144 | 
            -
                  time ||= Engine.now
         | 
| 145 | 
            -
             | 
| 146 | 
            -
                  emit(pri, time, record)
         | 
| 147 | 
            -
             | 
| 148 | 
            -
                rescue
         | 
| 149 | 
            -
                  $log.warn data.dump, :error=>$!.to_s
         | 
| 150 | 
            -
                  $log.debug_backtrace
         | 
| 151 | 
            -
                end
         | 
| 9 | 
            +
                config_param :format, :string, :default => SYSLOG_REGEXP
         | 
| 10 | 
            +
                config_param :drain_ids, :array, :default => nil
         | 
| 152 11 |  | 
| 153 12 | 
             
                private
         | 
| 154 13 |  | 
| 155 | 
            -
                def  | 
| 156 | 
            -
                   | 
| 157 | 
            -
             | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
                def emit(pri, time, record)
         | 
| 161 | 
            -
                  facility = FACILITY_MAP[pri >> 3]
         | 
| 162 | 
            -
                  priority = PRIORITY_MAP[pri & 0b111]
         | 
| 163 | 
            -
             | 
| 164 | 
            -
                  tag = "#{@tag}.#{facility}.#{priority}"
         | 
| 165 | 
            -
             | 
| 166 | 
            -
                  Engine.emit(tag, time, record)
         | 
| 167 | 
            -
                rescue => e
         | 
| 168 | 
            -
                  $log.error "syslog failed to emit", :error => e.to_s, :error_class => e.class.to_s, :tag => tag, :record => Yajl.dump(record)
         | 
| 169 | 
            -
                end
         | 
| 170 | 
            -
             | 
| 171 | 
            -
                class TcpHandler < Coolio::Socket
         | 
| 172 | 
            -
                  def initialize(io, on_message)
         | 
| 173 | 
            -
                    super(io)
         | 
| 174 | 
            -
                    if io.is_a?(TCPSocket)
         | 
| 175 | 
            -
                      opt = [1, @timeout.to_i].pack('I!I!')  # { int l_onoff; int l_linger; }
         | 
| 176 | 
            -
                      io.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, opt)
         | 
| 14 | 
            +
                def on_message(msg, addr)
         | 
| 15 | 
            +
                  @parser.parse(msg) { |time, record|
         | 
| 16 | 
            +
                    unless time && record
         | 
| 17 | 
            +
                      log.warn "pattern not match: #{msg.inspect}"
         | 
| 18 | 
            +
                      return
         | 
| 177 19 | 
             
                    end
         | 
| 178 | 
            -
                    $log.trace { "accepted fluent socket object_id=#{self.object_id}" }
         | 
| 179 | 
            -
                    @on_message = on_message
         | 
| 180 | 
            -
                    @buffer = "".force_encoding('ASCII-8BIT')
         | 
| 181 | 
            -
                  end
         | 
| 182 | 
            -
             | 
| 183 | 
            -
                  def on_connect
         | 
| 184 | 
            -
                  end
         | 
| 185 20 |  | 
| 186 | 
            -
             | 
| 187 | 
            -
             | 
| 188 | 
            -
             | 
| 189 | 
            -
             | 
| 190 | 
            -
                    # syslog family add "\n" to each message and this seems only way to split messages in tcp stream
         | 
| 191 | 
            -
                    while i = @buffer.index("\n", pos)
         | 
| 192 | 
            -
                      msg = @buffer[pos..i]
         | 
| 193 | 
            -
             | 
| 194 | 
            -
                      # Support Octet Counting 
         | 
| 195 | 
            -
                      # https://tools.ietf.org/html/rfc6587#section-3.4.1
         | 
| 196 | 
            -
                      m = OCTET_COUNTING_REGEXP.match(msg)
         | 
| 197 | 
            -
                      valid = true
         | 
| 198 | 
            -
                      if m
         | 
| 199 | 
            -
                        msg_len = m[1].to_i - 1
         | 
| 200 | 
            -
                        msg = m[2]
         | 
| 201 | 
            -
             | 
| 202 | 
            -
                        if msg_len != msg.length
         | 
| 203 | 
            -
                          $log.debug "invalid syslog message length", :expected => msg_len, :actual => msg.length, :data => msg
         | 
| 204 | 
            -
                          valid = false
         | 
| 205 | 
            -
                        end
         | 
| 206 | 
            -
                      end
         | 
| 207 | 
            -
                      @on_message.call(msg) if valid
         | 
| 208 | 
            -
                      pos = i + 1
         | 
| 21 | 
            +
                    unless @drain_ids.nil? || @drain_ids.include?(record['drain_id'])
         | 
| 22 | 
            +
                      log.warn "drain_id not match: #{msg.inspect}"
         | 
| 23 | 
            +
                      return
         | 
| 209 24 | 
             
                    end
         | 
| 210 | 
            -
                    @buffer.slice!(0, pos) if pos > 0
         | 
| 211 | 
            -
                  rescue => e
         | 
| 212 | 
            -
                    $log.error "syslog error", :error => e, :error_class => e.class
         | 
| 213 | 
            -
                    close
         | 
| 214 | 
            -
                  end
         | 
| 215 25 |  | 
| 216 | 
            -
             | 
| 217 | 
            -
                     | 
| 218 | 
            -
             | 
| 26 | 
            +
                    record[@source_host_key] = addr[3] if @source_host_key
         | 
| 27 | 
            +
                    parse_logplex(record)
         | 
| 28 | 
            +
                    router.emit(@tag, time, record)
         | 
| 29 | 
            +
                  }
         | 
| 30 | 
            +
                rescue => e
         | 
| 31 | 
            +
                  log.error msg.dump, :error => e, :error_class => e.class, :host => addr[3]
         | 
| 32 | 
            +
                  log.error_backtrace
         | 
| 219 33 | 
             
                end
         | 
| 220 34 | 
             
              end
         | 
| 221 35 | 
             
            end
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            require 'fluent/plugin/in_http'
         | 
| 2 | 
            +
            require_relative 'logplex'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Fluent
         | 
| 5 | 
            +
              class HerokuSyslogHttpInput < HttpInput
         | 
| 6 | 
            +
                Plugin.register_input('heroku_syslog_http', self)
         | 
| 7 | 
            +
                include Logplex
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                config_param :format, :string, :default => SYSLOG_REGEXP
         | 
| 10 | 
            +
                config_param :drain_ids, :array, :default => nil
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                private
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def parse_params_with_parser(params)
         | 
| 15 | 
            +
                  if content = params[EVENT_RECORD_PARAMETER]
         | 
| 16 | 
            +
                    records = []
         | 
| 17 | 
            +
                    messages = content.split("\n")
         | 
| 18 | 
            +
                    messages.each do |msg|
         | 
| 19 | 
            +
                      @parser.parse(msg) { |time, record|
         | 
| 20 | 
            +
                        raise "Received event is not #{@format}: #{content}" if record.nil?
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                        record["time"] ||= time
         | 
| 23 | 
            +
                        parse_logplex(record, params)
         | 
| 24 | 
            +
                        unless @drain_ids.nil? || @drain_ids.include?(record['drain_id'])
         | 
| 25 | 
            +
                          log.warn "drain_id not match: #{msg.inspect}"
         | 
| 26 | 
            +
                          next
         | 
| 27 | 
            +
                        end
         | 
| 28 | 
            +
                        records << record
         | 
| 29 | 
            +
                      }
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                    return nil, records
         | 
| 32 | 
            +
                  else
         | 
| 33 | 
            +
                    raise "'#{EVENT_RECORD_PARAMETER}' parameter is required"
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            module Fluent
         | 
| 2 | 
            +
              module Logplex
         | 
| 3 | 
            +
                SYSLOG_REGEXP = '/^([0-9]+)\\s+\\<(?<pri>[0-9]+)\\>[0-9]* (?<time>[^ ]*) (?<drain_id>[^ ]*) (?<ident>[a-zA-Z0-9_\\/\\.\\-]*) (?<pid>[a-zA-Z0-9\\.]+)? *(?<message>.*)$/'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                FACILITY_MAP = {
         | 
| 6 | 
            +
                  0   => 'kern',
         | 
| 7 | 
            +
                  1   => 'user',
         | 
| 8 | 
            +
                  2   => 'mail',
         | 
| 9 | 
            +
                  3   => 'daemon',
         | 
| 10 | 
            +
                  4   => 'auth',
         | 
| 11 | 
            +
                  5   => 'syslog',
         | 
| 12 | 
            +
                  6   => 'lpr',
         | 
| 13 | 
            +
                  7   => 'news',
         | 
| 14 | 
            +
                  8   => 'uucp',
         | 
| 15 | 
            +
                  9   => 'cron',
         | 
| 16 | 
            +
                  10  => 'authpriv',
         | 
| 17 | 
            +
                  11  => 'ftp',
         | 
| 18 | 
            +
                  12  => 'ntp',
         | 
| 19 | 
            +
                  13  => 'audit',
         | 
| 20 | 
            +
                  14  => 'alert',
         | 
| 21 | 
            +
                  15  => 'at',
         | 
| 22 | 
            +
                  16  => 'local0',
         | 
| 23 | 
            +
                  17  => 'local1',
         | 
| 24 | 
            +
                  18  => 'local2',
         | 
| 25 | 
            +
                  19  => 'local3',
         | 
| 26 | 
            +
                  20  => 'local4',
         | 
| 27 | 
            +
                  21  => 'local5',
         | 
| 28 | 
            +
                  22  => 'local6',
         | 
| 29 | 
            +
                  23  => 'local7'
         | 
| 30 | 
            +
                }
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                PRIORITY_MAP = {
         | 
| 33 | 
            +
                  0  => 'emerg',
         | 
| 34 | 
            +
                  1  => 'alert',
         | 
| 35 | 
            +
                  2  => 'crit',
         | 
| 36 | 
            +
                  3  => 'err',
         | 
| 37 | 
            +
                  4  => 'warn',
         | 
| 38 | 
            +
                  5  => 'notice',
         | 
| 39 | 
            +
                  6  => 'info',
         | 
| 40 | 
            +
                  7  => 'debug'
         | 
| 41 | 
            +
                }
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def parse_logplex(record, params=nil)
         | 
| 44 | 
            +
                  pri = record['pri'].to_i
         | 
| 45 | 
            +
                  record['facility'] = FACILITY_MAP[pri >> 3]
         | 
| 46 | 
            +
                  record['priority'] = PRIORITY_MAP[pri & 0b111]
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  if params
         | 
| 49 | 
            +
                    record['drain_id'] = params['HTTP_LOGPLEX_DRAIN_TOKEN']
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  record
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
            end
         | 
    
        data/test/helper.rb
    CHANGED
    
    
| @@ -15,7 +15,7 @@ class HerokuSyslogInputTest < Test::Unit::TestCase | |
| 15 15 | 
             
              IPv6_CONFIG = %[
         | 
| 16 16 | 
             
                port #{PORT}
         | 
| 17 17 | 
             
                bind ::1
         | 
| 18 | 
            -
                tag syslog
         | 
| 18 | 
            +
                tag heroku.syslog
         | 
| 19 19 | 
             
              ]
         | 
| 20 20 |  | 
| 21 21 | 
             
              def create_driver(conf=CONFIG)
         | 
| @@ -43,11 +43,13 @@ class HerokuSyslogInputTest < Test::Unit::TestCase | |
| 43 43 | 
             
                  tests = [
         | 
| 44 44 | 
             
                    {
         | 
| 45 45 | 
             
                        'msg' => "92 <13>1 2014-01-29T06:25:52.589365+00:00 d.916a3e50-efa1-4754-aded-ffffffffffff app web.1 foo\n",
         | 
| 46 | 
            -
                        'expected' =>  | 
| 46 | 
            +
                        'expected' => 'foo',
         | 
| 47 | 
            +
                        'expected_time' => Time.strptime('2014-01-29T06:25:52+00:00', '%Y-%m-%dT%H:%M:%S%z').to_i
         | 
| 47 48 | 
             
                    },
         | 
| 48 49 | 
             
                    {
         | 
| 49 50 | 
             
                        'msg' => "92 <13>1 2014-01-30T07:35:00.123456+09:00 d.916a3e50-efa1-4754-aded-ffffffffffff app web.1 bar\n",
         | 
| 50 | 
            -
                        'expected' =>  | 
| 51 | 
            +
                        'expected' => 'bar',
         | 
| 52 | 
            +
                        'expected_time' => Time.strptime('2014-01-30T07:35:00+09:00', '%Y-%m-%dT%H:%M:%S%z').to_i
         | 
| 51 53 | 
             
                    }
         | 
| 52 54 | 
             
                  ]
         | 
| 53 55 |  | 
| @@ -60,12 +62,7 @@ class HerokuSyslogInputTest < Test::Unit::TestCase | |
| 60 62 | 
             
                    sleep 1
         | 
| 61 63 | 
             
                  end
         | 
| 62 64 |  | 
| 63 | 
            -
                   | 
| 64 | 
            -
                  $log.debug emits
         | 
| 65 | 
            -
                  emits.each_index {|i|
         | 
| 66 | 
            -
                    $log.debug emits[i][1]
         | 
| 67 | 
            -
                    assert_equal(tests[i]['expected'], emits[i][1])
         | 
| 68 | 
            -
                  }
         | 
| 65 | 
            +
                  compare_test_result(d.emits, tests)
         | 
| 69 66 | 
             
                }
         | 
| 70 67 | 
             
              end
         | 
| 71 68 |  | 
| @@ -101,6 +98,54 @@ class HerokuSyslogInputTest < Test::Unit::TestCase | |
| 101 98 | 
             
                compare_test_result(d.emits, tests)
         | 
| 102 99 | 
             
              end
         | 
| 103 100 |  | 
| 101 | 
            +
              def test_accept_matched_drain_id
         | 
| 102 | 
            +
                d = create_driver(CONFIG + "\ndrain_ids [\"d.916a3e50-efa1-4754-aded-ffffffffffff\"]")
         | 
| 103 | 
            +
                tests = create_test_case
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                d.run do
         | 
| 106 | 
            +
                  TCPSocket.open('127.0.0.1', PORT) do |s|
         | 
| 107 | 
            +
                    tests.each {|test|
         | 
| 108 | 
            +
                      s.send(test['msg'], 0)
         | 
| 109 | 
            +
                    }
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
                  sleep 1
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                compare_test_result(d.emits, tests)
         | 
| 115 | 
            +
              end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
              def test_accept_matched_drain_id_multiple
         | 
| 118 | 
            +
                d = create_driver(CONFIG + "\ndrain_ids [\"abc\",\"d.916a3e50-efa1-4754-aded-ffffffffffff\"]")
         | 
| 119 | 
            +
                tests = create_test_case
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                d.run do
         | 
| 122 | 
            +
                  TCPSocket.open('127.0.0.1', PORT) do |s|
         | 
| 123 | 
            +
                    tests.each {|test|
         | 
| 124 | 
            +
                      s.send(test['msg'], 0)
         | 
| 125 | 
            +
                    }
         | 
| 126 | 
            +
                  end
         | 
| 127 | 
            +
                  sleep 1
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                compare_test_result(d.emits, tests)
         | 
| 131 | 
            +
              end
         | 
| 132 | 
            +
             | 
| 133 | 
            +
              def test_ignore_unmatched_drain_id
         | 
| 134 | 
            +
                d = create_driver(CONFIG + "\ndrain_ids [\"abc\"]")
         | 
| 135 | 
            +
                tests = create_test_case
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                d.run do
         | 
| 138 | 
            +
                  TCPSocket.open('127.0.0.1', PORT) do |s|
         | 
| 139 | 
            +
                    tests.each {|test|
         | 
| 140 | 
            +
                      s.send(test['msg'], 0)
         | 
| 141 | 
            +
                    }
         | 
| 142 | 
            +
                  end
         | 
| 143 | 
            +
                  sleep 1
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                assert_equal(0, d.emits.length)
         | 
| 147 | 
            +
              end
         | 
| 148 | 
            +
             | 
| 104 149 | 
             
              def create_test_case
         | 
| 105 150 | 
             
                # actual syslog message has "\n"
         | 
| 106 151 | 
             
                msgs = [
         | 
| @@ -116,11 +161,16 @@ class HerokuSyslogInputTest < Test::Unit::TestCase | |
| 116 161 | 
             
              end
         | 
| 117 162 |  | 
| 118 163 | 
             
              def compare_test_result(emits, tests)
         | 
| 164 | 
            +
                assert_equal(tests.length, emits.length)
         | 
| 119 165 | 
             
                emits.each_index {|i|
         | 
| 120 | 
            -
                  assert_equal( | 
| 166 | 
            +
                  assert_equal('heroku.syslog', emits[i][0])
         | 
| 167 | 
            +
                  assert_equal(tests[i]['expected_time'], emits[i][1]) if tests[i]['expected_time']
         | 
| 168 | 
            +
                  assert_equal(tests[i]['expected'], emits[i][2]['message']) if tests[i]['expected']
         | 
| 121 169 | 
             
                  assert_equal('d.916a3e50-efa1-4754-aded-ffffffffffff', emits[i][2]['drain_id'])
         | 
| 122 170 | 
             
                  assert_equal('app', emits[i][2]['ident'])
         | 
| 123 171 | 
             
                  assert_equal('web.1', emits[i][2]['pid'])
         | 
| 172 | 
            +
                  assert_equal('user', emits[i][2]['facility'])
         | 
| 173 | 
            +
                  assert_equal('notice', emits[i][2]['priority'])
         | 
| 124 174 | 
             
                }
         | 
| 125 175 | 
             
              end
         | 
| 126 176 |  | 
| @@ -0,0 +1,181 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
            require 'net/http'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class HerokuSyslogHttpInputTest < Test::Unit::TestCase
         | 
| 5 | 
            +
              def setup
         | 
| 6 | 
            +
                Fluent::Test.setup
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              PORT = unused_port
         | 
| 10 | 
            +
              CONFIG = %[
         | 
| 11 | 
            +
                port #{PORT}
         | 
| 12 | 
            +
                bind 127.0.0.1
         | 
| 13 | 
            +
                body_size_limit 10m
         | 
| 14 | 
            +
                keepalive_timeout 5
         | 
| 15 | 
            +
              ]
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              def create_driver(conf=CONFIG)
         | 
| 18 | 
            +
                Fluent::Test::InputTestDriver.new(Fluent::HerokuSyslogHttpInput).configure(conf)
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              def test_configure
         | 
| 22 | 
            +
                d = create_driver
         | 
| 23 | 
            +
                assert_equal PORT, d.instance.port
         | 
| 24 | 
            +
                assert_equal '127.0.0.1', d.instance.bind
         | 
| 25 | 
            +
                assert_equal 10*1024*1024, d.instance.body_size_limit
         | 
| 26 | 
            +
                assert_equal 5, d.instance.keepalive_timeout
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def test_time_format
         | 
| 30 | 
            +
                d = create_driver
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                tests = [
         | 
| 33 | 
            +
                  {
         | 
| 34 | 
            +
                      'msg' => "<13>1 2014-01-29T06:25:52.589365+00:00 host app web.1 foo",
         | 
| 35 | 
            +
                      'expected' => 'foo',
         | 
| 36 | 
            +
                      'expected_time' => Time.strptime('2014-01-29T06:25:52+00:00', '%Y-%m-%dT%H:%M:%S%z').to_i
         | 
| 37 | 
            +
                  },
         | 
| 38 | 
            +
                  {
         | 
| 39 | 
            +
                      'msg' => "<13>1 2014-01-30T07:35:00.123456+09:00 host app web.1 bar",
         | 
| 40 | 
            +
                      'expected' => 'bar',
         | 
| 41 | 
            +
                      'expected_time' => Time.strptime('2014-01-30T07:35:00+09:00', '%Y-%m-%dT%H:%M:%S%z').to_i
         | 
| 42 | 
            +
                  }
         | 
| 43 | 
            +
                ]
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                tests.each do |msg|
         | 
| 46 | 
            +
                  msg['msg'] = "#{msg['msg'].length} #{msg['msg']}"
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                d.expect_emit 'heroku', tests[0]['expected_time'], {
         | 
| 50 | 
            +
                  "drain_id" => "d.fc6b856b-3332-4546-93de-7d0ee272c3bd",
         | 
| 51 | 
            +
                  "ident"=>"app",
         | 
| 52 | 
            +
                  "pid"=>"web.1",
         | 
| 53 | 
            +
                  "message"=> "foo",
         | 
| 54 | 
            +
                  "pri" => "13",
         | 
| 55 | 
            +
                  "facility" => "user",
         | 
| 56 | 
            +
                  "priority" => "notice"
         | 
| 57 | 
            +
                }
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                d.expect_emit 'heroku', tests[1]['expected_time'], {
         | 
| 60 | 
            +
                  "drain_id" => "d.fc6b856b-3332-4546-93de-7d0ee272c3bd",
         | 
| 61 | 
            +
                  "ident"=>"app",
         | 
| 62 | 
            +
                  "pid"=>"web.1",
         | 
| 63 | 
            +
                  "message"=> "bar",
         | 
| 64 | 
            +
                  "pri" => "13",
         | 
| 65 | 
            +
                  "facility" => "user",
         | 
| 66 | 
            +
                  "priority" => "notice"
         | 
| 67 | 
            +
                }
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                d.run do
         | 
| 70 | 
            +
                  res = post(tests)
         | 
| 71 | 
            +
                  assert_equal "200", res.code
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              def test_msg_size
         | 
| 76 | 
            +
                d = create_driver
         | 
| 77 | 
            +
                tests = create_test_case
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                d.expect_emit 'heroku', tests[0]['expected_time'], {
         | 
| 80 | 
            +
                  "drain_id" => "d.fc6b856b-3332-4546-93de-7d0ee272c3bd",
         | 
| 81 | 
            +
                  "ident" => "app",
         | 
| 82 | 
            +
                  "pid" => "web.1",
         | 
| 83 | 
            +
                  "message" => "x" * 100,
         | 
| 84 | 
            +
                  "pri" => "13",
         | 
| 85 | 
            +
                  "facility" => "user",
         | 
| 86 | 
            +
                  "priority" => "notice"
         | 
| 87 | 
            +
                }
         | 
| 88 | 
            +
                d.expect_emit 'heroku', tests[1]['expected_time'], {
         | 
| 89 | 
            +
                  "drain_id" => "d.fc6b856b-3332-4546-93de-7d0ee272c3bd",
         | 
| 90 | 
            +
                  "ident" => "app",
         | 
| 91 | 
            +
                  "pid" => "web.1",
         | 
| 92 | 
            +
                  "message" => "x" * 1024,
         | 
| 93 | 
            +
                  "pri" => "13",
         | 
| 94 | 
            +
                  "facility" => "user",
         | 
| 95 | 
            +
                  "priority" => "notice"
         | 
| 96 | 
            +
                }
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                d.run do
         | 
| 99 | 
            +
                  res = post(tests)
         | 
| 100 | 
            +
                  assert_equal "200", res.code
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
              end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
              def test_accept_matched_drain_id_multiple
         | 
| 105 | 
            +
                d = create_driver(CONFIG + "\ndrain_ids [\"abc\", \"d.fc6b856b-3332-4546-93de-7d0ee272c3bd\"]")
         | 
| 106 | 
            +
                tests = create_test_case
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                d.expect_emit 'heroku', tests[0]['expected_time'], {
         | 
| 109 | 
            +
                  "drain_id" => "d.fc6b856b-3332-4546-93de-7d0ee272c3bd",
         | 
| 110 | 
            +
                  "ident" => "app",
         | 
| 111 | 
            +
                  "pid" => "web.1",
         | 
| 112 | 
            +
                  "message" => "x" * 100,
         | 
| 113 | 
            +
                  "pri" => "13",
         | 
| 114 | 
            +
                  "facility" => "user",
         | 
| 115 | 
            +
                  "priority" => "notice"
         | 
| 116 | 
            +
                }
         | 
| 117 | 
            +
                d.expect_emit 'heroku', tests[1]['expected_time'], {
         | 
| 118 | 
            +
                  "drain_id" => "d.fc6b856b-3332-4546-93de-7d0ee272c3bd",
         | 
| 119 | 
            +
                  "ident" => "app",
         | 
| 120 | 
            +
                  "pid" => "web.1",
         | 
| 121 | 
            +
                  "message" => "x" * 1024,
         | 
| 122 | 
            +
                  "pri" => "13",
         | 
| 123 | 
            +
                  "facility" => "user",
         | 
| 124 | 
            +
                  "priority" => "notice"
         | 
| 125 | 
            +
                }
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                d.run do
         | 
| 128 | 
            +
                  res = post(tests)
         | 
| 129 | 
            +
                  assert_equal "200", res.code
         | 
| 130 | 
            +
                end
         | 
| 131 | 
            +
              end
         | 
| 132 | 
            +
             | 
| 133 | 
            +
              def test_ignore_unmatched_drain_id
         | 
| 134 | 
            +
                d = create_driver(CONFIG + "\ndrain_ids [\"abc\"]")
         | 
| 135 | 
            +
                tests = create_test_case
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                d.run do
         | 
| 138 | 
            +
                  res = post(tests)
         | 
| 139 | 
            +
                  assert_equal "200", res.code
         | 
| 140 | 
            +
                end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                assert_equal(0, d.emits.length)
         | 
| 143 | 
            +
              end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
              def create_test_case
         | 
| 146 | 
            +
                # actual syslog message has "\n"
         | 
| 147 | 
            +
                msgs = [
         | 
| 148 | 
            +
                  {
         | 
| 149 | 
            +
                    'msg' => '<13>1 2014-01-01T01:23:45.123456+00:00 host app web.1 ' + 'x' * 100,
         | 
| 150 | 
            +
                    'expected' => 'x' * 100,
         | 
| 151 | 
            +
                    'expected_time' => Time.parse("2014-01-01T01:23:45 UTC").to_i
         | 
| 152 | 
            +
                  },
         | 
| 153 | 
            +
                  {
         | 
| 154 | 
            +
                    'msg' => '<13>1 2014-01-01T01:23:45.123456+00:00 host app web.1 ' + 'x' * 1024,
         | 
| 155 | 
            +
                    'expected' => 'x' * 1024,
         | 
| 156 | 
            +
                    'expected_time' => Time.parse("2014-01-01T01:23:45 UTC").to_i
         | 
| 157 | 
            +
                  }
         | 
| 158 | 
            +
                ]
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                msgs.each do |msg|
         | 
| 161 | 
            +
                  msg['msg'] = "#{msg['msg'].length} #{msg['msg']}"
         | 
| 162 | 
            +
                end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                msgs
         | 
| 165 | 
            +
              end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
              def post(messages)
         | 
| 168 | 
            +
                # https://github.com/heroku/logplex/blob/master/doc/README.http_drains.md
         | 
| 169 | 
            +
                http = Net::HTTP.new("127.0.0.1", PORT)
         | 
| 170 | 
            +
                req = Net::HTTP::Post.new('/heroku', {
         | 
| 171 | 
            +
                  "Content-Type" => "application/logplex-1",
         | 
| 172 | 
            +
                  "Logplex-Msg-Count" => messages.length.to_s,
         | 
| 173 | 
            +
                  "Logplex-Frame-Id" => "09C557EAFCFB6CF2740EE62F62971098",
         | 
| 174 | 
            +
                  "Logplex-Drain-Token" => "d.fc6b856b-3332-4546-93de-7d0ee272c3bd",
         | 
| 175 | 
            +
                  "User-Agent" => "Logplex/v49"
         | 
| 176 | 
            +
                })
         | 
| 177 | 
            +
                req.body = messages.map {|msg| msg['msg']}.join("\n")
         | 
| 178 | 
            +
                http.request(req)
         | 
| 179 | 
            +
              end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: fluent-plugin-heroku-syslog
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0 | 
| 4 | 
            +
              version: 0.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Kazuyuki Honda
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2015-02-03 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: fluentd
         | 
| @@ -16,14 +16,14 @@ dependencies: | |
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version:  | 
| 19 | 
            +
                    version: 0.10.55
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 24 | 
             
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version:  | 
| 26 | 
            +
                    version: 0.10.55
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: rake
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -38,6 +38,20 @@ dependencies: | |
| 38 38 | 
             
                - - ">="
         | 
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 40 | 
             
                    version: '0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: test-unit
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - "~>"
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: 3.0.2
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - "~>"
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: 3.0.2
         | 
| 41 55 | 
             
            description: fluent plugin to drain heroku syslog
         | 
| 42 56 | 
             
            email:
         | 
| 43 57 | 
             
            - hakobera@gmail.com
         | 
| @@ -53,8 +67,11 @@ files: | |
| 53 67 | 
             
            - Rakefile
         | 
| 54 68 | 
             
            - fluent-plugin-heroku-syslog.gemspec
         | 
| 55 69 | 
             
            - lib/fluent/plugin/in_heroku_syslog.rb
         | 
| 70 | 
            +
            - lib/fluent/plugin/in_heroku_syslog_http.rb
         | 
| 71 | 
            +
            - lib/fluent/plugin/logplex.rb
         | 
| 56 72 | 
             
            - test/helper.rb
         | 
| 57 73 | 
             
            - test/plugin/test_in_heroku_syslog.rb
         | 
| 74 | 
            +
            - test/plugin/test_in_heroku_syslog_http.rb
         | 
| 58 75 | 
             
            homepage: https://github.com/hakobera/fluent-plugin-heroku-syslog
         | 
| 59 76 | 
             
            licenses:
         | 
| 60 77 | 
             
            - APLv2
         | 
| @@ -75,10 +92,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 75 92 | 
             
                  version: '0'
         | 
| 76 93 | 
             
            requirements: []
         | 
| 77 94 | 
             
            rubyforge_project: 
         | 
| 78 | 
            -
            rubygems_version: 2.2. | 
| 95 | 
            +
            rubygems_version: 2.2.2
         | 
| 79 96 | 
             
            signing_key: 
         | 
| 80 97 | 
             
            specification_version: 4
         | 
| 81 98 | 
             
            summary: fluent plugin to drain heroku syslog
         | 
| 82 99 | 
             
            test_files:
         | 
| 83 100 | 
             
            - test/helper.rb
         | 
| 84 101 | 
             
            - test/plugin/test_in_heroku_syslog.rb
         | 
| 102 | 
            +
            - test/plugin/test_in_heroku_syslog_http.rb
         |