logstash-core 1.5.0.beta2-java
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of logstash-core might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/lib/logstash-event.rb +2 -0
- data/lib/logstash.rb +4 -0
- data/lib/logstash/JRUBY-PR1448.rb +32 -0
- data/lib/logstash/agent.rb +355 -0
- data/lib/logstash/bundler.rb +124 -0
- data/lib/logstash/codecs/base.rb +50 -0
- data/lib/logstash/config/config_ast.rb +508 -0
- data/lib/logstash/config/file.rb +39 -0
- data/lib/logstash/config/grammar.rb +3503 -0
- data/lib/logstash/config/mixin.rb +495 -0
- data/lib/logstash/config/registry.rb +13 -0
- data/lib/logstash/environment.rb +168 -0
- data/lib/logstash/errors.rb +12 -0
- data/lib/logstash/event.rb +310 -0
- data/lib/logstash/filters/base.rb +239 -0
- data/lib/logstash/gemfile.rb +175 -0
- data/lib/logstash/inputs/base.rb +137 -0
- data/lib/logstash/inputs/threadable.rb +18 -0
- data/lib/logstash/java_integration.rb +41 -0
- data/lib/logstash/json.rb +53 -0
- data/lib/logstash/logging.rb +91 -0
- data/lib/logstash/multiqueue.rb +53 -0
- data/lib/logstash/namespace.rb +17 -0
- data/lib/logstash/outputs/base.rb +124 -0
- data/lib/logstash/patches.rb +3 -0
- data/lib/logstash/patches/bugfix_jruby_2558.rb +50 -0
- data/lib/logstash/patches/cabin.rb +34 -0
- data/lib/logstash/patches/profile_require_calls.rb +47 -0
- data/lib/logstash/pipeline.rb +305 -0
- data/lib/logstash/plugin.rb +177 -0
- data/lib/logstash/pluginmanager.rb +17 -0
- data/lib/logstash/pluginmanager/install.rb +112 -0
- data/lib/logstash/pluginmanager/list.rb +38 -0
- data/lib/logstash/pluginmanager/main.rb +22 -0
- data/lib/logstash/pluginmanager/maven_tools_patch.rb +12 -0
- data/lib/logstash/pluginmanager/uninstall.rb +49 -0
- data/lib/logstash/pluginmanager/update.rb +50 -0
- data/lib/logstash/pluginmanager/util.rb +88 -0
- data/lib/logstash/program.rb +15 -0
- data/lib/logstash/runner.rb +167 -0
- data/lib/logstash/sized_queue.rb +8 -0
- data/lib/logstash/threadwatchdog.rb +37 -0
- data/lib/logstash/timestamp.rb +97 -0
- data/lib/logstash/util.rb +152 -0
- data/lib/logstash/util/accessors.rb +88 -0
- data/lib/logstash/util/buftok.rb +139 -0
- data/lib/logstash/util/charset.rb +35 -0
- data/lib/logstash/util/fieldreference.rb +68 -0
- data/lib/logstash/util/filetools.rb +185 -0
- data/lib/logstash/util/password.rb +25 -0
- data/lib/logstash/util/plugin_version.rb +43 -0
- data/lib/logstash/util/prctl.rb +11 -0
- data/lib/logstash/util/require-helper.rb +18 -0
- data/lib/logstash/util/retryable.rb +39 -0
- data/lib/logstash/util/socket_peer.rb +7 -0
- data/lib/logstash/version.rb +6 -0
- data/locales/en.yml +176 -0
- metadata +427 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/inputs/base"
|
4
|
+
|
5
|
+
# This is the threadable class for logstash inputs.
|
6
|
+
# Use this class in your inputs if it can support multiple threads
|
7
|
+
class LogStash::Inputs::Threadable < LogStash::Inputs::Base
|
8
|
+
|
9
|
+
# Set this to the number of threads you want this input to spawn.
|
10
|
+
# This is the same as declaring the input multiple times
|
11
|
+
config :threads, :validate => :number, :default => 1
|
12
|
+
|
13
|
+
def initialize(params)
|
14
|
+
super
|
15
|
+
@threadable = true
|
16
|
+
end
|
17
|
+
|
18
|
+
end # class LogStash::Inputs::Threadable
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "java"
|
2
|
+
|
3
|
+
# this is mainly for usage with JrJackson json parsing in :raw mode which genenerates
|
4
|
+
# Java::JavaUtil::ArrayList and Java::JavaUtil::LinkedHashMap native objects for speed.
|
5
|
+
# these object already quacks like their Ruby equivalents Array and Hash but they will
|
6
|
+
# not test for is_a?(Array) or is_a?(Hash) and we do not want to include tests for
|
7
|
+
# both classes everywhere. see LogStash::JSon.
|
8
|
+
|
9
|
+
class Java::JavaUtil::ArrayList
|
10
|
+
# have ArrayList objects report is_a?(Array) == true
|
11
|
+
def is_a?(clazz)
|
12
|
+
return true if clazz == Array
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Java::JavaUtil::LinkedHashMap
|
18
|
+
# have LinkedHashMap objects report is_a?(Array) == true
|
19
|
+
def is_a?(clazz)
|
20
|
+
return true if clazz == Hash
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Array
|
26
|
+
# enable class equivalence between Array and ArrayList
|
27
|
+
# so that ArrayList will work with case o when Array ...
|
28
|
+
def self.===(other)
|
29
|
+
return true if other.is_a?(Java::JavaUtil::ArrayList)
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Hash
|
35
|
+
# enable class equivalence between Hash and LinkedHashMap
|
36
|
+
# so that LinkedHashMap will work with case o when Hash ...
|
37
|
+
def self.===(other)
|
38
|
+
return true if other.is_a?(Java::JavaUtil::LinkedHashMap)
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/environment"
|
3
|
+
require "logstash/errors"
|
4
|
+
if LogStash::Environment.jruby?
|
5
|
+
require "jrjackson"
|
6
|
+
require "logstash/java_integration"
|
7
|
+
else
|
8
|
+
require "oj"
|
9
|
+
end
|
10
|
+
|
11
|
+
module LogStash
|
12
|
+
module Json
|
13
|
+
class ParserError < LogStash::Error; end
|
14
|
+
class GeneratorError < LogStash::Error; end
|
15
|
+
|
16
|
+
extend self
|
17
|
+
|
18
|
+
### MRI
|
19
|
+
|
20
|
+
def mri_load(data, options = {})
|
21
|
+
Oj.load(data)
|
22
|
+
rescue Oj::ParseError => e
|
23
|
+
raise LogStash::Json::ParserError.new(e.message)
|
24
|
+
end
|
25
|
+
|
26
|
+
def mri_dump(o)
|
27
|
+
Oj.dump(o, :mode => :compat, :use_to_json => true)
|
28
|
+
rescue => e
|
29
|
+
raise LogStash::Json::GeneratorError.new(e.message)
|
30
|
+
end
|
31
|
+
|
32
|
+
### JRuby
|
33
|
+
|
34
|
+
def jruby_load(data, options = {})
|
35
|
+
options[:symbolize_keys] ? JrJackson::Raw.parse_sym(data) : JrJackson::Raw.parse_raw(data)
|
36
|
+
rescue JrJackson::ParseError => e
|
37
|
+
raise LogStash::Json::ParserError.new(e.message)
|
38
|
+
end
|
39
|
+
|
40
|
+
def jruby_dump(o)
|
41
|
+
# test for enumerable here to work around an omission in JrJackson::Json.dump to
|
42
|
+
# also look for Java::JavaUtil::ArrayList, see TODO submit issue
|
43
|
+
o.is_a?(Enumerable) ? JrJackson::Raw.generate(o) : JrJackson::Json.dump(o)
|
44
|
+
rescue => e
|
45
|
+
raise LogStash::Json::GeneratorError.new(e.message)
|
46
|
+
end
|
47
|
+
|
48
|
+
prefix = LogStash::Environment.jruby? ? "jruby" : "mri"
|
49
|
+
alias_method :load, "#{prefix}_load".to_sym
|
50
|
+
alias_method :dump, "#{prefix}_dump".to_sym
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "cabin"
|
4
|
+
require "logger"
|
5
|
+
|
6
|
+
class LogStash::Logger
|
7
|
+
attr_accessor :target
|
8
|
+
|
9
|
+
public
|
10
|
+
def initialize(*args)
|
11
|
+
super()
|
12
|
+
|
13
|
+
#self[:program] = File.basename($0)
|
14
|
+
#subscribe(::Logger.new(*args))
|
15
|
+
@target = args[0]
|
16
|
+
@channel = Cabin::Channel.get(LogStash)
|
17
|
+
|
18
|
+
# lame hack until cabin's smart enough not to doubley-subscribe something.
|
19
|
+
# without this subscription count check, running the test suite
|
20
|
+
# causes Cabin to subscribe to STDOUT maaaaaany times.
|
21
|
+
subscriptions = @channel.instance_eval { @subscribers.count }
|
22
|
+
@channel.subscribe(@target) unless subscriptions > 0
|
23
|
+
|
24
|
+
# Set default loglevel to WARN unless $DEBUG is set (run with 'ruby -d')
|
25
|
+
@level = $DEBUG ? :debug : :warn
|
26
|
+
if ENV["LOGSTASH_DEBUG"]
|
27
|
+
@level = :debug
|
28
|
+
end
|
29
|
+
|
30
|
+
# Direct metrics elsewhere.
|
31
|
+
@channel.metrics.channel = Cabin::Channel.new
|
32
|
+
end # def initialize
|
33
|
+
|
34
|
+
# Delegation
|
35
|
+
def level=(value) @channel.level = value; end
|
36
|
+
def debug(*args); @channel.debug(*args); end
|
37
|
+
def debug?(*args); @channel.debug?(*args); end
|
38
|
+
def info(*args); @channel.info(*args); end
|
39
|
+
def info?(*args); @channel.info?(*args); end
|
40
|
+
def warn(*args); @channel.warn(*args); end
|
41
|
+
def warn?(*args); @channel.warn?(*args); end
|
42
|
+
def error(*args); @channel.error(*args); end
|
43
|
+
def error?(*args); @channel.error?(*args); end
|
44
|
+
def fatal(*args); @channel.fatal(*args); end
|
45
|
+
def fatal?(*args); @channel.fatal?(*args); end
|
46
|
+
|
47
|
+
def self.setup_log4j(logger)
|
48
|
+
require "java"
|
49
|
+
|
50
|
+
properties = java.util.Properties.new
|
51
|
+
log4j_level = "WARN"
|
52
|
+
case logger.level
|
53
|
+
when :debug
|
54
|
+
log4j_level = "DEBUG"
|
55
|
+
when :info
|
56
|
+
log4j_level = "INFO"
|
57
|
+
when :warn
|
58
|
+
log4j_level = "WARN"
|
59
|
+
end # case level
|
60
|
+
properties.setProperty("log4j.rootLogger", "#{log4j_level},logstash")
|
61
|
+
|
62
|
+
# TODO(sissel): This is a shitty hack to work around the fact that
|
63
|
+
# LogStash::Logger isn't used anymore. We should fix that.
|
64
|
+
target = logger.instance_eval { @subscribers }.values.first.instance_eval { @io }
|
65
|
+
case target
|
66
|
+
when STDOUT
|
67
|
+
properties.setProperty("log4j.appender.logstash",
|
68
|
+
"org.apache.log4j.ConsoleAppender")
|
69
|
+
properties.setProperty("log4j.appender.logstash.Target", "System.out")
|
70
|
+
when STDERR
|
71
|
+
properties.setProperty("log4j.appender.logstash",
|
72
|
+
"org.apache.log4j.ConsoleAppender")
|
73
|
+
properties.setProperty("log4j.appender.logstash.Target", "System.err")
|
74
|
+
when target.is_a?(File)
|
75
|
+
properties.setProperty("log4j.appender.logstash",
|
76
|
+
"org.apache.log4j.FileAppender")
|
77
|
+
properties.setProperty("log4j.appender.logstash.File", target.path)
|
78
|
+
else
|
79
|
+
properties.setProperty("log4j.appender.logstash", "org.apache.log4j.varia.NullAppender")
|
80
|
+
end # case target
|
81
|
+
|
82
|
+
properties.setProperty("log4j.appender.logstash.layout",
|
83
|
+
"org.apache.log4j.PatternLayout")
|
84
|
+
properties.setProperty("log4j.appender.logstash.layout.conversionPattern",
|
85
|
+
"log4j, [%d{yyyy-MM-dd}T%d{HH:mm:ss.SSS}] %5p: %c: %m%n")
|
86
|
+
|
87
|
+
org.apache.log4j.LogManager.resetConfiguration
|
88
|
+
org.apache.log4j.PropertyConfigurator.configure(properties)
|
89
|
+
logger.debug("log4j java properties setup", :log4j_level => log4j_level)
|
90
|
+
end
|
91
|
+
end # class LogStash::Logger
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "cabin"
|
4
|
+
|
5
|
+
class LogStash::MultiQueue
|
6
|
+
attr_accessor :logger
|
7
|
+
|
8
|
+
public
|
9
|
+
def initialize(*queues)
|
10
|
+
@logger = Cabin::Channel.get(LogStash)
|
11
|
+
@mutex = Mutex.new
|
12
|
+
@queues = queues
|
13
|
+
end # def initialize
|
14
|
+
|
15
|
+
public
|
16
|
+
def logger=(_logger)
|
17
|
+
@logger = _logger
|
18
|
+
|
19
|
+
# Set the logger for all known queues, too.
|
20
|
+
@queues.each do |q|
|
21
|
+
q.logger = _logger
|
22
|
+
end
|
23
|
+
end # def logger=
|
24
|
+
|
25
|
+
# Push an object to all queues.
|
26
|
+
public
|
27
|
+
def push(object)
|
28
|
+
@queues.each { |q| q.push(object) }
|
29
|
+
end # def push
|
30
|
+
alias :<< :push
|
31
|
+
|
32
|
+
alias_method :<<, :push
|
33
|
+
|
34
|
+
# Add a new Queue to this queue.
|
35
|
+
public
|
36
|
+
def add_queue(queue)
|
37
|
+
@mutex.synchronize do
|
38
|
+
@queues << queue
|
39
|
+
end
|
40
|
+
end # def add_queue
|
41
|
+
|
42
|
+
public
|
43
|
+
def remove_queue(queue)
|
44
|
+
@mutex.synchronize do
|
45
|
+
@queues.delete(queue)
|
46
|
+
end
|
47
|
+
end # def remove_queue
|
48
|
+
|
49
|
+
public
|
50
|
+
def size
|
51
|
+
return @queues.collect { |q| q.size }
|
52
|
+
end # def size
|
53
|
+
end # class LogStash::MultiQueue
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#$: << File.join(File.dirname(__FILE__), "..", "..", "vendor", "bundle")
|
3
|
+
|
4
|
+
module LogStash
|
5
|
+
module Inputs; end
|
6
|
+
module Outputs; end
|
7
|
+
module Filters; end
|
8
|
+
module Search; end
|
9
|
+
module Config; end
|
10
|
+
module File; end
|
11
|
+
module Web; end
|
12
|
+
module Util; end
|
13
|
+
module PluginMixins; end
|
14
|
+
module PluginManager; end
|
15
|
+
|
16
|
+
SHUTDOWN = :shutdown
|
17
|
+
end # module LogStash
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "cgi"
|
3
|
+
require "logstash/event"
|
4
|
+
require "logstash/logging"
|
5
|
+
require "logstash/plugin"
|
6
|
+
require "logstash/namespace"
|
7
|
+
require "logstash/config/mixin"
|
8
|
+
require "uri"
|
9
|
+
|
10
|
+
class LogStash::Outputs::Base < LogStash::Plugin
|
11
|
+
include LogStash::Config::Mixin
|
12
|
+
|
13
|
+
config_name "output"
|
14
|
+
|
15
|
+
# The type to act on. If a type is given, then this output will only
|
16
|
+
# act on messages with the same type. See any input plugin's `type`
|
17
|
+
# attribute for more.
|
18
|
+
# Optional.
|
19
|
+
config :type, :validate => :string, :default => "", :deprecated => "You can achieve this same behavior with the new conditionals, like: `if [type] == \"sometype\" { %PLUGIN% { ... } }`."
|
20
|
+
|
21
|
+
# Only handle events with all of these tags.
|
22
|
+
# Optional.
|
23
|
+
config :tags, :validate => :array, :default => [], :deprecated => "You can achieve similar behavior with the new conditionals, like: `if \"sometag\" in [tags] { %PLUGIN% { ... } }`"
|
24
|
+
|
25
|
+
# Only handle events without any of these tags.
|
26
|
+
# Optional.
|
27
|
+
config :exclude_tags, :validate => :array, :default => [], :deprecated => "You can achieve similar behavior with the new conditionals, like: `if !(\"sometag\" in [tags]) { %PLUGIN% { ... } }`"
|
28
|
+
|
29
|
+
# The codec used for output data. Output codecs are a convenient method for encoding your data before it leaves the output, without needing a separate filter in your Logstash pipeline.
|
30
|
+
config :codec, :validate => :codec, :default => "plain"
|
31
|
+
|
32
|
+
# The number of workers to use for this output.
|
33
|
+
# Note that this setting may not be useful for all outputs.
|
34
|
+
config :workers, :validate => :number, :default => 1
|
35
|
+
|
36
|
+
attr_reader :worker_plugins
|
37
|
+
|
38
|
+
public
|
39
|
+
def workers_not_supported(message=nil)
|
40
|
+
return if @workers == 1
|
41
|
+
if message
|
42
|
+
@logger.warn(I18n.t("logstash.pipeline.output-worker-unsupported-with-message", :plugin => self.class.config_name, :worker_count => @workers, :message => message))
|
43
|
+
else
|
44
|
+
@logger.warn(I18n.t("logstash.pipeline.output-worker-unsupported", :plugin => self.class.config_name, :worker_count => @workers))
|
45
|
+
end
|
46
|
+
@workers = 1
|
47
|
+
end
|
48
|
+
|
49
|
+
public
|
50
|
+
def initialize(params={})
|
51
|
+
super
|
52
|
+
config_init(params)
|
53
|
+
end
|
54
|
+
|
55
|
+
public
|
56
|
+
def register
|
57
|
+
raise "#{self.class}#register must be overidden"
|
58
|
+
end # def register
|
59
|
+
|
60
|
+
public
|
61
|
+
def receive(event)
|
62
|
+
raise "#{self.class}#receive must be overidden"
|
63
|
+
end # def receive
|
64
|
+
|
65
|
+
public
|
66
|
+
def worker_setup
|
67
|
+
if @workers == 1
|
68
|
+
@worker_plugins = [self]
|
69
|
+
else
|
70
|
+
define_singleton_method(:handle, method(:handle_worker))
|
71
|
+
@worker_queue = SizedQueue.new(20)
|
72
|
+
@worker_plugins = @workers.times.map { self.class.new(params.merge("workers" => 1, "codec" => @codec.clone)) }
|
73
|
+
@worker_plugins.map.with_index do |plugin, i|
|
74
|
+
Thread.new(original_params, @worker_queue) do |params, queue|
|
75
|
+
LogStash::Util::set_thread_name(">#{self.class.config_name}.#{i}")
|
76
|
+
plugin.register
|
77
|
+
while true
|
78
|
+
event = queue.pop
|
79
|
+
plugin.handle(event)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
public
|
87
|
+
def handle(event)
|
88
|
+
receive(event)
|
89
|
+
end # def handle
|
90
|
+
|
91
|
+
def handle_worker(event)
|
92
|
+
@worker_queue.push(event)
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
def output?(event)
|
97
|
+
if !@type.empty?
|
98
|
+
if event["type"] != @type
|
99
|
+
@logger.debug? and @logger.debug("outputs/#{self.class.name}: Dropping event because type doesn't match",
|
100
|
+
:type => @type, :event => event)
|
101
|
+
return false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
if !@tags.empty?
|
106
|
+
return false if !event["tags"]
|
107
|
+
if (event["tags"] & @tags).size != @tags.size
|
108
|
+
@logger.debug? and @logger.debug("outputs/#{self.class.name}: Dropping event because tags don't match",
|
109
|
+
:tags => @tags, :event => event)
|
110
|
+
return false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
if !@exclude_tags.empty? && event["tags"]
|
115
|
+
if (diff_tags = (event["tags"] & @exclude_tags)).size != 0
|
116
|
+
@logger.debug? and @logger.debug("outputs/#{self.class.name}: Dropping event because tags contains excluded tags",
|
117
|
+
:diff_tags => diff_tags, :exclude_tags => @exclude_tags, :event => event)
|
118
|
+
return false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
return true
|
123
|
+
end
|
124
|
+
end # class LogStash::Outputs::Base
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "logstash/environment"
|
2
|
+
|
3
|
+
if LogStash::Environment.windows? && LogStash::Environment.jruby?
|
4
|
+
require "socket"
|
5
|
+
module JRubyBug2558SocketPeerAddrBugFix
|
6
|
+
def peeraddr
|
7
|
+
orig_peeraddr.map do |v|
|
8
|
+
case v
|
9
|
+
when String
|
10
|
+
v.force_encoding(Encoding::UTF_8)
|
11
|
+
else
|
12
|
+
v
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class << Socket
|
19
|
+
# Bugfix for jruby #2558
|
20
|
+
alias_method :orig_gethostname, :gethostname
|
21
|
+
def gethostname
|
22
|
+
return orig_gethostname.force_encoding(Encoding::UTF_8)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class TCPSocket
|
27
|
+
alias_method :orig_peeraddr, :peeraddr
|
28
|
+
include JRubyBug2558SocketPeerAddrBugFix
|
29
|
+
end
|
30
|
+
class UDPSocket
|
31
|
+
alias_method :orig_peeraddr, :peeraddr
|
32
|
+
include JRubyBug2558SocketPeerAddrBugFix
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
if LogStash::Environment.windows?
|
37
|
+
# make sure all strings pulled out of ENV are UTF8
|
38
|
+
class <<ENV
|
39
|
+
alias_method :orig_getter, :[]
|
40
|
+
def [](key)
|
41
|
+
case value = orig_getter(key)
|
42
|
+
when String
|
43
|
+
# dup is necessary since force_encoding is destructive
|
44
|
+
value.dup.force_encoding(Encoding::UTF_8)
|
45
|
+
else
|
46
|
+
value
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|