Logstash Ruby not handling float value correctly

I have Kafak <> Logstash (then Ruby) <> Elastic

Kafak Input:

{"customerid":"smit","last_name":"shah","age":10,"height":10,"weight":100,"automated_email":false, "header": { "endpoint":"/pay"}, "transaction": { "amount":100.50, "currency" : "SGD"}}

Logstash:

 json {
        source => "message"
      }

 mutate {
        convert => { "amount" => "float" }
    }
	ruby {
        # Cancel 90% of events
        path => "/usr/local/etc/logstash/main.rb"
        script_params => { "percentage" => 0.9 }
      }
    }

Ruby

transaction = event.get('transaction')
		puts transaction
		puts transaction['amount']

This prints:

{"amount"=>0.1005e3, "currency"=>"SGD"}
0.1005e3

Why I am not getting 100.5?

ruby likes to print floats in exponential form. You can tell it not to using sprintf formatting strings such as %5.1f

1 Like

Thanks. Thats solved the issue partially.

I have added this: amazing_var = sprintf('%f',transaction['amount'])

It is printing 100.500000 Is it possible for it to not format to padding zero and keep exact value.

Note: It is not known the no. of decimal points in the input.

I suggest you use mutate+gsub to remove the trailing zeroes.

@Badger Here is the code I am planning on using, do you suggest any better way to write this:

amount = "1234.50000"

def filtered_amount(amount)
    decimal_amt = amount.split('.', -1)[1]
    after_index = -1
    for i in 0..decimal_amt.length - 1
        current_char = decimal_amt[i]
        if current_char == '0' && after_index == -1
            after_index = i
        elsif current_char != '0'
            after_index = -1
        end
    end
    first_part = decimal_amt[0..after_index]
    return amount.split('.', -1)[0] << "." << first_part
end

puts "Before: " << amount

puts "After: " << filtered_amount(amount)

Output:

$ruby main.rb
Before: 1234.50000
After: 1234.50

As I believe this will take up too much of processing time. Any Suggestion?

If you always want two digits after the period I would use mutate, not ruby

mutate { gsub => [ "amount", "(\.\d\d)0+", "\1" ] }

Nope, my usecase does not have a fixed length after dot. However thanks for the code snippet. Appreciate it.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.