I am writing a logstash filter plugin. It takes a payload and generates a jwt token, and looks like this.
gentoken {
payload => {
"userid" => '%{userid}'
"role" => '%{role}'
}
secret => "3053565582"
alg => "HS256"
}
Then, a token field will be created and the event will be inserted into elasticsearch cluster.
I found that all token generated are having the same userid, role, module value that the filter is called.
e.g .
message1: foo,role1
message2: bar,role2
message3: boo,role3
All tokens generated will have 'foo' and 'role1' as the userid and role.
I followed the guide https://www.elastic.co/guide/en/logstash/current/_how_to_write_a_logstash_filter_plugin.html.
In the rb file, I have something like this
config :payload, :validate => :hash, :default => {}
'#accessing the @payload parameter and then convert it back to hash
t_payload = eval(event.sprintf(@payload))
t_payload.each do |field, value|
payload.store(event.sprintf(field), event.sprintf(value))
end
...
Please kindly help.
nww
t_payload = eval(event.sprintf(@payload))
What are you trying to accomplish here?
I am thinking of accessing @payload using event.sprintf instead of direct reference. Below is my previous attempt. But, it doesn't work.
@payload.each do |field, value|
payload.store(event.sprintf(field), event.sprintf(value))
end
Below is my complete rb file.
# encoding: utf-8
require "logstash/filters/base"
require "logstash/namespace"
require "jwt"
# This filter is created base on the example from github. It will
# generate a json web token from the given payload and base64 coded
# it. The enocded token will be add the the event 'token' field.
#
class LogStash::Filters::GenToken < LogStash::Filters::Base
# Setting the config_name here is required. This is how you
# configure this filter from your Logstash config.
#
# filter {
# gentoken {
# payload {
# "field1" => "value1"
# "field2" => "value2"
# ...
# }
# secret => "mysecret"
# alg => "HS256"
# }
# }
#
config_name "gentoken"
# Parameters
config :payload, :validate => :hash, :default => {}
config :secret, :validate => :string, :required => true
config :alg, :validate => :string, :default => "HS256"
#time lapsed before the token expired, default to 4 hours
config :lapse, :validate => :number, :default => 14400
public
def register
# Add instance variables
end # def register
public
def filter(event)
# accessing the @payload parameter and then convert it back to hash
t_payload = eval(event.sprintf(@payload))
if t_payload
# Generate JWT from the payload and base64 encoded it.
# Read all fields passed in and put it in a new hash
t_payload.each do |field, value|
@logger.debug? && @logger.debug("payload: ", :field => event.sprintf(field), :value => event.sprintf(value) )
payload.store(event.sprintf(field), event.sprintf(value))
end
#work out the token expired time
exp = Time.now.to_i + lapse
payload.store("exp", exp)
@logger.debug? && @logger.debug("payload: ", :payload => payload)
# using the event.set API
event.set("token", Base64.urlsafe_encode64(JWT.encode payload, @secret, @alg))
# correct debugging log statement for reference
# using the event.get API
@logger.debug? && @logger.debug("token is now: #{event.get("token")}")
end
# filter_matched should go in the last line of our successful code
filter_matched(event)
end # def filter
end # class LogStash::Filters::GenToken
After a few times of build and install, build and install, the codes work now... Don't know what went wrong...