2016-12-29 2 views
1

Ich habe ein benutzerdefiniertes Filter-Plugin für Logstash geschrieben, um eine Java-Klasse aufzurufen.Logstash benutzerdefinierte Eingabe-Plugin zum Aufruf Java-Klasse

Voraussetzung:

Eingang Plugin: lesen aus der Warteschlange

Benutzerdefinierte Plugin: Für jede Nachricht in der Warteschlange der Klasse Java rufen

**Code:** 

# encoding: utf-8 
require "logstash/filters/base" 
require "logstash/namespace" 
require "java" 
require "test.jar" 

class LogStash::Filters::Example < LogStash::Filters::Base 

    config_name "example" 

    public 
    def register 
    end # def register 

    public 
    def filter(event) 
     object = Java::Com.test.Test.new 
     a = object.readMessage(event.get("message")) 
     event.set("message",a) 

    filter_matched(event) 
    end # def filter 

end # class LogStash::Filters::Example 

Problem: Gibt es eine Möglichkeit dass ich die Java-Klasse nur einmal instanziieren kann? Für jede Nachricht, die ich aus der Warteschlange lese, möchte ich keine neue Instanz der Java-Klasse erstellen, sondern sie während des Logstash-Starts instantiieren und das gleiche Objekt für alle eingehenden Nachrichten verwenden.

Antwort

1

Ja. Es ist ziemlich einfach, das zu tun. Sie können eine Instanzvariable in Ihrer Ruby-Klasse erstellen, um das Java-Objekt aufzunehmen und in der register-Methode Ihrer Ruby-Klasse instanziieren. Verwenden Sie in der Filtermethode die Instanzvariable, um auf das Java-Objekt zuzugreifen.

Unten Code sollte für Sie arbeiten.

# encoding: utf-8 
require "logstash/filters/base" 
require "logstash/namespace" 
require "java" 
require "test.jar" 

class LogStash::Filters::Example < LogStash::Filters::Base 

    config_name "example" 

    public 
    def register 
    @object = Java::Com.test.Test.new 
    end # def register 

    public 
    def filter(event) 
     a = @object.readMessage(event.get("message")) 
     event.set("message",a) 
    filter_matched(event) 
    end # def filter 
end # class LogStash::Filters::Example 

Denken Sie daran, @ vor dem Variablennamen zu verwenden, es eine Instanzvariable in Ruby zu machen.

+0

Dank. Du hast meinen Tag gerettet! – minion

1

Eine Alternative wäre die Verwendung der Ruby Singleton-Klasse;

require 'singleton' 

class Logger 
    include Singleton 

    def initialize 
    @log = File.open("log.txt", "a") 
    end 

    def log(msg) 
    @log.puts(msg) 
    end 
end 

Logger.instance.log('message 2') 

können Sie tun, was Sie in der Methode initialize benötigen, und dann alle nur die Instanz der Klasse es ohne sie jedes Mal initialisiert wird immer wieder anzurufen.

Mehr unter:

1) Singleton Pattern

2) Ruby Singleton class documentation

Verwandte Themen