# # Fluentd # # Copyright (C) 2011 FURUHASHI Sadayuki # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'optparse' require 'fluent/log' require 'fluent/env' require 'fluent/version' op = OptionParser.new op.version = Fluent::VERSION # default values config_path = Fluent::DEFAULT_CONFIG_PATH plugin_dirs = [Fluent::DEFAULT_PLUGIN_DIR] log_level = Fluent::Log::LEVEL_INFO log_file = nil daemonize = false libs = [] setup_path = nil chuser = nil chgroup = nil op.on('-s', "--setup [DIR=#{File.dirname(Fluent::DEFAULT_CONFIG_PATH)}]", "install sample configuration file to the directory") {|s| setup_path = s || File.dirname(Fluent::DEFAULT_CONFIG_PATH) } op.on('-c', '--config PATH', "config flie path (default: #{config_path})") {|s| config_path = s } op.on('-p', '--plugin DIR', "add plugin directory") {|s| plugin_dirs << s } op.on('-I PATH', "add library path") {|s| $LOAD_PATH << s } op.on('-r NAME', "load library") {|s| libs << s } op.on('-d', '--daemon PIDFILE', "daemonize fluent process") {|s| daemonize = s } op.on('--user USER', "change user") {|s| chuser = s } op.on('--group GROUP', "change group") {|s| chgroup = s } op.on('-o', '--log PATH', "log file path") {|s| log_file = s } op.on('-v', '--verbose', "increment verbose level (-v: debug, -vv: trace)", TrueClass) {|b| if b case log_level when Fluent::Log::LEVEL_INFO log_level = Fluent::Log::LEVEL_DEBUG when Fluent::Log::LEVEL_DEBUG log_level = Fluent::Log::LEVEL_TRACE end end } (class<<self;self;end).module_eval do define_method(:usage) do |msg| puts op.to_s puts "error: #{msg}" if msg exit 1 end end begin op.parse!(ARGV) if ARGV.length != 0 usage nil end rescue usage $!.to_s end if setup_path require 'fileutils' FileUtils.mkdir_p File.join(setup_path, "plugin") confpath = File.join(setup_path, "fluent.conf") if File.exist?(confpath) puts "#{confpath} already exists." else File.open(confpath, "w") {|f| conf = File.read File.join(File.dirname(__FILE__), "..", "..", "..", "fluent.conf") f.write conf } puts "Installed #{confpath}." end exit 0 end if log_file && log_file != "-" log_out = File.open(log_file, "a") else log_out = STDOUT end $log = Fluent::Log.new(log_out, log_level) $log.enable_color(false) if log_file $log.enable_debug if log_level <= Fluent::Log::LEVEL_DEBUG require 'fluent/load' begin # # initialize # Fluent::Engine.init libs.each {|lib| require lib } plugin_dirs.each {|dir| if Dir.exist?(dir) dir = File.expand_path(dir) Fluent::Engine.load_plugin_dir(dir) end } Fluent::Engine.read_config(config_path) # # daemonize # if chgroup chgid = chgroup.to_i if chgid.to_s != chgroup chgid = `id -u #{chgroup}`.to_i if $?.to_i != 0 exit 1 end end Process::GID.change_privilege(chgid) end if chuser chuid = chuser.to_i if chuid.to_s != chuser chuid = `id -u #{chuser}`.to_i if $?.to_i != 0 exit 1 end end Process::UID.change_privilege(chuid) end trap :INT do Fluent::Engine.stop end trap :TERM do Fluent::Engine.stop end trap :HUP do if log_file $log.reopen(log_file, "a") end end trap :USR1 do $log.info "force flushing buffered events" Fluent::Engine.flush! end if daemonize exit!(0) if fork Process.setsid exit!(0) if fork File.umask(0) STDIN.reopen("/dev/null") STDOUT.reopen("/dev/null", "w") STDERR.reopen("/dev/null", "w") File.open(daemonize, "w") {|f| f.write Process.pid.to_s } end # # run # $log.info "running fluent-#{Fluent::VERSION}" Fluent::Engine.run rescue Fluent::ConfigError $log.error "config error", :file=>config_path, :error=>$!.to_s $log.debug_backtrace # also STDOUT if log_out != STDOUT console = Fluent::Log.new(STDOUT, log_level).enable_debug console.error "config error", :file=>config_path, :error=>$!.to_s console.debug_backtrace end exit 1 rescue $log.error "unexpected error", :error=>$!.to_s $log.error_backtrace # also STDOUT if log_out != STDOUT console = Fluent::Log.new(STDOUT, log_level).enable_debug console.error "unexpected error", :error=>$!.to_s console.error_backtrace end exit 1 end