From aa3c0326b0e86ef8335df16f1412bcfcb2aea894 Mon Sep 17 00:00:00 2001 From: uu59 Date: Fri, 9 May 2014 15:37:16 +0900 Subject: [PATCH] Add basic fleuntd management --- app/controllers/fluentd_controller.rb | 34 ++++++++ app/models/fluentd.rb | 109 ++++++++++++++++++++++++++ app/views/fluentd/index.html.haml | 7 ++ app/views/fluentd/status.html.haml | 8 ++ config/routes.rb | 16 ++++ 5 files changed, 174 insertions(+) create mode 100644 app/controllers/fluentd_controller.rb create mode 100644 app/models/fluentd.rb create mode 100644 app/views/fluentd/index.html.haml create mode 100644 app/views/fluentd/status.html.haml diff --git a/app/controllers/fluentd_controller.rb b/app/controllers/fluentd_controller.rb new file mode 100644 index 0000000..947c2e9 --- /dev/null +++ b/app/controllers/fluentd_controller.rb @@ -0,0 +1,34 @@ +class FluentdController < ApplicationController + before_filter :fluentd + + def index + end + + def status + end + + def start + fluentd.start + render :status + end + + def stop + fluentd.stop + render :status + end + + def reload + fluentd.reload + render :status + end + + def log + render text: fluentd.log, content_type: "text/plain" + end + + private + + def fluentd + @fluentd ||= Fluentd.new(Rails.root + "tmp" + "fluentd") + end +end diff --git a/app/models/fluentd.rb b/app/models/fluentd.rb new file mode 100644 index 0000000..6cc770b --- /dev/null +++ b/app/models/fluentd.rb @@ -0,0 +1,109 @@ +Bundler.require(:default, :development) + +require 'fluent/log' +require 'fluent/env' +require 'fluent/version' +require 'fluent/supervisor' + +class Fluentd + attr_reader :root_dir + + def initialize(root_dir) + @root_dir = root_dir + FileUtils.mkdir_p @root_dir + end + + def pid_file + File.join(root_dir, "fluentd.pid") + end + + def pid + return unless File.exists?(pid_file) + File.read(pid_file) + end + + def log_file + File.join(root_dir, "fluentd.log") + end + + def config_file + file = File.join(root_dir, "fluentd.conf") + unless File.exists?(file) + File.open(file, "w") {|f| f.write "\ntype forward\n" } # TODO + end + file + end + + def plugin_dir + dir = File.join(root_dir, "fluentd", "plugins") + unless Dir.exist?(dir) + FileUtils.mkdir_p(dir) + end + dir + end + + def options + # TODO: https://github.com/fluent/fluentd/pull/315 + { + :config_path => Fluent::DEFAULT_CONFIG_PATH, + :plugin_dirs => [Fluent::DEFAULT_PLUGIN_DIR], + :log_level => Fluent::Log::LEVEL_INFO, + :log_path => nil, + :daemonize => false, + :libs => [], + :setup_path => nil, + :chuser => nil, + :chgroup => nil, + :suppress_interval => 0, + :suppress_repeated_stacktrace => false, + :use_v1_config => false, + }.merge({ + :use_v1_config => true, + :plugin_dirs => [plugin_dir], + :config_path => config_file, + :daemonize => pid_file, + :log_path => log_file, + :log_level => Fluent::Log::LEVEL_INFO, + }) + end + + def running? + pid && system("/bin/kill -0 #{pid}", :out => File::NULL, :err => File::NULL) + end + + def start + return if running? + spawn("bundle exec fluentd #{options_to_argv(options)}") # TODO + end + + def stop + return unless running? + system("/bin/kill -TERM #{pid}") + File.unlink(pid_file) + end + + def reload + return unless running? + system("/bin/kill -HUP #{pid}") + end + + def log + File.read log_file # TODO: large log file + end + + def config + File.read config_file # TODO: Use Fluent::Engine or Fluent::V1Config + end + + private + + def options_to_argv(options) + argv = "" + argv << " --use-v1-config" if options[:use_v1_config] + argv << " -c #{options[:config_path]}" if options[:config_path].present? + argv << " -p #{options[:plugin_dir].first}" if options[:plugin_dir].present? + argv << " -d #{options[:daemonize]}" if options[:daemonize].present? + argv << " -o #{options[:log_path]}" if options[:log_path].present? + argv + end +end diff --git a/app/views/fluentd/index.html.haml b/app/views/fluentd/index.html.haml new file mode 100644 index 0000000..52e3299 --- /dev/null +++ b/app/views/fluentd/index.html.haml @@ -0,0 +1,7 @@ +%h1 + = @fluentd.running? ? "running" : "stopped" + + = link_to "start", start_fluentd_path(id: 1), method: :put, remote: true + = link_to "stop", stop_fluentd_path(id: 1), method: :put + = link_to "reload", reload_fluentd_path(id: 1), method: :put + = link_to "log", log_fluentd_path(id: 1) diff --git a/app/views/fluentd/status.html.haml b/app/views/fluentd/status.html.haml new file mode 100644 index 0000000..9ded537 --- /dev/null +++ b/app/views/fluentd/status.html.haml @@ -0,0 +1,8 @@ + +%h1 + = @fluentd.running? ? "running" : "stopped" + + = link_to "start", start_fluentd_path(id: 1), method: :put, remote: true + = link_to "stop", stop_fluentd_path(id: 1), method: :put + = link_to "reload", reload_fluentd_path(id: 1), method: :put + = link_to "log", log_fluentd_path(id: 1) diff --git a/config/routes.rb b/config/routes.rb index 3f66539..ec5a52b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,20 @@ Rails.application.routes.draw do + resources :fluentd, only: [:index] do + member do + get "status" + put "start" + put "stop" + put "reload" + get "log" + resource :config do + end + end + end + resources :plugins do + end + + resources :misc, only: [] do + end # The priority is based upon order of creation: first created -> highest priority. # See how all your routes lay out with "rake routes".