logstash-plugins / logstash-output-influxdb

Apache License 2.0
58 stars 79 forks source link

Plugin fails on fields with boolean values #45

Open zserg8 opened 8 years ago

zserg8 commented 8 years ago

If there is field with boolean type in logstash event, influxdb plugin fails giving the following stack trace:

{:timestamp=>"2016-07-22T18:10:14.701000+0100", :message=>"Failed to flush outgoing items", :outgoing_count=>100, :exception=>"NoMethodError", :backtrace=>["/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-output-influxdb-3.1.2/lib/logstash/outputs/influxdb.rb:342:inquoted'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-output-influxdb-3.1.2/lib/logstash/outputs/influxdb.rb:227:in events_to_request_body'", "org/jruby/RubyHash.java:1342:ineach'", "org/jruby/RubyEnumerable.java:757:in map'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-output-influxdb-3.1.2/lib/logstash/outputs/influxdb.rb:227:inevents_to_request_body'", "org/jruby/RubyArray.java:2414:in map'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-output-influxdb-3.1.2/lib/logstash/outputs/influxdb.rb:224:inevents_to_request_body'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-output-influxdb-3.1.2/lib/logstash/outputs/influxdb.rb:171:in flush'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/stud-0.0.22/lib/stud/buffer.rb:221:inbuffer_flush'", "org/jruby/RubyHash.java:1342:in each'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/stud-0.0.22/lib/stud/buffer.rb:216:inbuffer_flush'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/stud-0.0.22/lib/stud/buffer.rb:193:in buffer_flush'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/stud-0.0.22/lib/stud/buffer.rb:159:inbuffer_receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-output-influxdb-3.1.2/lib/logstash/outputs/influxdb.rb:165:in receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.3.3-java/lib/logstash/outputs/base.rb:83:inmulti_receive'", "org/jruby/RubyArray.java:1613:in each'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.3.3-java/lib/logstash/outputs/base.rb:83:inmulti_receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.3.3-java/lib/logstash/output_delegator.rb:130:in worker_multi_receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.3.3-java/lib/logstash/output_delegator.rb:114:inmulti_receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.3.3-java/lib/logstash/pipeline.rb:301:in output_batch'", "org/jruby/RubyHash.java:1342:ineach'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.3.3-java/lib/logstash/pipeline.rb:301:in output_batch'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.3.3-java/lib/logstash/pipeline.rb:232:inworker_loop'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.3.3-java/lib/logstash/pipeline.rb:201:in start_workers'"], :level=>:warn}

This happens only with messages containing boolean fields. See "compr_on" below:

{
                   "message" => "<compressor> 2016-06-23T06:39:11.091+0100;true;0;7.29;0;287.62;0;299.56\r",
                "@timestamp" => "2016-06-23T05:39:11.091Z",
                      "host" => "172.30.156.217",
                    "source" => "compressor",
                  "compr_on" => true,
    "waterflow_sensor_state" => "0",
                 "waterflow" => "7.29",
    "watertemp_sensor_state" => "0",
         "water_temperature" => "287.62",
           "rt_sensor_state" => "0",
                        "rt" => "299.56"
}

this conversion, in turn, is generated by the following logstash config line:

        mutate {
            remove_field => ["port", "@version"]
            convert => { "compr_on" => "boolean" }
        }

Simply commenting out convert lines eliminates the error.

InfluxDB-relevant part of logstash config is:

influxdb {
                #Connection configuration
                host => "localhost"
                port => "8086"
                user => "logstash"
                password => "password"
                db => "dbname"

                #Data configuration
                measurement => "measurement"
                idle_flush_time => "1"
                use_event_fields_for_data_points => "true"
                send_as_tags => ["host", "source"]
            }
reinhard-brandstaedter commented 8 years ago

I can confirm this behavior I have the same problem.

reinhard-brandstaedter commented 8 years ago

A quick fix should be in influxdb.rb code, the escaped funtions are not safe for boolean types sou you need to check:

# Escape tag key, tag value, or field key
def escaped(value)
      !!value == value ? value : value.gsub(/[ ,=]/, ' ' => '\ ', ',' => '\,', '=' => '\=')
end

# Escape measurements note they don't need to worry about the '=' case
def escaped_measurement(value)
  !!value == value ? value : value.gsub(/[ ,]/, ' ' => '\ ', ',' => '\,')
end