logstash-output-stackify 1.0.3 → 1.0.4
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/lib/logstash/outputs/stackify.rb +127 -27
- data/lib/logstash/outputs/stackify/http_client.rb +131 -0
- data/logstash-output-stackify.gemspec +2 -1
- metadata +23 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: adaf7be7736925de7b4a9d6af06d3a0e83079c22b4b966999560eae67ec62e7d
         | 
| 4 | 
            +
              data.tar.gz: a7b120bd7de7f818acbcb9452adc4b9d2b9ef33f336a145e547f5dfe362462fa
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 69d4a6bdca008bb34313dfcb9946c403eae443314d9001c650f9798325c43dff6458c6d679448ea197d30828006f04be73cbad19a84adffb8128464d69ace3a2
         | 
| 7 | 
            +
              data.tar.gz: e9989d729f6a46c7e344b4d6d0bd60572fb051da8e25064e9dc4582ba7eacc25f4ecb4d8c67dc03403bd9e55a5d529a351ee61f2ee8d93903d0c7bcc0f951bae
         | 
| @@ -1,15 +1,37 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Core classes
         | 
| 2 4 | 
             
            require 'date'
         | 
| 3 5 | 
             
            require 'socket'
         | 
| 4 6 | 
             
            require 'json'
         | 
| 5 7 | 
             
            require 'uri'
         | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
            require "logstash/outputs/base"
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # Logstash classes
         | 
| 9 10 | 
             
            require "logstash/namespace"
         | 
| 11 | 
            +
            require "logstash/json"
         | 
| 12 | 
            +
            require "logstash/outputs/base"
         | 
| 13 | 
            +
            require "logstash/outputs/stackify/http_client"
         | 
| 14 | 
            +
             | 
| 10 15 |  | 
| 11 16 | 
             
            # Use logstash to ship logs to Stackify
         | 
| 12 17 | 
             
            class LogStash::Outputs::Stackify < LogStash::Outputs::Base
         | 
| 18 | 
            +
              include HttpClient
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              CONTENT_TYPE = "application/json".freeze
         | 
| 21 | 
            +
              MAX_ATTEMPTS = 3
         | 
| 22 | 
            +
              METHOD = :post.freeze
         | 
| 23 | 
            +
              RETRYABLE_MANTICORE_EXCEPTIONS = [
         | 
| 24 | 
            +
                  ::Manticore::Timeout,
         | 
| 25 | 
            +
                  ::Manticore::SocketException,
         | 
| 26 | 
            +
                  ::Manticore::ClientProtocolException,
         | 
| 27 | 
            +
                  ::Manticore::ResolutionFailure,
         | 
| 28 | 
            +
                  ::Manticore::SocketTimeout
         | 
| 29 | 
            +
              ].freeze
         | 
| 30 | 
            +
              RETRYABLE_CODES = [429, 500, 502, 503, 504].freeze
         | 
| 31 | 
            +
              URL = "https://api.stackify.com/Log/Save".freeze
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              concurrency :shared
         | 
| 34 | 
            +
             | 
| 13 35 | 
             
              config_name "stackify"
         | 
| 14 36 |  | 
| 15 37 | 
             
              # Your Stackify Activation Key
         | 
| @@ -39,14 +61,27 @@ class LogStash::Outputs::Stackify < LogStash::Outputs::Base | |
| 39 61 | 
             
              public
         | 
| 40 62 |  | 
| 41 63 | 
             
              def register
         | 
| 64 | 
            +
                @headers = {
         | 
| 65 | 
            +
                    "Content-Type" => CONTENT_TYPE,
         | 
| 66 | 
            +
                    "Accept" => CONTENT_TYPE,
         | 
| 67 | 
            +
                    "X-Stackify-PV" => "V1",
         | 
| 68 | 
            +
                    "X-Stackify-Key" => @key.to_s
         | 
| 69 | 
            +
                }
         | 
| 70 | 
            +
                @url = URL
         | 
| 71 | 
            +
                @logger.info("Stackify Plugin Registered")
         | 
| 42 72 | 
             
              end
         | 
| 43 73 |  | 
| 44 | 
            -
               | 
| 74 | 
            +
              def multi_receive(events)
         | 
| 75 | 
            +
                send_events(events)
         | 
| 76 | 
            +
              end
         | 
| 45 77 |  | 
| 46 | 
            -
               | 
| 78 | 
            +
              def close
         | 
| 79 | 
            +
                http_client.close
         | 
| 80 | 
            +
              end
         | 
| 47 81 |  | 
| 48 | 
            -
               | 
| 82 | 
            +
              private
         | 
