Start using i18n for user message lookups.

Notable big changes is that I try to offer suggestions as to what might
be wrong. Additionally, for unrecoverable failures, emit a big message
about how this is probably a bug and offer irc/mailing list/etc
This commit is contained in:
Jordan Sissel 2013-02-08 01:04:03 -08:00
parent 1631275a71
commit d267d752e6
3 changed files with 115 additions and 37 deletions

View file

@ -3,45 +3,39 @@ require "logstash/pipeline"
require "clamp" # gem 'clamp' require "clamp" # gem 'clamp'
require "cabin" # gem 'cabin' require "cabin" # gem 'cabin'
require "sys/uname" # gem 'sys-uname' require "sys/uname" # gem 'sys-uname'
require "i18n" # gem 'i18n'
I18n.load_path << File.expand_path(
File.join(File.dirname(__FILE__), "../../locales/en.yml")
)
class LogStash::Agent2 < Clamp::Command class LogStash::Agent2 < Clamp::Command
class ConfigurationError < StandardError; end class ConfigurationError < StandardError; end
option ["-f", "--config"], "CONFIG_PATH", option ["-f", "--config"], "CONFIG_PATH",
"Load the logstash config from a specific file or directory. " \ I18n.t("logstash.agent.flag.config"),
"If a direcory is given, all files in that directory will " \
"be concatonated in lexicographical order and then parsed as " \
"a single config file. You can also specify wildcards (globs)" \
"and any matched files will be loaded in the order described above",
:attribute_name => :config_path :attribute_name => :config_path
option "-e", "CONFIG_STRING", option "-e", "CONFIG_STRING",
"Use the given string as the configuration data. Same syntax as " \ I18n.t("logstash.agent.flag.config-string"),
"the config file. If not input is specified, then " \
"'stdin { type => stdin }' is the default input. If no output is " \
"specified, then 'stdout { debug => true }}' is default output.",
:attribute_name => :config_string :attribute_name => :config_string
option ["-w", "--filterworkers"], "COUNT", option ["-w", "--filterworkers"], "COUNT",
"Sets the number of filter workers to run.", I18n.t("logstash.agent.flag.filterworkers"),
:attribute_name => :filter_workers, :default => 1, &:to_i :attribute_name => :filter_workers, :default => 1, &:to_i
option "--watchdog-timeout", "SECONDS", option "--watchdog-timeout", "SECONDS",
"Set the filter watchdog timeout (in seconds). This timeout is used" \ I18n.t("logstash.agent.flag.watchdog-timeout"),
" to detect stuck filters; stuck filters usually symptoms of bugs. " \ :default => 10, &:to_f
"When a filter takes longer than TIMEOUT seconds, it will cause " \
"logstash to abort.", :default => 10, &:to_f
option ["-l", "--log"], "FILE", option ["-l", "--log"], "FILE",
"Write logstash internal logs to the given file. Without this flag, " \ I18n.t("logstash.agent.flag.log"),
"logstash will emit logs to standard output.",
:attribute_name => :log_file :attribute_name => :log_file
verbosity = 0 verbosity = 0
option "-v", :flag, "Increase verbosity of logstash internal logs. " \ option "-v", :flag,
"Specifying once will show 'informational' logs. Specifying twice " \ I18n.t("logstash.agent.flag.verbosity"),
"will show 'debug' logs.", :default => :warn, :default => :warn, :attribute_name => :verbosity do
:attribute_name => :verbosity do
verbosity += 1 verbosity += 1
if verbosity == 1 if verbosity == 1
@ -52,16 +46,12 @@ class LogStash::Agent2 < Clamp::Command
end # -v end # -v
option ["-V", "--version"], :flag, option ["-V", "--version"], :flag,
"Emit the version of logstash and its friends" I18n.t("logstash.agent.flag.version")
plugin_paths = [] plugin_paths = []
option ["-p", "--pluginpath"] , "PATH", option ["-p", "--pluginpath"] , "PATH",
"A path of where to find plugins. This flag can be " \ I18n.t("logstash.agent.flag.pluginpath"),
"given multiple times to include multiple paths. " \ :attribute_name => :plugin_paths do |value|
"Plugins are expected to be in a specific directory hierarchy: " \
"'PATH/logstash/TYPE/NAME.rb' where TYPE is 'input' 'filter' or " \
"'output' and NAME is the name of the plugin.",
:attribute_name => :plugin_paths do |value|
plugin_paths << value unless plugin_paths.include?(value) plugin_paths << value unless plugin_paths.include?(value)
next plugin_paths next plugin_paths
end # -p / --pluginpath end # -p / --pluginpath
@ -86,6 +76,7 @@ class LogStash::Agent2 < Clamp::Command
end end
logger = Cabin::Channel.get logger = Cabin::Channel.get
# Set with the -v (or -vv...) flag # Set with the -v (or -vv...) flag
logger.level = verbosity? logger.level = verbosity?
@ -95,19 +86,21 @@ class LogStash::Agent2 < Clamp::Command
# @filter_workers # @filter_workers
# @watchdog_timeout # @watchdog_timeout
puts "GO"
sleep 5
pipeline = LogStash::Pipeline.new(@config_string) pipeline = LogStash::Pipeline.new(@config_string)
# Make SIGINT shutdown the pipeline.
trap_id = Stud::trap("INT") { pipeline.shutdown } trap_id = Stud::trap("INT") { pipeline.shutdown }
# TODO(sissel): Get pipeline completion status.
pipeline.run pipeline.run
return 0 return 0
rescue ConfigurationError => e rescue ConfigurationError => e
puts "Error: #{e}" puts I18n.t("logstash.agent.error", :error => e)
return 1 return 1
rescue => e rescue => e
puts e puts I18n.t("unexpected-exception", :error => e)
puts e.backtrace return 1
#puts e.backtrace
ensure ensure
Stud::untrap("INT", trap_id) unless trap_id.nil? Stud::untrap("INT", trap_id) unless trap_id.nil?
end # def execute end # def execute
@ -165,7 +158,7 @@ class LogStash::Agent2 < Clamp::Command
# Log file stuff, plugin path checking, etc. # Log file stuff, plugin path checking, etc.
def configure def configure
configure_logging(log_file) if !log_file.nil? configure_logging(log_file) if !log_file.nil?
configure_plugin_path(plugin_paths) if !plugin_paths.nil?? configure_plugin_path(plugin_paths) if !plugin_paths.nil?
end # def configure end # def configure
# Point logging at a specific path. # Point logging at a specific path.
@ -176,7 +169,8 @@ class LogStash::Agent2 < Clamp::Command
begin begin
file = File.new(path, "a") file = File.new(path, "a")
rescue => e rescue => e
fail("Failed to open #{path} for writing: #{e}") fail(I18n.t("logstash.agent.configuration.log_file_failed",
:path => path, :error => e))
end end
puts "Sending all output to #{path}." puts "Sending all output to #{path}."
logger.subscribe(file) logger.subscribe(file)
@ -189,14 +183,17 @@ class LogStash::Agent2 < Clamp::Command
paths.each do |path| paths.each do |path|
# Verify the path exists # Verify the path exists
if !Dir.exists?(path) if !Dir.exists?(path)
warn("This plugin path does not exist: '#{path}'") warn(I18n.t("logstash.agent.configuration.plugin_path_missing",
:path => path))
end end
# TODO(sissel): Verify the path looks like the correct form. # TODO(sissel): Verify the path looks like the correct form.
# aka, there must be file in path/logstash/{filters,inputs,outputs}/*.rb # aka, there must be file in path/logstash/{filters,inputs,outputs}/*.rb
plugin_glob = File.join(path, "logstash", "{inputs,filters,outputs}", "*.rb") plugin_glob = File.join(path, "logstash", "{inputs,filters,outputs}", "*.rb")
if Dir.glob(plugin_glob).empty? if Dir.glob(plugin_glob).empty?
warn("No plugins were found at #{plugin_glob}") warn(I18n.t("logstash.agent.configuration.no_plugins_found",
:path => path, :plugin_glob => plugin_glob))
end end
# We push plugin paths to the front of the LOAD_PATH so that folks # We push plugin paths to the front of the LOAD_PATH so that folks

