Custome Logstash Filter Plugin Parameter Problem


(Nww Pot Fung Nng) #1

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


(Magnus B├Ąck) #2

t_payload = eval(event.sprintf(@payload))

What are you trying to accomplish here?


(Nww Pot Fung Nng) #3

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


(Nww Pot Fung Nng) #4

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

(Nww Pot Fung Nng) #5

After a few times of build and install, build and install, the codes work now... Don't know what went wrong...


(Nww Pot Fung Nng) #6

And I only need this.

@payload.each do |field, value|
payload.store(event.sprintf(field), event.sprintf(value))
end


(system) #7

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