| 49 83 |  | 
| 84 | 
            +
              def send_events(events)
         | 
| 50 85 | 
             
                begin
         | 
| 51 86 |  | 
| 52 87 | 
             
                  default_level = 'info'
         | 
| @@ -109,10 +144,10 @@ class LogStash::Outputs::Stackify < LogStash::Outputs::Base | |
| 109 144 | 
             
                      begin
         | 
| 110 145 | 
             
                        timestamp = (event.get('@timestamp').to_f * 1000).to_i
         | 
| 111 146 | 
             
                      rescue StandardError => e
         | 
| 112 | 
            -
                         | 
| 147 | 
            +
                        @logger.warn('Error parsing @timestamp: ' + e.to_s)
         | 
| 113 148 | 
             
                      end
         | 
| 114 149 | 
             
                      if timestamp.nil?
         | 
| 115 | 
            -
             | 
| 150 | 
            +
                        timestamp = DateTime.now.strftime('%Q')
         | 
| 116 151 | 
             
                      end
         | 
| 117 152 |  | 
| 118 153 | 
             
                      # generate key
         | 
| @@ -140,7 +175,7 @@ class LogStash::Outputs::Stackify < LogStash::Outputs::Base | |
| 140 175 | 
             
                      log_msg_groups[log_msg_group_key]['Msgs'].push(log_msg)
         | 
| 141 176 |  | 
| 142 177 | 
             
                    rescue StandardError => e
         | 
| 143 | 
            -
                       | 
| 178 | 
            +
                      @logger.warn(e.to_s)
         | 
| 144 179 | 
             
                    end
         | 
| 145 180 |  | 
| 146 181 | 
             
                  end
         | 
| @@ -149,31 +184,96 @@ class LogStash::Outputs::Stackify < LogStash::Outputs::Base | |
| 149 184 | 
             
                  log_msg_groups.each do |key, log_msg_group|
         | 
| 150 185 |  | 
| 151 186 | 
             
                    begin
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                      data = log_msg_group.to_json
         | 
| 154 | 
            -
                      header = {
         | 
| 155 | 
            -
                          'Content-Type' => 'application/json',
         | 
| 156 | 
            -
                          'Accept' => 'application/json',
         | 
| 157 | 
            -
                          'X-Stackify-PV' => 'V1',
         | 
| 158 | 
            -
                          'X-Stackify-Key' => @key.to_s
         | 
| 159 | 
            -
                      }
         | 
| 160 | 
            -
             | 
| 161 | 
            -
                      uri = URI.parse('https://api.stackify.com/Log/Save')
         | 
| 162 | 
            -
                      https = Net::HTTP.new(uri.host, uri.port)
         | 
| 163 | 
            -
                      https.use_ssl = true
         | 
| 164 | 
            -
                      req = Net::HTTP::Post.new(uri.path, initheader = header)
         | 
| 165 | 
            -
                      req.body = data
         | 
| 166 | 
            -
                      https.request(req)
         | 
| 167 | 
            -
             | 
| 187 | 
            +
                      post_log_msg_group(log_msg_group, 0)
         | 
| 168 188 | 
             
                    rescue StandardError => e
         | 
| 169 | 
            -
                       | 
| 189 | 
            +
                      @logger.warn(e.to_s)
         | 
| 170 190 | 
             
                    end
         | 
| 171 191 |  | 
| 172 192 | 
             
                  end
         | 
| 173 193 |  | 
| 174 194 | 
             
                rescue StandardError => e
         | 
| 175 | 
            -
                   | 
| 195 | 
            +
                  @logger.warn(e.to_s)
         | 
| 196 | 
            +
                end
         | 
| 197 | 
            +
             | 
| 198 | 
            +
              end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
             | 
| 201 | 
            +
              def post_log_msg_group(log_msg_group, attempt)
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                @logger.debug("Stackify Request, Attempt " + attempt.to_s)
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                if attempt > MAX_ATTEMPTS
         | 
| 206 | 
            +
                  @logger.warn(
         | 
| 207 | 
            +
                      "Max attempts exceeded, dropping events",
         | 
| 208 | 
            +
                      :attempt => attempt
         | 
| 209 | 
            +
                  )
         | 
| 210 | 
            +
                  return false
         | 
| 211 | 
            +
                end
         | 
| 212 | 
            +
             | 
| 213 | 
            +
                response =
         | 
| 214 | 
            +
                    begin
         | 
| 215 | 
            +
                      body =  log_msg_group.to_json
         | 
| 216 | 
            +
                      http_client.post(@url, :body => body, :headers => @headers)
         | 
| 217 | 
            +
                    rescue Exception => e
         | 