80
locales/en.yml Normal file
View file

@ -0,0 +1,80 @@
# YAML notes
# |- means 'scalar block' useful for formatted text
# > means 'scalar block' but it chomps all newlines. Useful
# for unformatted text.
en:
unexpected-exception: |-
+-------------------------------------------------------
| An unexpected error occurred. This is probably a bug.
| You can find help with this problem in a few places:
|
| * chat: #logstash IRC channel on freenode irc. To get
| to IRC on the web, go here: http://goo.gl/TI4Ro
| * email: logstash-users@googlegroups.com
| * bug system: https://logstash.jira.com/
|
+-------------------------------------------------------
The error reported is:
%{error}
logstash:
agent:
error: |-
Error: %{error}
configuration:
plugin_path_missing: |-
You specified a plugin path that does not exist: %{path}
no_plugins_found: |-
Could not find any plugins in "%{path}"
I tried to find files matching the following, but found none:
%{plugin_glob}
log_file_failed: |-
Failed to open %{path} for writing: %{error}
This is often a permissions issue, or the wrong
path was specified?
flag:
# Wrap these at 45 chars so they display nicely when clamp emits them in
# an 80-character terminal
config: |-
Load the logstash config from a specific file
or directory. If a direcory is given, all
files in that directory will be concatonated
in lexicographical order and then parsed as a
single config file. You can also specify
wildcards (globs) and any matched files will
be loaded in the order described above.
config-string: |-
Use the given string as the configuration
data. Same syntax as the config file. If not
input is specified, then 'stdin { type =|-
stdin }' is the default input. If no output
is specified, then 'stdout { debug => true
}}' is default output.
filterworkers: |-
Sets the number of filter workers to run.
watchdog-timeout: |-
Set the filter watchdog timeout (in seconds).
This timeout is used to detect stuck filters;
stuck filters usually symptoms of bugs.
When a filter takes longer than TIMEOUT
seconds, it will cause logstash to abort.
log: |-
Write logstash internal logs to the given
file. Without this flag, logstash will emit
logs to standard output.
verbosity: |-
Increase verbosity of logstash internal logs.
Specifying once will show 'informational'
logs. Specifying twice will show 'debug'
logs.
version: |-
Emit the version of logstash and its friends,
then exit.
pluginpath: |-
A path of where to find plugins. This flag
can be given multiple times to include
multiple paths. Plugins are expected to be
in a specific directory hierarchy:
'PATH/logstash/TYPE/NAME.rb' where TYPE is
'input' 'filter' or 'output' and NAME is the
name of the plugin.

View file

@ -24,6 +24,7 @@ Gem::Specification.new do |gem|
gem.add_runtime_dependency "stud" gem.add_runtime_dependency "stud"
gem.add_runtime_dependency "sys-uname" # for platform detection gem.add_runtime_dependency "sys-uname" # for platform detection
gem.add_runtime_dependency "clamp" # for command line args/flags gem.add_runtime_dependency "clamp" # for command line args/flags
gem.add_runtime_dependency "i18n"
# Web dependencies # Web dependencies
gem.add_runtime_dependency "ftw", ["~> 0.0.26"] gem.add_runtime_dependency "ftw", ["~> 0.0.26"]