logstash-core 5.0.0.alpha3.snapshot2-java → 5.0.0.alpha3.snapshot4-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of logstash-core might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash/agent.rb +49 -31
- data/lib/logstash/api/init.ru +3 -3
- data/lib/logstash/api/lib/app/service.rb +1 -1
- data/lib/logstash/config/config_ast.rb +23 -18
- data/lib/logstash/config/loader.rb +4 -4
- data/lib/logstash/config/mixin.rb +10 -21
- data/lib/logstash/environment.rb +30 -0
- data/lib/logstash/filters/base.rb +2 -2
- data/lib/logstash/inputs/base.rb +2 -2
- data/lib/logstash/instrument/collector.rb +1 -1
- data/lib/logstash/logging/json.rb +21 -0
- data/lib/logstash/output_delegator.rb +2 -2
- data/lib/logstash/patches/clamp.rb +69 -0
- data/lib/logstash/pipeline.rb +37 -62
- data/lib/logstash/plugin.rb +1 -1
- data/lib/logstash/runner.rb +155 -146
- data/lib/logstash/settings.rb +267 -0
- data/lib/logstash/util/decorators.rb +6 -6
- data/lib/logstash/util/java_version.rb +1 -10
- data/lib/logstash/util/worker_threads_default_printer.rb +2 -2
- data/lib/logstash/version.rb +1 -1
- data/locales/en.yml +17 -20
- data/logstash-core.gemspec +1 -1
- data/spec/api/spec_helper.rb +15 -16
- data/spec/conditionals_spec.rb +113 -113
- data/spec/logstash/agent_spec.rb +77 -68
- data/spec/logstash/config/config_ast_spec.rb +4 -2
- data/spec/logstash/config/mixin_spec.rb +33 -7
- data/spec/logstash/filters/base_spec.rb +16 -16
- data/spec/logstash/inputs/base_spec.rb +8 -8
- data/spec/logstash/output_delegator_spec.rb +2 -0
- data/spec/logstash/pipeline_spec.rb +60 -26
- data/spec/logstash/plugin_spec.rb +2 -2
- data/spec/logstash/runner_spec.rb +112 -25
- data/spec/logstash/setting_spec.rb +130 -0
- data/spec/logstash/settings_spec.rb +62 -0
- metadata +11 -9
- data/lib/logstash/util/defaults_printer.rb +0 -31
- data/spec/logstash/util/defaults_printer_spec.rb +0 -50
- data/spec/logstash/util/worker_threads_default_printer_spec.rb +0 -45
@@ -0,0 +1,267 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module LogStash
|
4
|
+
class Settings
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@settings = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def register(setting)
|
11
|
+
if @settings.key?(setting.name)
|
12
|
+
raise ArgumentError.new("Setting \"#{setting.name}\" has already been registered as #{setting.inspect}")
|
13
|
+
else
|
14
|
+
@settings[setting.name] = setting
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_setting(setting_name)
|
19
|
+
setting = @settings[setting_name]
|
20
|
+
raise ArgumentError.new("Setting \"#{setting_name}\" hasn't been registered") if setting.nil?
|
21
|
+
setting
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_subset(setting_regexp)
|
25
|
+
regexp = setting_regexp.is_a?(Regexp) ? setting_regexp : Regexp.new(setting_regexp)
|
26
|
+
settings = self.class.new
|
27
|
+
@settings.each do |setting_name, setting|
|
28
|
+
next unless setting_name.match(regexp)
|
29
|
+
settings.register(setting.clone)
|
30
|
+
end
|
31
|
+
settings
|
32
|
+
end
|
33
|
+
|
34
|
+
def set?(setting_name)
|
35
|
+
get_setting(setting_name).set?
|
36
|
+
end
|
37
|
+
|
38
|
+
def clone
|
39
|
+
get_subset(".*")
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_default(setting_name)
|
43
|
+
get_setting(setting_name).default
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_value(setting_name)
|
47
|
+
get_setting(setting_name).value
|
48
|
+
end
|
49
|
+
alias_method :get, :get_value
|
50
|
+
|
51
|
+
def set_value(setting_name, value)
|
52
|
+
get_setting(setting_name).set(value)
|
53
|
+
end
|
54
|
+
alias_method :set, :set_value
|
55
|
+
|
56
|
+
def to_hash
|
57
|
+
hash = {}
|
58
|
+
@settings.each do |name, setting|
|
59
|
+
hash[name] = setting.value
|
60
|
+
end
|
61
|
+
hash
|
62
|
+
end
|
63
|
+
|
64
|
+
def merge(hash)
|
65
|
+
hash.each {|key, value| set_value(key, value) }
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
def format_settings
|
70
|
+
output = []
|
71
|
+
output << "-------- Logstash Settings (* means modified) ---------"
|
72
|
+
@settings.each do |setting_name, setting|
|
73
|
+
value = setting.value
|
74
|
+
default_value = setting.default
|
75
|
+
if default_value == value # print setting and its default value
|
76
|
+
output << "#{setting_name}: #{value.inspect}" unless value.nil?
|
77
|
+
elsif default_value.nil? # print setting and warn it has been set
|
78
|
+
output << "*#{setting_name}: #{value.inspect}"
|
79
|
+
elsif value.nil? # default setting not set by user
|
80
|
+
output << "#{setting_name}: #{default_value.inspect}"
|
81
|
+
else # print setting, warn it has been set, and show default value
|
82
|
+
output << "*#{setting_name}: #{value.inspect} (default: #{default_value.inspect})"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
output << "--------------- Logstash Settings -------------------"
|
86
|
+
output
|
87
|
+
end
|
88
|
+
|
89
|
+
def reset
|
90
|
+
@settings.values.each(&:reset)
|
91
|
+
end
|
92
|
+
|
93
|
+
def from_yaml(yaml_path)
|
94
|
+
settings = read_yaml(::File.join(yaml_path, "logstash.yml"))
|
95
|
+
self.merge(flatten_hash(settings))
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
def read_yaml(path)
|
100
|
+
YAML.safe_load(IO.read(path)) || {}
|
101
|
+
end
|
102
|
+
|
103
|
+
def flatten_hash(h,f="",g={})
|
104
|
+
return g.update({ f => h }) unless h.is_a? Hash
|
105
|
+
if f.empty?
|
106
|
+
h.each { |k,r| flatten_hash(r,k,g) }
|
107
|
+
else
|
108
|
+
h.each { |k,r| flatten_hash(r,"#{f}.#{k}",g) }
|
109
|
+
end
|
110
|
+
g
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class Setting
|
115
|
+
attr_reader :name, :default
|
116
|
+
|
117
|
+
def initialize(name, klass, default=nil, strict=true, &validator_proc)
|
118
|
+
@name = name
|
119
|
+
unless klass.is_a?(Class)
|
120
|
+
raise ArgumentError.new("Setting \"#{@name}\" must be initialized with a class (received #{klass})")
|
121
|
+
end
|
122
|
+
@klass = klass
|
123
|
+
@validator_proc = validator_proc
|
124
|
+
@value = nil
|
125
|
+
@value_is_set = false
|
126
|
+
|
127
|
+
validate(default) if strict
|
128
|
+
@default = default
|
129
|
+
end
|
130
|
+
|
131
|
+
def value
|
132
|
+
@value_is_set ? @value : default
|
133
|
+
end
|
134
|
+
|
135
|
+
def set?
|
136
|
+
@value_is_set
|
137
|
+
end
|
138
|
+
|
139
|
+
def set(value)
|
140
|
+
validate(value)
|
141
|
+
@value = value
|
142
|
+
@value_is_set = true
|
143
|
+
@value
|
144
|
+
end
|
145
|
+
|
146
|
+
def reset
|
147
|
+
@value = nil
|
148
|
+
@value_is_set = false
|
149
|
+
end
|
150
|
+
|
151
|
+
def to_hash
|
152
|
+
{
|
153
|
+
"name" => @name,
|
154
|
+
"klass" => @klass,
|
155
|
+
"value" => @value,
|
156
|
+
"value_is_set" => @value_is_set,
|
157
|
+
"default" => @default,
|
158
|
+
# Proc#== will only return true if it's the same obj
|
159
|
+
# so no there's no point in comparing it
|
160
|
+
# also thereś no use case atm to return the proc
|
161
|
+
# so let's not expose it
|
162
|
+
#"validator_proc" => @validator_proc
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
def ==(other)
|
167
|
+
self.to_hash == other.to_hash
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
def validate(value)
|
172
|
+
if !value.is_a?(@klass)
|
173
|
+
raise ArgumentError.new("Setting \"#{@name}\" must be a #{@klass}. Received: #{value} (#{value.class})")
|
174
|
+
elsif @validator_proc && !@validator_proc.call(value)
|
175
|
+
raise ArgumentError.new("Failed to validate setting \"#{@name}\" with value: #{value}")
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
### Specific settings #####
|
180
|
+
|
181
|
+
class Boolean < Setting
|
182
|
+
def initialize(name, default, strict=true, &validator_proc)
|
183
|
+
@name = name
|
184
|
+
@klass = Object
|
185
|
+
@value = nil
|
186
|
+
@value_is_set = false
|
187
|
+
@validator_proc = validator_proc
|
188
|
+
coerced_default = coerce(default)
|
189
|
+
validate(coerced_default)
|
190
|
+
@default = coerced_default
|
191
|
+
end
|
192
|
+
|
193
|
+
def coerce(value)
|
194
|
+
case value
|
195
|
+
when TrueClass, "true"
|
196
|
+
true
|
197
|
+
when FalseClass, "false"
|
198
|
+
false
|
199
|
+
else
|
200
|
+
raise ArgumentError.new("could not coerce #{value} into a boolean")
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def set(value)
|
205
|
+
coerced_value = coerce(value)
|
206
|
+
validate(coerced_value)
|
207
|
+
@value = coerce(coerced_value)
|
208
|
+
@value_is_set = true
|
209
|
+
@value
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
class String < Setting
|
214
|
+
def initialize(name, default=nil, strict=true)
|
215
|
+
super(name, ::String, default, strict)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
class Numeric < Setting
|
220
|
+
def initialize(name, default=nil, strict=true)
|
221
|
+
super(name, ::Numeric, default, strict)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
class Port < Setting
|
226
|
+
def initialize(name, default=nil, strict=true)
|
227
|
+
super(name, ::Numeric, default, strict) {|value| value >= 1 && value <= 65535 }
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
class Validator < Setting
|
232
|
+
def initialize(name, default=nil, strict=true, validator_class=nil)
|
233
|
+
@validator_class = validator_class
|
234
|
+
super(name, ::Object, default, strict)
|
235
|
+
end
|
236
|
+
|
237
|
+
def validate(value)
|
238
|
+
@validator_class.validate(value)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
class String < Setting
|
243
|
+
def initialize(name, default=nil, strict=true, possible_strings=[])
|
244
|
+
super(name, ::String, default, strict)
|
245
|
+
end
|
246
|
+
|
247
|
+
def validate(value)
|
248
|
+
super(value) && possible_strings.include?(value)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
class ExistingFilePath < Setting
|
253
|
+
def initialize(name, default=nil, strict=true)
|
254
|
+
super(name, ::String, default, strict) do |file_path|
|
255
|
+
if !::File.exists?(file_path)
|
256
|
+
raise ::ArgumentError.new("File \"#{file_path}\" must exist but was not found.")
|
257
|
+
else
|
258
|
+
true
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
SETTINGS = Settings.new
|
267
|
+
end
|
@@ -7,7 +7,7 @@ module LogStash::Util
|
|
7
7
|
# Decorators provides common manipulation on the event data.
|
8
8
|
module Decorators
|
9
9
|
extend self
|
10
|
-
|
10
|
+
|
11
11
|
@logger = Cabin::Channel.get(LogStash)
|
12
12
|
|
13
13
|
# fields is a hash of field => value
|
@@ -22,11 +22,11 @@ module LogStash::Util
|
|
22
22
|
# note below that the array field needs to be updated then reassigned to the event.
|
23
23
|
# this is important because a construct like event[field] << v will not work
|
24
24
|
# in the current Java event implementation. see https://github.com/elastic/logstash/issues/4140
|
25
|
-
a = Array(event
|
25
|
+
a = Array(event.get(field))
|
26
26
|
a << v
|
27
|
-
event
|
27
|
+
event.set(field, a)
|
28
28
|
else
|
29
|
-
event
|
29
|
+
event.set(field, v)
|
30
30
|
end
|
31
31
|
@logger.debug? and @logger.debug("#{pluginname}: adding value to field", :field => field, :value => value)
|
32
32
|
end
|
@@ -41,9 +41,9 @@ module LogStash::Util
|
|
41
41
|
# note below that the tags array field needs to be updated then reassigned to the event.
|
42
42
|
# this is important because a construct like event["tags"] << tag will not work
|
43
43
|
# in the current Java event implementation. see https://github.com/elastic/logstash/issues/4140
|
44
|
-
tags = event
|
44
|
+
tags = event.get("tags") || []
|
45
45
|
tags << tag
|
46
|
-
event
|
46
|
+
event.set("tags", tags)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -5,16 +5,7 @@ module LogStash::Util::JavaVersion
|
|
5
5
|
def self.logger
|
6
6
|
@logger ||= Cabin::Channel.get(LogStash)
|
7
7
|
end
|
8
|
-
|
9
|
-
# Print a warning if we're on a bad version of java
|
10
|
-
def self.warn_on_bad_java_version
|
11
|
-
if self.bad_java_version?(self.version)
|
12
|
-
msg = "!!! Please upgrade your java version, the current version '#{self.version}' is not supported. We recommend a minimum version of Java 8"
|
13
|
-
STDERR.puts(msg)
|
14
|
-
logger.warn(msg)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
8
|
+
|
18
9
|
# Return the current java version string. Returns nil if this is a non-java platform (e.g. MRI).
|
19
10
|
def self.version
|
20
11
|
return nil unless LogStash::Environment.jruby?
|
@@ -6,8 +6,8 @@ require "logstash/util"
|
|
6
6
|
module LogStash module Util class WorkerThreadsDefaultPrinter
|
7
7
|
|
8
8
|
def initialize(settings)
|
9
|
-
@setting = settings.fetch(
|
10
|
-
@default = settings.fetch(
|
9
|
+
@setting = settings.fetch('pipeline.workers', 0)
|
10
|
+
@default = settings.fetch('default-pipeline-workers', 0)
|
11
11
|
end
|
12
12
|
|
13
13
|
def visit(collector)
|
data/lib/logstash/version.rb
CHANGED
data/locales/en.yml
CHANGED
@@ -71,12 +71,8 @@ en:
|
|
71
71
|
non_reloadable_config_reload: >-
|
72
72
|
Unable to reload configuration because it does not support dynamic reloading
|
73
73
|
non_reloadable_config_register: |-
|
74
|
-
Logstash
|
75
|
-
dynamic reloading and -r or --auto-reload flag was enabled
|
74
|
+
Logstash is not able to start since configuration auto reloading was enabled but the configuration contains plugins that don't support it. Quitting...
|
76
75
|
web_api:
|
77
|
-
flag:
|
78
|
-
http_host: Web API binding host
|
79
|
-
http_port: Web API http port
|
80
76
|
hot_threads:
|
81
77
|
title: |-
|
82
78
|
::: {%{hostname}}
|
@@ -182,10 +178,8 @@ en:
|
|
182
178
|
the empty string for the '-e' flag.
|
183
179
|
configtest: |+
|
184
180
|
Check configuration for valid syntax and then exit.
|
185
|
-
|
186
|
-
|
187
|
-
values. Instances of "${VAR}" in strings will be replaced
|
188
|
-
with the respective environment variable value named "VAR".
|
181
|
+
http_host: Web API binding host
|
182
|
+
http_port: Web API http port
|
189
183
|
pipeline-workers: |+
|
190
184
|
Sets the number of pipeline workers to run.
|
191
185
|
pipeline-batch-size: |+
|
@@ -193,6 +187,9 @@ en:
|
|
193
187
|
pipeline-batch-delay: |+
|
194
188
|
When creating pipeline batches, how long to wait while polling
|
195
189
|
for the next event.
|
190
|
+
path_settings: |+
|
191
|
+
Directory containing logstash.yml file. This can also be
|
192
|
+
set through the LS_SETTINGS_DIR environment variable.
|
196
193
|
auto_reload: |+
|
197
194
|
Monitor configuration changes and reload
|
198
195
|
whenever it is changed.
|
@@ -221,15 +218,12 @@ en:
|
|
221
218
|
'PATH/logstash/TYPE/NAME.rb' where TYPE is
|
222
219
|
'inputs' 'filters', 'outputs' or 'codecs'
|
223
220
|
and NAME is the name of the plugin.
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
debug: |+
|
231
|
-
Most verbose logging. This causes 'debug'
|
232
|
-
level logs to be emitted.
|
221
|
+
log_level: |+
|
222
|
+
Set the log level for logstash. Possible values are:
|
223
|
+
- quiet => :error
|
224
|
+
- verbose => :info
|
225
|
+
- debug => :debug
|
226
|
+
- warn => :warn
|
233
227
|
unsafe_shutdown: |+
|
234
228
|
Force logstash to exit during shutdown even
|
235
229
|
if there are still inflight events in memory.
|
@@ -243,7 +237,10 @@ en:
|
|
243
237
|
it will default to the current hostname.
|
244
238
|
agent: |+
|
245
239
|
Specify an alternate agent plugin name.
|
246
|
-
|
240
|
+
config_debug: |+
|
247
241
|
Print the compiled config ruby code out as a debug log (you must also have --debug enabled).
|
248
242
|
WARNING: This will include any 'password' options passed to plugin configs as plaintext, and may result
|
249
|
-
in plaintext passwords appearing in your logs!
|
243
|
+
in plaintext passwords appearing in your logs!
|
244
|
+
log_format: |+
|
245
|
+
Specify if Logstash should write its own logs in JSON form (one
|
246
|
+
event per line) or in plain text (using Ruby's Object#inspect)
|
data/logstash-core.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.require_paths = ["lib"]
|
18
18
|
gem.version = LOGSTASH_CORE_VERSION.gsub(/-/, '.')
|
19
19
|
|
20
|
-
gem.add_runtime_dependency "logstash-core-event-java", "5.0.0
|
20
|
+
gem.add_runtime_dependency "logstash-core-event-java", "5.0.0.alpha3.snapshot4"
|
21
21
|
|
22
22
|
gem.add_runtime_dependency "cabin", "~> 0.8.0" #(Apache 2.0 license)
|
23
23
|
gem.add_runtime_dependency "pry", "~> 0.10.1" #(Ruby license)
|
data/spec/api/spec_helper.rb
CHANGED
@@ -3,6 +3,7 @@ API_ROOT = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib",
|
|
3
3
|
|
4
4
|
require "logstash/devutils/rspec/spec_helper"
|
5
5
|
|
6
|
+
require "logstash/settings"
|
6
7
|
require 'rack/test'
|
7
8
|
require 'rspec'
|
8
9
|
require "json"
|
@@ -37,26 +38,24 @@ class LogStashRunner
|
|
37
38
|
attr_reader :config_str, :agent, :pipeline_settings
|
38
39
|
|
39
40
|
def initialize
|
40
|
-
args = [
|
41
|
-
:logger => Cabin::Channel.get(LogStash),
|
42
|
-
:auto_reload => false,
|
43
|
-
:collect_metric => true,
|
44
|
-
:debug => false,
|
45
|
-
:node_name => "test_agent",
|
46
|
-
:web_api_http_port => rand(9600..9700)
|
47
|
-
]
|
48
|
-
|
49
41
|
@config_str = "input { generator {count => 0} } output { }"
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
42
|
+
args = {
|
43
|
+
"config.reload.automatic" => false,
|
44
|
+
"metric.collect" => true,
|
45
|
+
"log.level" => "debug",
|
46
|
+
"node.name" => "test_agent",
|
47
|
+
"http.port" => rand(9600..9700),
|
48
|
+
"config.string" => @config_str,
|
49
|
+
"pipeline.batch.size" => 1,
|
50
|
+
"pipeline.workers" => 1
|
51
|
+
}
|
52
|
+
@settings = ::LogStash::SETTINGS.clone.merge(args)
|
53
|
+
|
54
|
+
@agent = LogStash::DummyAgent.new(@settings)
|
56
55
|
end
|
57
56
|
|
58
57
|
def start
|
59
|
-
agent.register_pipeline("main",
|
58
|
+
agent.register_pipeline("main", @settings)
|
60
59
|
@runner = Thread.new(agent) do |_agent|
|
61
60
|
_agent.execute
|
62
61
|
end
|