| 218 | 
            +
                      if retryable_exception?(e)
         | 
| 219 | 
            +
                        @logger.warn(
         | 
| 220 | 
            +
                            "Attempt #{attempt}, retryable exception when making request",
         | 
| 221 | 
            +
                            :attempt => attempt,
         | 
| 222 | 
            +
                            :class => e.class.name,
         | 
| 223 | 
            +
                            :message => e.message,
         | 
| 224 | 
            +
                            :backtrace => e.backtrace
         | 
| 225 | 
            +
                        )
         | 
| 226 | 
            +
                        return post_log_msg_group(log_msg_group, attempt + 1)
         | 
| 227 | 
            +
                      else
         | 
| 228 | 
            +
                        @logger.error(
         | 
| 229 | 
            +
                            "Attempt #{attempt}, fatal exception when making request",
         | 
| 230 | 
            +
                            :attempt => attempt,
         | 
| 231 | 
            +
                            :class => e.class.name,
         | 
| 232 | 
            +
                            :message => e.message,
         | 
| 233 | 
            +
                            :backtrace => e.backtrace
         | 
| 234 | 
            +
                        )
         | 
| 235 | 
            +
                        return false
         | 
| 236 | 
            +
                      end
         | 
| 237 | 
            +
                    end
         | 
| 238 | 
            +
             | 
| 239 | 
            +
                @logger.debug("Stackify Response: " + response.code.to_s)
         | 
| 240 | 
            +
             | 
| 241 | 
            +
                code = response.code
         | 
| 242 | 
            +
             | 
| 243 | 
            +
                if code >= 200 && code <= 299
         | 
| 244 | 
            +
                  true
         | 
| 245 | 
            +
                elsif RETRYABLE_CODES.include?(code)
         | 
| 246 | 
            +
                  @logger.warn(
         | 
| 247 | 
            +
                      "Bad retryable response from the Stackify API",
         | 
| 248 | 
            +
                      :attempt => attempt,
         | 
| 249 | 
            +
                      :code => code
         | 
| 250 | 
            +
                  )
         | 
| 251 | 
            +
                  sleep_time = sleep_for_attempt(attempt)
         | 
| 252 | 
            +
                  sleep(sleep_time)
         | 
| 253 | 
            +
                  post_log_msg_group(log_msg_group, attempt + 1)
         | 
| 254 | 
            +
                else
         | 
| 255 | 
            +
                  @logger.error(
         | 
| 256 | 
            +
                      "Bad fatal response from the Stackify API",
         | 
| 257 | 
            +
                      :attempt => attempt,
         | 
| 258 | 
            +
                      :code => code
         | 
| 259 | 
            +
                  )
         | 
| 260 | 
            +
                  false
         | 
| 176 261 | 
             
                end
         | 
| 177 262 |  | 
| 178 263 | 
             
              end
         | 
| 264 | 
            +
             | 
| 265 | 
            +
             | 
| 266 | 
            +
              def retryable_exception?(e)
         | 
| 267 | 
            +
                RETRYABLE_MANTICORE_EXCEPTIONS.any? do |exception_class|
         | 
| 268 | 
            +
                  e.is_a?(exception_class)
         | 
| 269 | 
            +
                end
         | 
| 270 | 
            +
              end
         | 
| 271 | 
            +
             | 
| 272 | 
            +
              def sleep_for_attempt(attempt)
         | 
| 273 | 
            +
                sleep_for = attempt ** 2
         | 
| 274 | 
            +
                sleep_for = sleep_for <= 60 ? sleep_for : 60
         | 
| 275 | 
            +
                (sleep_for / 2) + (rand(0..sleep_for) / 2)
         | 
| 276 | 
            +
              end
         | 
| 277 | 
            +
             | 
| 278 | 
            +
             | 
| 179 279 | 
             
            end # class LogStash::Outputs::Stackify
         | 
| @@ -0,0 +1,131 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
            require "logstash/config/mixin"
         | 
| 3 | 
            +
            require "manticore"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            # This contains the HTTP client code within it's own namespace. It is based off
         | 
| 6 | 
            +
            # of the logstash-mixin-http_client plugin.
         | 
| 7 | 
            +
            class LogStash::Outputs::Stackify < LogStash::Outputs::Base
         | 
| 8 | 
            +
              module HttpClient
         | 
| 9 | 
            +
                class InvalidHTTPConfigError < StandardError; end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def self.included(base)
         | 
| 12 | 
            +
                  base.extend(self)
         | 
| 13 | 
            +
                  base.setup_http_client_config
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def setup_http_client_config
         | 
| 17 | 
            +
                  # Timeout (in seconds) for the entire request
         | 
