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,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/util"
|
4
|
+
|
5
|
+
class LogStash::Util::Charset
|
6
|
+
attr_accessor :logger
|
7
|
+
|
8
|
+
def initialize(charset)
|
9
|
+
@charset = charset
|
10
|
+
@charset_encoding = Encoding.find(charset)
|
11
|
+
end
|
12
|
+
|
13
|
+
def convert(data)
|
14
|
+
data.force_encoding(@charset_encoding)
|
15
|
+
|
16
|
+
# NON UTF-8 charset declared.
|
17
|
+
# Let's convert it (as cleanly as possible) into UTF-8 so we can use it with JSON, etc.
|
18
|
+
return data.encode(Encoding::UTF_8, :invalid => :replace, :undef => :replace) unless @charset_encoding == Encoding::UTF_8
|
19
|
+
|
20
|
+
# UTF-8 charset declared.
|
21
|
+
# Some users don't know the charset of their logs or just don't know they
|
22
|
+
# can set the charset setting.
|
23
|
+
unless data.valid_encoding?
|
24
|
+
# A silly hack to help convert some of the unknown bytes to
|
25
|
+
# somewhat-readable escape codes. The [1..-2] is to trim the quotes
|
26
|
+
# ruby puts on the value.
|
27
|
+
return data.inspect[1..-2].tap do |escaped|
|
28
|
+
@logger.warn("Received an event that has a different character encoding than you configured.", :text => escaped, :expected_charset => @charset)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
return data
|
33
|
+
end # def convert
|
34
|
+
|
35
|
+
end # class LogStash::Util::Charset
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/util"
|
4
|
+
|
5
|
+
module LogStash::Util::FieldReference
|
6
|
+
|
7
|
+
def compile(accessor)
|
8
|
+
if accessor[0,1] != '['
|
9
|
+
return <<-"CODE"
|
10
|
+
lambda do |store, &block|
|
11
|
+
return block.nil? ? store[#{accessor.inspect}] : block.call(store, #{accessor.inspect})
|
12
|
+
end
|
13
|
+
CODE
|
14
|
+
end
|
15
|
+
|
16
|
+
code = "lambda do |store, &block|\n"
|
17
|
+
selectors = accessor.scan(/(?<=\[).+?(?=\])/)
|
18
|
+
selectors.each_with_index do |tok, i|
|
19
|
+
last = (i == selectors.count() - 1)
|
20
|
+
code << " # [#{tok}]#{ last ? " (last selector)" : "" }\n"
|
21
|
+
|
22
|
+
if last
|
23
|
+
code << <<-"CODE"
|
24
|
+
return block.call(store, #{tok.inspect}) unless block.nil?
|
25
|
+
CODE
|
26
|
+
end
|
27
|
+
|
28
|
+
code << <<-"CODE"
|
29
|
+
store = store.is_a?(Array) ? store[#{tok.to_i}] : store[#{tok.inspect}]
|
30
|
+
return store if store.nil?
|
31
|
+
CODE
|
32
|
+
|
33
|
+
end
|
34
|
+
code << "return store\nend"
|
35
|
+
#puts code
|
36
|
+
return code
|
37
|
+
end # def compile
|
38
|
+
|
39
|
+
def exec(accessor, store, &block)
|
40
|
+
@__fieldeval_cache ||= {}
|
41
|
+
@__fieldeval_cache[accessor] ||= eval(compile(accessor))
|
42
|
+
return @__fieldeval_cache[accessor].call(store, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def set(accessor, value, store)
|
46
|
+
# The assignment can fail if the given field reference (accessor) does not exist
|
47
|
+
# In this case, we'll want to set the value manually.
|
48
|
+
if exec(accessor, store) { |hash, key| hash[key] = value }.nil?
|
49
|
+
return (store[accessor] = value) if accessor[0,1] != "["
|
50
|
+
|
51
|
+
# No existing element was found, so let's set one.
|
52
|
+
*parents, key = accessor.scan(/(?<=\[)[^\]]+(?=\])/)
|
53
|
+
parents.each do |p|
|
54
|
+
if store.include?(p)
|
55
|
+
store = store[p]
|
56
|
+
else
|
57
|
+
store[p] = {}
|
58
|
+
store = store[p]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
store[key] = value
|
62
|
+
end
|
63
|
+
|
64
|
+
return value
|
65
|
+
end
|
66
|
+
|
67
|
+
extend self
|
68
|
+
end # module LogStash::Util::FieldReference
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "uri"
|
3
|
+
require "digest/sha1"
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module LogStash::Util::FileTools
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def fetch(url, sha1, output)
|
10
|
+
|
11
|
+
puts "Downloading #{url}"
|
12
|
+
actual_sha1 = download(url, output)
|
13
|
+
|
14
|
+
if actual_sha1 != sha1
|
15
|
+
fail "SHA1 does not match (expected '#{sha1}' but got '#{actual_sha1}')"
|
16
|
+
end
|
17
|
+
end # def fetch
|
18
|
+
|
19
|
+
def file_fetch(url, sha1, target)
|
20
|
+
filename = File.basename( URI(url).path )
|
21
|
+
output = "#{target}/#{filename}"
|
22
|
+
begin
|
23
|
+
actual_sha1 = file_sha1(output)
|
24
|
+
if actual_sha1 != sha1
|
25
|
+
fetch(url, sha1, output)
|
26
|
+
end
|
27
|
+
rescue Errno::ENOENT
|
28
|
+
fetch(url, sha1, output)
|
29
|
+
end
|
30
|
+
return output
|
31
|
+
end
|
32
|
+
|
33
|
+
def file_sha1(path)
|
34
|
+
digest = Digest::SHA1.new
|
35
|
+
fd = File.new(path, "r")
|
36
|
+
while true
|
37
|
+
begin
|
38
|
+
digest << fd.sysread(16384)
|
39
|
+
rescue EOFError
|
40
|
+
break
|
41
|
+
end
|
42
|
+
end
|
43
|
+
return digest.hexdigest
|
44
|
+
ensure
|
45
|
+
fd.close if fd
|
46
|
+
end
|
47
|
+
|
48
|
+
def download(url, output)
|
49
|
+
uri = URI(url)
|
50
|
+
digest = Digest::SHA1.new
|
51
|
+
tmp = "#{output}.tmp"
|
52
|
+
Net::HTTP.start(uri.host, uri.port, :use_ssl => (uri.scheme == "https")) do |http|
|
53
|
+
request = Net::HTTP::Get.new(uri.path)
|
54
|
+
http.request(request) do |response|
|
55
|
+
fail "HTTP fetch failed for #{url}. #{response}" if [200, 301].include?(response.code)
|
56
|
+
size = (response["content-length"].to_i || -1).to_f
|
57
|
+
count = 0
|
58
|
+
File.open(tmp, "w") do |fd|
|
59
|
+
response.read_body do |chunk|
|
60
|
+
fd.write(chunk)
|
61
|
+
digest << chunk
|
62
|
+
if size > 0 && $stdout.tty?
|
63
|
+
count += chunk.bytesize
|
64
|
+
$stdout.write(sprintf("\r%0.2f%%", count/size * 100))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
$stdout.write("\r \r") if $stdout.tty?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
File.rename(tmp, output)
|
73
|
+
|
74
|
+
return digest.hexdigest
|
75
|
+
rescue SocketError => e
|
76
|
+
puts "Failure while downloading #{url}: #{e}"
|
77
|
+
raise
|
78
|
+
ensure
|
79
|
+
File.unlink(tmp) if File.exist?(tmp)
|
80
|
+
end # def download
|
81
|
+
|
82
|
+
def untar(tarball, &block)
|
83
|
+
require "archive/tar/minitar"
|
84
|
+
tgz = Zlib::GzipReader.new(File.open(tarball))
|
85
|
+
# Pull out typesdb
|
86
|
+
tar = Archive::Tar::Minitar::Input.open(tgz)
|
87
|
+
tar.each do |entry|
|
88
|
+
path = block.call(entry)
|
89
|
+
next if path.nil?
|
90
|
+
parent = File.dirname(path)
|
91
|
+
|
92
|
+
FileUtils.mkdir_p(parent) unless File.directory?(parent)
|
93
|
+
|
94
|
+
# Skip this file if the output file is the same size
|
95
|
+
if entry.directory?
|
96
|
+
FileUtils.mkdir_p(path) unless File.directory?(path)
|
97
|
+
else
|
98
|
+
entry_mode = entry.instance_eval { @mode } & 0777
|
99
|
+
if File.exists?(path)
|
100
|
+
stat = File.stat(path)
|
101
|
+
# TODO(sissel): Submit a patch to archive-tar-minitar upstream to
|
102
|
+
# expose headers in the entry.
|
103
|
+
entry_size = entry.instance_eval { @size }
|
104
|
+
# If file sizes are same, skip writing.
|
105
|
+
next if stat.size == entry_size && (stat.mode & 0777) == entry_mode
|
106
|
+
end
|
107
|
+
puts "Extracting #{entry.full_name} from #{tarball} #{entry_mode.to_s(8)}"
|
108
|
+
File.open(path, "w") do |fd|
|
109
|
+
# eof? check lets us skip empty files. Necessary because the API provided by
|
110
|
+
# Archive::Tar::Minitar::Reader::EntryStream only mostly acts like an
|
111
|
+
# IO object. Something about empty files in this EntryStream causes
|
112
|
+
# IO.copy_stream to throw "can't convert nil into String" on JRuby
|
113
|
+
# TODO(sissel): File a bug about this.
|
114
|
+
while !entry.eof?
|
115
|
+
chunk = entry.read(16384)
|
116
|
+
fd.write(chunk)
|
117
|
+
end
|
118
|
+
#IO.copy_stream(entry, fd)
|
119
|
+
end
|
120
|
+
File.chmod(entry_mode, path)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
tar.close
|
124
|
+
File.unlink(tarball) if File.file?(tarball)
|
125
|
+
end # def untar
|
126
|
+
|
127
|
+
def do_ungz(file)
|
128
|
+
|
129
|
+
outpath = file.gsub('.gz', '')
|
130
|
+
tgz = Zlib::GzipReader.new(File.open(file))
|
131
|
+
begin
|
132
|
+
File.open(outpath, "w") do |out|
|
133
|
+
IO::copy_stream(tgz, out)
|
134
|
+
end
|
135
|
+
File.unlink(file)
|
136
|
+
rescue
|
137
|
+
File.unlink(outpath) if File.file?(outpath)
|
138
|
+
raise
|
139
|
+
end
|
140
|
+
tgz.close
|
141
|
+
end
|
142
|
+
|
143
|
+
def eval_file(entry, files, prefix)
|
144
|
+
return false if entry.full_name =~ /PaxHeaders/
|
145
|
+
if !files.nil?
|
146
|
+
if files.is_a?(Array)
|
147
|
+
return false unless files.include?(entry.full_name.gsub(prefix, ''))
|
148
|
+
entry.full_name.split("/").last
|
149
|
+
elsif files.is_a?(String)
|
150
|
+
return false unless entry.full_name =~ Regexp.new(files)
|
151
|
+
entry.full_name.split("/").last
|
152
|
+
end
|
153
|
+
else
|
154
|
+
entry.full_name.gsub(prefix, '')
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def process_downloads(files,target='')
|
159
|
+
|
160
|
+
FileUtils.mkdir_p(target) unless File.directory?(target)
|
161
|
+
|
162
|
+
files.each do |file|
|
163
|
+
download = file_fetch(file['url'], file['sha1'],target)
|
164
|
+
|
165
|
+
if download =~ /.tar.gz/
|
166
|
+
prefix = download.gsub('.tar.gz', '').gsub("#{target}/", '')
|
167
|
+
untar(download) do |entry|
|
168
|
+
next unless out = eval_file(entry, file['files'], prefix)
|
169
|
+
File.join(target, out)
|
170
|
+
end
|
171
|
+
|
172
|
+
elsif download =~ /.tgz/
|
173
|
+
prefix = download.gsub('.tgz', '').gsub("#{target}/", '')
|
174
|
+
untar(download) do |entry|
|
175
|
+
next unless out = eval_file(entry, file['files'], prefix)
|
176
|
+
File.join(target, out)
|
177
|
+
end
|
178
|
+
|
179
|
+
elsif download =~ /.gz/
|
180
|
+
do_ungz(download)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/util"
|
4
|
+
|
5
|
+
# This class exists to quietly wrap a password string so that, when printed or
|
6
|
+
# logged, you don't accidentally print the password itself.
|
7
|
+
class LogStash::Util::Password
|
8
|
+
attr_reader :value
|
9
|
+
|
10
|
+
public
|
11
|
+
def initialize(password)
|
12
|
+
@value = password
|
13
|
+
end # def initialize
|
14
|
+
|
15
|
+
public
|
16
|
+
def to_s
|
17
|
+
return "<password>"
|
18
|
+
end # def to_s
|
19
|
+
|
20
|
+
public
|
21
|
+
def inspect
|
22
|
+
return to_s
|
23
|
+
end # def inspect
|
24
|
+
end # class LogStash::Util::Password
|
25
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'logstash/errors'
|
2
|
+
require 'rubygems/version'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module LogStash::Util
|
6
|
+
class PluginVersion
|
7
|
+
extend Forwardable
|
8
|
+
include Comparable
|
9
|
+
|
10
|
+
GEM_NAME_PREFIX = 'logstash'
|
11
|
+
|
12
|
+
def_delegators :@version, :to_s
|
13
|
+
attr_reader :version
|
14
|
+
|
15
|
+
def initialize(*options)
|
16
|
+
if options.size == 1 && options.first.is_a?(Gem::Version)
|
17
|
+
@version = options.first
|
18
|
+
else
|
19
|
+
@version = Gem::Version.new(options.join('.'))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.find_version!(name)
|
24
|
+
begin
|
25
|
+
specification = Gem::Specification.find_by_name(name)
|
26
|
+
new(specification.version)
|
27
|
+
rescue Gem::LoadError
|
28
|
+
# Rescuing the LoadError and raise a Logstash specific error.
|
29
|
+
# Likely we can't find the gem in the current GEM_PATH
|
30
|
+
raise LogStash::PluginNoVersionError
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.find_plugin_version!(type, name)
|
35
|
+
plugin_name = [GEM_NAME_PREFIX, type, name].join('-')
|
36
|
+
find_version!(plugin_name)
|
37
|
+
end
|
38
|
+
|
39
|
+
def <=>(other)
|
40
|
+
version <=> other.version
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/logging"
|
4
|
+
|
5
|
+
module LogStash::Util::Require
|
6
|
+
class << self
|
7
|
+
attr_accessor :logger
|
8
|
+
|
9
|
+
def require(lib, gemdep, message=nil)
|
10
|
+
@logger ||= LogStash::Logger.new(STDERR)
|
11
|
+
begin
|
12
|
+
require lib
|
13
|
+
rescue LoadError => e
|
14
|
+
@logger.error("Failed loading '#{lib}'")
|
15
|
+
end
|
16
|
+
end # def require
|
17
|
+
end # class << self
|
18
|
+
end # def LogStash::Util::Require
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module LogStash
|
2
|
+
module Retryable
|
3
|
+
# execute retryable code block
|
4
|
+
# @param [Hash] options retryable options
|
5
|
+
# @option options [Fixnum] :tries retries to perform, default 1, set to 0 for infite retries. 1 means that upon exception the block will be retried once
|
6
|
+
# @option options [Fixnum] :base_sleep seconds to sleep on first retry, default 1
|
7
|
+
# @option options [Fixnum] :max_sleep max seconds to sleep upon exponential backoff, default 1
|
8
|
+
# @option options [Exception] :rescue exception class list to retry on, defaults is Exception, which retries on any Exception.
|
9
|
+
# @option options [Proc] :on_retry call the given Proc/lambda before each retry with the raised exception as parameter
|
10
|
+
def retryable(options = {}, &block)
|
11
|
+
options = {
|
12
|
+
:tries => 1,
|
13
|
+
:rescue => Exception,
|
14
|
+
:on_retry => nil,
|
15
|
+
:base_sleep => 1,
|
16
|
+
:max_sleep => 1,
|
17
|
+
}.merge(options)
|
18
|
+
|
19
|
+
rescue_classes = Array(options[:rescue])
|
20
|
+
max_sleep_retry = Math.log2(options[:max_sleep] / options[:base_sleep])
|
21
|
+
retry_count = 0
|
22
|
+
|
23
|
+
begin
|
24
|
+
return yield(retry_count)
|
25
|
+
rescue *rescue_classes => e
|
26
|
+
raise e if options[:tries] > 0 && retry_count >= options[:tries]
|
27
|
+
|
28
|
+
options[:on_retry].call(retry_count + 1, e) if options[:on_retry]
|
29
|
+
|
30
|
+
# dont compute and maybe overflow exponent on too big a retry count
|
31
|
+
seconds = retry_count < max_sleep_retry ? options[:base_sleep] * (2 ** retry_count) : options[:max_sleep]
|
32
|
+
sleep(seconds)
|
33
|
+
|
34
|
+
retry_count += 1
|
35
|
+
retry
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|