Writing a Logstash GEM gives an error: undefined local variable or method - ruby

Trying to build a gem to use it for Logstash as a filter. I'm using classes and methods from a .jar file.
The following is my Jruby code so far:
# encoding: utf-8
require "logstash/filters/base"
require "logstash/namespace"
require 'java'
require 'Processing.jar'
java_import 'process.Process'
class LogStash::Filters::Process < LogStash::Filters::Base
config_name "process"
StringPath = "/path/to/file/"
ML = JavaUtilities.get_proxy_class('processing.Processing')
#ML = ML.new(StringPath)
public
def register
end
public
def filter(event)
event["result"] = #ML.Process("any string.")
filter_matched(event)
end
end
However, it gave me the following error:
←[31mException in filterworker, the pipeline stopped processing new events, plea
se check your filter configuration and restart Logstash. {"exception"=>#<NoMetho
dError: undefined method 'Process' for nil:NilClass>, "backtrace"=>[
"/path/to/logstash-2.0.0/vendor/local_gems
/dda91dc0/logstash-filter-Process-0.5.0/lib/logstash/filters/processing.rb:54:in 'filter'", "/path/to/log
stash-2.0.0/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/f
ilters/base.rb:152:in 'multi_filter'", "org/jruby/RubyArray.java:1613:in 'each'"
, "/path/to/logstash-2.0.0/vendor/bundle/j
ruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/filters/base.rb:149:in 'mult
i_filter'", "(eval):233:in 'filter_func'", "/path/to/logstash-2.0.0/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/
lib/logstash/pipeline.rb:219:in 'filterworker'", "path/to/log/logstash-2.0.0/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0
-java/lib/logstash/pipeline.rb:154:in 'start_filters'"], :level=>:error}←[0m
NoMethodError: undefined method 'Process' for nil:NilClass
filter at /path/to/logstash-2.0.0
/vendor/local_gems/dda91dc0/logstash-filter-Process-0.5.0/lib/logstash
/filters/Process.rb:54
multi_filter at /path/to/logstash-2.0.0
/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/filters/base
.rb:152
each at org/jruby/RubyArray.java:1613
multi_filter at /path/to/logstash-2.0.0
/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/filters/base
.rb:149
filter_func at (eval):233
filterworker at /path/to/logstash-2.0.0
/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/pipeline.rb:
219
start_filters at /path/to/logstash-2.0.0
/vendor/bundle/jruby/1.9/gems/logstash-core-2.0.0-java/lib/logstash/pipeline.rb:
154
I tried the following:
.
.
.
public
def filter(event)
StringPath = "/path/to/file/"
ML = JavaUtilities.get_proxy_class('processing.Processing')
#ML = ML.new(StringPath)
event["result"] = #ML.Process("any string.")
filter_matched(event)
end
end
But it gave me the error:
SyntaxError: dynamic constant assignment error.
I tried this in a normal jruby file and everything worked with me. Using Logstash's filter however is what seems to be giving me an issue here.

It seems you are struggling with local and instance variables in Ruby. Please see this blog post for more information.
When you call event["result"] = ML.Process(event["text"]) ruby tries to find a local variable named ML which doesn't exist. Therefore you get undefined local variable or method ML.Process(event["text"]). So, messing around with your variables might solve your problem.
#ML is an instance variable and is available in all methods calling it using #ML or self.ML. Please try this:
public
def filter(event)
event["result"] = #ML.Process(event["text"])
filter_matched(event)
end
Things I stumbled upon:
Where do MLVectorPath and MLStopWordPath come from?
What is StringPath? It is assigned but never used.
Do you have a field text? Otherwise change event["text"] into event["message"].
However, I know neither your Java code nor your logstash configuration so these things may be okay. Please let me know if this helps.

Related

Undefined method `collection' for #<Mongo::Client> Did you mean? collections (NoMethodError). Ruby

I am working with automated test. This is the first time I'm working with mongoDB.
So, I am trying to create a generic method to find a document in a desired collection that will be passed as parameter. I've found some examples and all of them use the .collection method. It doesn't seem to work in my project.
Here's my DB client code:
require 'mongo'
require 'singleton'
class DBClient
include Singleton
def initialize
#db_connection = Mongo::Client.new($env['database']['feature']['url'])
end
def find(collection, value)
coll = #db_connection.collection(collection)
coll.find(owner: 'value')
end
end
And here's how I instance my method
DBClient.instance.find('collectionTest', 'Jhon')
When I run my test I get the following message:
undefined method `collection' for #<Mongo::Client: cluster=localhost:>
Did you mean? collections (NoMethodError)
The gem I'm using is mongo (2.6.1).
What I am doing wrong?
Based on documentation, there is indeed no method collection in Mongo::Client. What you are looking for is the [] method. The code will then look like this:
require 'mongo'
require 'singleton'
class DBClient
include Singleton
def initialize
#db_connection = Mongo::Client.new($env['database']['feature']['url'])
end
def find(collection, value)
coll = #db_connection[collection]
coll.find(owner: value)
end
end
EDIT: I've also changed the line with the find itself. In your original code, it would find documents where owner is 'value' string. I presume you want the documents where owner matches the value send to the function.

Undefined local variable or method `translator' for main:Object (NameError)

I've used a gem and tried to create a method (trans) in my code.
require 'yandex-translator'
translator = Yandex::Translator.new(api_key)
def trans(text)
a = translator.translate text, to: "ru"
return a
end
puts trans("stack")
When I run the code, I get this error:
'trans': undefined local variable or method `translator' for main:Object (NameError)
Why did I get this error, and how can I solve this?
translator variable in this code is defined on class level, hence it’s a local variable in main context (since the whole code is executed in main context.)
You are trying to call it from the instance context, where it is obviously not defined. The easiest way to overcome it, would be to define #translator as being a class’ instance variable:
#translator = Yandex::Translator.new(api_key)
def trans(text)
#translator.translate text, to: "ru"
end
Because in this way you are looking for a local variable translator and you have not. Some solutions:
make translator global
$translator = Yandex::Translator.new(api_key)
or pass translator to trans method
def trans(translator, text)
translator.translate text, to: "ru"
end

I have a Ruby undefined local variable or method error

When I try to run this code:
class Message
##messages_sent = 0
def initialize(from, to)
#from = from
#to = to
##messages_sent += 1
end
end
my_message = Message.new(chicago, tokyo)
I get an error that tells me that one of my parameters is undefined local variable. I was just trying to create an instance using Message, and was curious as to why this was not working. I thought this would work as I am calling the class.
Problem
With your current code, you get this error:
undefined local variable or method `chicago' for main:Object (NameError)
because the way you instantiated the Message class:
my_message = Message.new(chicago, tokyo)
chicago and tokyo are interpreted as variable or method that you did not actually define or declare, that's why you got that error.
Solution
I think, you just wanted to pass two string objects (putting chicago and tokyo in the quotes) as the arguments of Message.new call like this:
my_message = Message.new('chicago', 'tokyo')
This will solve your problem.
Hope this makes it clear why you are getting the error and how to solve the problem.
The 'undefined local variable' error is showing up because there's no value associated with chicago or tokyo. If you want to just pass them as strings, wrap them in quotation marks instead, like this:
class Message
##messages_sent = 0
def initialize(from, to)
#from = from
#to = to
##messages_sent += 1
end
end
my_message = Message.new("chicago", "tokyo")

Why isn't this simple Ruby code working in HAML?

If I run this simple Ruby code regularly, it works fine:
class String
def add_two
self + "2"
end
end
puts "hello".add_two
It prints "hello2" as it should. But this fails:
:ruby
class String
def add_two
self + "2"
end
end
puts "hello".add_two
This code produces an error:
NoMethodError at /
undefined method `add_two' for "hello":String
Any ideas what's wrong?
(Not sure if it matters, but I'm using HAML with Sinatra, which is running on Apache with the Passenger module.)
I would suggest that String is in another namespace and therefor another class.
What happens with that?
class ::String
I put your code as is into one of my Haml views in a Rails app and I got a different error to you:
SyntaxError at /
class definition in method body
So I wondered whether it was Haml's :ruby filter that was complaining, but since it "Parses the filtered text with the normal Ruby interpreter", it seemed unlikely. So, I searched for more info about the error and found references (see below) that led me to this, which works (but, really, should never be used):
:ruby
String.module_eval do
def add_two
self + "2"
end
end
puts "hello".add_two
References:
Class inside a Method Body
Class (Re)definition in Method Body

Unable to override read method URI::HTTP

I am trying to stub the following:
uri = URI(base_url)
source = uri.read
I have re-written the read method as follows:
equire 'open-uri'
module OpenURI
module OpenRead
def read
return IO.read('source.html')
end
end
end
But it doesn't seem to work. New to ruby and could use some pointers. I always seem to end up with
NoMethodError: undefined method `read' for #<URI::HTTP:0x10ac59918>
uri = URI(base_url)
source = uri.read
You use the read method, so take a look where it is:
uri.method(:read).method_location
If you want to know where to override, go for
uri.method(:read).owner
or simply
def uri.read
<your body>
end

Resources