| 18 | 
            +
                  config :request_timeout, :validate => :number, :default => 60
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  # Timeout (in seconds) to wait for data on the socket. Default is `10s`
         | 
| 21 | 
            +
                  config :socket_timeout, :validate => :number, :default => 10
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  # Timeout (in seconds) to wait for a connection to be established. Default is `10s`
         | 
| 24 | 
            +
                  config :connect_timeout, :validate => :number, :default => 10
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  # Max number of concurrent connections. Defaults to `50`
         | 
| 27 | 
            +
                  config :pool_max, :validate => :number, :default => 50
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  # If you need to use a custom X.509 CA (.pem certs) specify the path to that here
         | 
| 30 | 
            +
                  config :cacert, :validate => :path
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  # If you'd like to use a client certificate (note, most people don't want this) set the path to the x509 cert here
         | 
| 33 | 
            +
                  config :client_cert, :validate => :path
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  # If you're using a client certificate specify the path to the encryption key here
         | 
| 36 | 
            +
                  config :client_key, :validate => :path
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  # If you need to use a custom keystore (`.jks`) specify that here. This does not work with .pem keys!
         | 
| 39 | 
            +
                  config :keystore, :validate => :path
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  # Specify the keystore password here.
         | 
| 42 | 
            +
                  # Note, most .jks files created with keytool require a password!
         | 
| 43 | 
            +
                  config :keystore_password, :validate => :password
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  # Specify the keystore type here. One of `JKS` or `PKCS12`. Default is `JKS`
         | 
| 46 | 
            +
                  config :keystore_type, :validate => :string, :default => "JKS"
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  # If you need to use a custom truststore (`.jks`) specify that here. This does not work with .pem certs!
         | 
| 49 | 
            +
                  config :truststore, :validate => :path
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  # Specify the truststore password here.
         | 
| 52 | 
            +
                  # Note, most .jks files created with keytool require a password!
         | 
| 53 | 
            +
                  config :truststore_password, :validate => :password
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  # Specify the truststore type here. One of `JKS` or `PKCS12`. Default is `JKS`
         | 
| 56 | 
            +
                  config :truststore_type, :validate => :string, :default => "JKS"
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  # If you'd like to use an HTTP proxy . This supports multiple configuration syntaxes:
         | 
| 59 | 
            +
                  #
         | 
| 60 | 
            +
                  # 1. Proxy host in form: `http://proxy.org:1234`
         | 
| 61 | 
            +
                  # 2. Proxy host in form: `{host => "proxy.org", port => 80, scheme => 'http', user => 'username@host', password => 'password'}`
         | 
| 62 | 
            +
                  # 3. Proxy host in form: `{url =>  'http://proxy.org:1234', user => 'username@host', password => 'password'}`
         | 
| 63 | 
            +
                  config :proxy
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                def build_http_client_config
         | 
| 67 | 
            +
                  c = {
         | 
| 68 | 
            +
                      connect_timeout: @connect_timeout,
         | 
| 69 | 
            +
                      socket_timeout: @socket_timeout,
         | 
| 70 | 
            +
                      request_timeout: @request_timeout,
         | 
| 71 | 
            +
                      follow_redirects: true,
         | 
| 72 | 
            +
                      automatic_retries: 1,
         | 
| 73 | 
            +
                      retry_non_idempotent: true,
         | 
| 74 | 
            +
                      check_connection_timeout: 200,
         | 
| 75 | 
            +
                      pool_max: @pool_max,
         | 
| 76 | 
            +
                      pool_max_per_route: @pool_max,
         | 
| 77 | 
            +
                      cookies: false,
         | 
| 78 | 
            +
                      keepalive: true
         | 
| 79 | 
            +
                  }
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  if @proxy
         | 
| 82 | 
            +
                    # Symbolize keys if necessary
         | 
| 83 | 
            +
                    c[:proxy] = @proxy.is_a?(Hash) ?
         | 
| 84 | 
            +
                                    @proxy.reduce({}) {|memo,(k,v)| memo[k.to_sym] = v; memo} :
         | 
| 85 | 
            +
                                    @proxy
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                  c[:ssl] = {}
         | 
| 89 | 
            +
                  if @cacert
         | 
| 90 | 
            +
                    c[:ssl][:ca_file] = @cacert
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  if @truststore
         | 
| 94 | 
            +
                    c[:ssl].merge!(
         | 
| 95 | 
            +
                        :truststore => @truststore,
         | 
| 96 | 
            +
                        :truststore_type => @truststore_type,
         | 
| 97 | 
            +
                        :truststore_password => @truststore_password.value
         | 
| 98 | 
            +
                    )
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                    if c[:ssl][:truststore_password].nil?
         | 
