diff --git a/app/controllers/fluentd/settings/out_s3_controller.rb b/app/controllers/fluentd/settings/out_s3_controller.rb new file mode 100644 index 0000000..b90240a --- /dev/null +++ b/app/controllers/fluentd/settings/out_s3_controller.rb @@ -0,0 +1,34 @@ +class Fluentd::Settings::OutS3Controller < ApplicationController + before_action :login_required + before_action :find_fluentd + + def show + @setting = Fluentd::Setting::OutS3.new({ + s3_endpoint: "s3-us-west-1.amazonaws.com", + buffer_path: "/var/log/fluent/s3", + }) + end + + def finish + @setting = Fluentd::Setting::OutS3.new(setting_params) + unless @setting.valid? + return render "show" + end + + @fluentd.agent.config_append @setting.to_conf + if @fluentd.agent.running? + unless @fluentd.agent.restart + @setting.errors.add(:base, @fluentd.agent.log_tail(1).first) + return render "show" + end + end + redirect_to fluentd_setting_path(@fluentd) + end + + private + + def setting_params + params.require(:fluentd_setting_out_s3).permit(*Fluentd::Setting::OutS3::KEYS) + end + +end diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb new file mode 100644 index 0000000..133e029 --- /dev/null +++ b/app/helpers/settings_helper.rb @@ -0,0 +1,19 @@ +module SettingsHelper + def field(form, key, opts = {}) + html = '
' + html << h(form.label(key)) + html << " " # NOTE: Adding space for padding + + case form.object.column_type(key) + when :boolean, :flag + html << form.check_box(key, {}, "true", "false") + when :choice + html << form.select(key, form.object.values_of(key), opts) + else + html << form.text_field(key) + end + + html << "
" + html.html_safe + end +end diff --git a/app/models/fluentd/setting/common.rb b/app/models/fluentd/setting/common.rb index 3ac5e73..321a5b3 100644 --- a/app/models/fluentd/setting/common.rb +++ b/app/models/fluentd/setting/common.rb @@ -1,9 +1,95 @@ class Fluentd module Setting module Common + extend ActiveSupport::Concern + + module ClassMethods + attr_accessor :values, :types + + def choice(key, values) + @values ||= {} + @values[key] = values + set_type(:choice, [key]) + end + + def booleans(*keys) + # e.g.: + # use_ssl true + # include_time_key false + set_type(:boolean, keys) + end + + def flags(*keys) + # e.g.: + # tag_mapped + # utc + set_type(:flag, keys) + end + + private + + def set_type(type, keys) + @types ||= {} + keys.each do |key| + @types[key] = type + end + end + end + + def values_of(key) + self.class.values[key] || [] + end + + def column_type(key) + self.class.types[key] || "string" + end + + def conf(key) + case column_type(key) + when :boolean + boolenan(key) + when :flag + flag(key) + else + print_if_present(key) + end + end + + def plugin_type_name + # Fluentd::Setting::OutS3 -> s3 + # Override this method if not above style + self.class.to_s.split("::").last.sub(/(In|Out)/, "").downcase + end + def print_if_present(key) + # e.g.: + # path /var/log/td/aaa + # user nobody + # retry_limit 3 send(key).present? ? "#{key} #{send(key)}" : "" end + + def boolenan(key) + send(key).presence == "true" ? "#{key} true" : "#{key} false" + end + + def flag(key) + send(key).presence == "true" ? key.to_s : "" + end + + def to_config + indent = " " + config = "\n" + config << "#{indent}type #{plugin_type_name}\n" + self.class.const_get(:KEYS).each do |key| + next if key == :match + config << indent + config << conf(key) + config << "\n" + end + config << "\n" + config.gsub(/^[ ]*\n/m, "") + end end end end diff --git a/app/models/fluentd/setting/out_s3.rb b/app/models/fluentd/setting/out_s3.rb new file mode 100644 index 0000000..b9f0a2b --- /dev/null +++ b/app/models/fluentd/setting/out_s3.rb @@ -0,0 +1,33 @@ +class Fluentd + module Setting + class OutS3 + include ActiveModel::Model + include Common + + KEYS = [ + :match, + :aws_key_id, :aws_sec_key, :s3_bucket, :s3_endpoint, :path, + # :reduced_redundancy, :check_apikey_on_start, :command_parameter, # not configurable? + :format, :include_time_key, :time_key, :delimiter, :label_delimiter, :add_newline, + :time_slice_format, :time_slice_wait, :time_format, :utc, :store_as, :proxy_uri, :use_ssl, + :buffer_type, :buffer_path, :buffer_queue_limit, :buffer_chunk_limit, :flush_interval, + :retry_wait, :retry_limit, :max_retry_wait, :num_threads, + ].freeze + + attr_accessor(*KEYS) + + choice :format, %w(out_file json ltsv single_value) + choice :store_as, %w(gzip lzo lzma2 json txt) + booleans :include_time_key, :add_newline, :use_ssl + flags :utc + + validates :match, presence: true + validates :s3_bucket, presence: true + validates :buffer_path, presence: true + + def to_conf + to_config + end + end + end +end diff --git a/app/views/fluentd/settings/out_s3/_form.html.haml b/app/views/fluentd/settings/out_s3/_form.html.haml new file mode 100644 index 0000000..7523f98 --- /dev/null +++ b/app/views/fluentd/settings/out_s3/_form.html.haml @@ -0,0 +1,39 @@ +- @setting.errors.full_messages.each do |msg| + = msg + += form_for(@setting, url: finish_fluentd_setting_out_s3_path(@fluentd), html: {class: "ignore-rails-error-div"}) do |f| + = field(f, :match) + = field(f, :aws_key_id) + = field(f, :aws_sec_key) + = field(f, :s3_bucket) + = field(f, :s3_endpoint) + = field(f, :path) + = field(f, :format, prompt: "--") + = field(f, :time_slice_format) + = field(f, :time_slice_wait) + = field(f, :include_time_key) + = field(f, :utc) + = field(f, :delimiter) + = field(f, :label_delimiter) + = field(f, :store_as) + = field(f, :proxy_uri) + = field(f, :use_ssl) + + .well.well-sm + %h4{"data-toggle" => "collapse", "href" => "#advanced-setting"} + = icon('fa-caret-down') + = t('terms.advanced_setting') + #advanced-setting.collapse + = field(f, :buffer_type) + = field(f, :buffer_path) + = field(f, :buffer_queue_limit) + = field(f, :buffer_chunk_limit) + = field(f, :flush_interval) + = field(f, :retry_wait) + = field(f, :retry_limit) + = field(f, :max_retry_wait) + = field(f, :num_threads) + = f.submit t('fluentd.common.finish') , class: "btn btn-lg btn-primary pull-right" + = f.submit t('terms.prev'), class: "btn btn-lg btn-default", name: "back" + + diff --git a/app/views/fluentd/settings/out_s3/show.html.haml b/app/views/fluentd/settings/out_s3/show.html.haml new file mode 100644 index 0000000..4cb594e --- /dev/null +++ b/app/views/fluentd/settings/out_s3/show.html.haml @@ -0,0 +1,6 @@ +- page_title t(".page_title") + +.well + = raw t('fluentd.settings.out_td.option_guide') + += render "form" diff --git a/config/routes.rb b/config/routes.rb index 788b1ce..e2c1bc7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -29,6 +29,10 @@ Rails.application.routes.draw do resource :out_td, only: ["show"], module: :settings, controller: :out_td do post "finish" end + + resource :out_s3, only: ["show"], module: :settings, controller: :out_s3 do + post "finish" + end end end