| 101 | 
            +
                      raise LogStash::ConfigurationError, "Truststore declared without a password! This is not valid, please set the 'truststore_password' option"
         | 
| 102 | 
            +
                    end
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  if @keystore
         | 
| 106 | 
            +
                    c[:ssl].merge!(
         | 
| 107 | 
            +
                        :keystore => @keystore,
         | 
| 108 | 
            +
                        :keystore_type => @keystore_type,
         | 
| 109 | 
            +
                        :keystore_password => @keystore_password.value
         | 
| 110 | 
            +
                    )
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                    if c[:ssl][:keystore_password].nil?
         | 
| 113 | 
            +
                      raise LogStash::ConfigurationError, "Keystore declared without a password! This is not valid, please set the 'keystore_password' option"
         | 
| 114 | 
            +
                    end
         | 
| 115 | 
            +
                  end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                  if @client_cert && @client_key
         | 
| 118 | 
            +
                    c[:ssl][:client_cert] = @client_cert
         | 
| 119 | 
            +
                    c[:ssl][:client_key] = @client_key
         | 
| 120 | 
            +
                  elsif !!@client_cert ^ !!@client_key
         | 
| 121 | 
            +
                    raise InvalidHTTPConfigError, "You must specify both client_cert and client_key for an HTTP client, or neither!"
         | 
| 122 | 
            +
                  end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                  c
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                def http_client
         | 
| 128 | 
            +
                  @http_client ||= Manticore::Client.new(build_http_client_config)
         | 
| 129 | 
            +
                end
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
            end
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Gem::Specification.new do |s|
         | 
| 2 2 | 
             
              s.name = 'logstash-output-stackify'
         | 
| 3 | 
            -
              s.version = '1.0. | 
| 3 | 
            +
              s.version = '1.0.4'
         | 
| 4 4 | 
             
              s.licenses = ['Apache License (2.0)']
         | 
| 5 5 | 
             
              s.summary = "Sends logs to Stackify"
         | 
| 6 6 | 
             
              s.description     = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
         | 
| @@ -20,6 +20,7 @@ Gem::Specification.new do |s| | |
| 20 20 |  | 
| 21 21 | 
             
              # Gem dependencies
         | 
| 22 22 | 
             
              s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
         | 
| 23 | 
            +
              s.add_runtime_dependency 'manticore', '>= 0.5.2', '< 1.0.0'
         | 
| 23 24 |  | 
| 24 25 | 
             
              s.add_development_dependency 'logstash-devutils'
         | 
| 25 26 | 
             
              s.add_development_dependency 'logstash-codec-plain'
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: logstash-output-stackify
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.0. | 
| 4 | 
            +
              version: 1.0.4
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Stackify
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2019-04- | 
| 11 | 
            +
            date: 2019-04-06 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -30,6 +30,26 @@ dependencies: | |
| 30 30 | 
             
                - - "<="
         | 
| 31 31 | 
             
                  - !ruby/object:Gem::Version
         | 
| 32 32 | 
             
                    version: '2.99'
         | 
| 33 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 34 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 35 | 
            +
                requirements:
         | 
| 36 | 
            +
                - - ">="
         | 
| 37 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 38 | 
            +
                    version: 0.5.2
         | 
| 39 | 
            +
                - - "<"
         | 
| 40 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 41 | 
            +
                    version: 1.0.0
         | 
| 42 | 
            +
              name: manticore
         | 
| 43 | 
            +
              prerelease: false
         | 
| 44 | 
            +
              type: :runtime
         | 
| 45 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 46 | 
            +
                requirements:
         | 
| 47 | 
            +
                - - ">="
         | 
| 48 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 49 | 
            +
                    version: 0.5.2
         | 
| 50 | 
            +
                - - "<"
         | 
| 51 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 52 | 
            +
                    version: 1.0.0
         | 
| 33 53 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 34 54 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 35 55 | 
             
                requirements:
         | 
| @@ -85,6 +105,7 @@ files: | |
| 85 105 | 
             
            - README.md
         | 
| 86 106 | 
             
            - docs/DEVELOPMENT.md
         | 
| 87 107 | 
             
            - lib/logstash/outputs/stackify.rb
         | 
| 108 | 
            +
            - lib/logstash/outputs/stackify/http_client.rb
         | 
| 88 109 | 
             
            - logstash-output-stackify.gemspec
         | 
| 89 110 | 
             
            - spec/outputs/stackify_spec.rb
         | 
| 90 111 | 
             
            homepage: https://www.stackify.com
         |