fluentd-ui 0.3.11 → 0.3.12

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd-ui might be problematic. Click here for more details.

Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +11 -0
  3. data/Gemfile.lock +1 -1
  4. data/app/assets/stylesheets/common.css.scss +4 -0
  5. data/app/controllers/application_controller.rb +25 -15
  6. data/app/controllers/concerns/setting_history_concern.rb +28 -0
  7. data/app/controllers/fluentd/agents_controller.rb +13 -15
  8. data/app/controllers/fluentd/settings/histories_controller.rb +3 -13
  9. data/app/controllers/fluentd/settings/notes_controller.rb +16 -0
  10. data/app/controllers/fluentd/settings/running_backup_controller.rb +2 -12
  11. data/app/controllers/fluentd/settings_controller.rb +2 -2
  12. data/app/controllers/misc_controller.rb +27 -18
  13. data/app/controllers/polling_controller.rb +10 -13
  14. data/app/helpers/settings_helper.rb +67 -29
  15. data/app/models/{fluentd/setting/backup_file.rb → concerns/fluentd/setting_archive/archivable.rb} +11 -11
  16. data/app/models/fluent_gem.rb +1 -1
  17. data/app/models/fluentd/agent/fluentd_gem.rb +7 -3
  18. data/app/models/fluentd/agent/local_common.rb +44 -9
  19. data/app/models/fluentd/agent/td_agent/macosx.rb +5 -2
  20. data/app/models/fluentd/agent/td_agent/unix.rb +4 -0
  21. data/app/models/fluentd/setting/out_s3.rb +3 -3
  22. data/app/models/fluentd/setting_archive/backup_file.rb +20 -0
  23. data/app/models/fluentd/setting_archive/note.rb +28 -0
  24. data/app/models/plugin.rb +12 -6
  25. data/app/views/fluentd/settings/histories/_list.html.haml +17 -6
  26. data/app/views/fluentd/settings/histories/show.html.haml +12 -2
  27. data/app/views/fluentd/settings/running_backup/show.html.haml +8 -3
  28. data/app/views/layouts/application.html.erb +1 -1
  29. data/app/views/plugins/updated.html.haml +21 -19
  30. data/app/views/shared/_flash.html.haml +3 -0
  31. data/config/locales/translation_en.yml +5 -0
  32. data/config/locales/translation_ja.yml +5 -0
  33. data/config/routes.rb +4 -0
  34. data/lib/file_reverse_reader.rb +38 -13
  35. data/lib/fluentd-ui/version.rb +1 -1
  36. data/spec/controllers/application_controller_spec.rb +88 -0
  37. data/spec/controllers/fluentd/agents_controller_spec.rb +45 -0
  38. data/spec/controllers/misc_controller_spec.rb +68 -0
  39. data/spec/controllers/polling_controller_spec.rb +34 -0
  40. data/spec/features/fluentd/setting/histories_spec.rb +87 -0
  41. data/spec/features/fluentd/setting/notes_spec.rb +27 -0
  42. data/spec/features/fluentd/setting/out_forward_spec.rb +40 -0
  43. data/spec/features/fluentd/setting/{ranning_backup_spec.rb → running_backup_spec.rb} +36 -0
  44. data/spec/features/setting_spec.rb +2 -2
  45. data/spec/models/fluentd/agent_spec.rb +49 -0
  46. data/spec/support/fixtures/error3.log +7 -0
  47. data/spec/support/fluentd_agent_common_behavior.rb +14 -0
  48. metadata +23 -13
  49. data/app/helpers/miscs_helper.rb +0 -2
  50. data/db/seeds.rb +0 -7
  51. data/spec/controllers/plugins_controller_spec.rb +0 -5
  52. data/spec/controllers/tutorials_controller_spec.rb +0 -5
  53. data/spec/features/fluentd/setting/hisotries_spec.rb +0 -48
@@ -1,21 +1,21 @@
1
1
  class Fluentd
2
- module Setting
3
- class BackupFile
2
+ module SettingArchive
3
+ module Archivable
4
+ extend ActiveSupport::Concern
4
5
  attr_accessor :file_path
5
6
 
6
- def self.find_by_file_id(backup_dir, file_id)
7
- file_path = Pathname.new(backup_dir).join("#{file_id}.conf")
8
- raise "No such a file #{file_path}" unless File.exist?(file_path)
7
+ module ClassMethods
8
+ private
9
9
 
10
- new(file_path)
11
- end
12
-
13
- def initialize(file_path)
14
- @file_path = file_path
10
+ def file_path_of(dir, id)
11
+ file_path = Pathname.new(dir).join("#{id}#{self::FILE_EXTENSION}")
12
+ raise "No such a file #{file_path}" unless File.exist?(file_path)
13
+ file_path
14
+ end
15
15
  end
16
16
 
17
17
  def file_id
18
- @file_id ||= with_file { name.gsub(/.conf\Z/,'') }
18
+ @file_id ||= with_file { name.gsub(/#{Regexp.escape(self.class::FILE_EXTENSION)}\Z/,'') }
19
19
  end
20
20
 
21
21
  def name
@@ -21,7 +21,7 @@ module FluentGem
21
21
  if $? && $?.exitstatus != 0 # NOTE: $? will be nil on CircleCI, so check $? at first
22
22
  raise GemError, "failed command: `#{gem} list`"
23
23
  end
24
- output.lines
24
+ output.lines.to_a
25
25
  end
26
26
  end
27
27
 
@@ -42,6 +42,12 @@ class Fluentd
42
42
  actual_reload
43
43
  end
44
44
 
45
+ def dryrun
46
+ Bundler.with_clean_env do
47
+ system("fluentd -q --dry-run #{options_to_argv}")
48
+ end
49
+ end
50
+
45
51
  def version
46
52
  Bundler.with_clean_env do
47
53
  `fluentd --version`.strip
@@ -60,9 +66,7 @@ class Fluentd
60
66
  end
61
67
 
62
68
  def validate_fluentd_options
63
- Bundler.with_clean_env do
64
- system("fluentd --dry-run #{options_to_argv}")
65
- end
69
+ dryrun
66
70
  end
67
71
 
68
72
  def actual_start
@@ -89,8 +89,9 @@ class Fluentd
89
89
  return if over_file_count <= 0
90
90
 
91
91
  backup_files_in_old_order.first(over_file_count).each do |file|
92
- next unless File.exist? file
93
- FileUtils.rm(file)
92
+ note_file_attached_backup = file.sub(/#{Regexp.escape(File.extname(file))}\z/, ::Fluentd::SettingArchive::Note::FILE_EXTENSION)
93
+ FileUtils.rm(note_file_attached_backup) if File.exist? note_file_attached_backup
94
+ FileUtils.rm(file) if File.exist? file
94
95
  end
95
96
  end
96
97
 
@@ -116,12 +117,14 @@ class Fluentd
116
117
  # 2014-06-30 11:24:08 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.2/lib/ruby/2.1.0/socket.rb:461:in `block in tcp_server_sockets'
117
118
  # ]
118
119
  # }
119
- subject, *notes = *buf.reverse
120
- block.call({
121
- subject: subject,
122
- notes: notes,
123
- })
120
+ split_error_lines_to_error_units(buf.reverse).each do |error_unit|
121
+ block.call({
122
+ subject: error_unit[:subject],
123
+ notes: error_unit[:notes],
124
+ })
125
+ end
124
126
  end
127
+
125
128
  buf = []
126
129
  next
127
130
  end
@@ -131,12 +134,44 @@ class Fluentd
131
134
  io && io.close
132
135
  end
133
136
 
137
+ def split_error_lines_to_error_units(buf)
138
+ # NOTE: if a following log is given
139
+ #
140
+ #2014-05-27 10:54:37 +0900 [error]: unexpected error error_class=Errno::EADDRINUSE error=#<Errno::#EADDRINUSE: Address already in use - bind(2) for "0.0.0.0" port 24224>
141
+ #2014-05-27 10:55:40 +0900 [error]: unexpected error error_class=Errno::EADDRINUSE error=#<Errno::#EADDRINUSE: Address already in use - bind(2) for "0.0.0.0" port 24224>
142
+ # 2014-05-27 10:55:40 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `initialize'
143
+ # 2014-05-27 10:55:40 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `new'
144
+ #
145
+ #the first line and second line must be each "error_unit". and after third lines lines are "notes" of second error unit of .
146
+ # [
147
+ # { subject: "2014-05-27 10:54:37 +0900 [error]: unexpected error error_class=Errno::EADDRINUSE error=#<Errno::#EADDRINUSE: Address already in use - bind(2) for "0.0.0.0" port 24224> ",
148
+ # notes: [] },
149
+ # { subject: "2014-05-27 10:55:40 +0900 [error]: unexpected error error_class=Errno::EADDRINUSE error=#<Errno::#EADDRINUSE: Address already in use - bind(2) for "0.0.0.0" port 24224> ",
150
+ # notes: [
151
+ # "2014-05-27 10:55:40 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `initialize'",
152
+ # "2014-05-27 10:55:40 +0900 [error]: /Users/uu59/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/cool.io-1.2.4/lib/cool.io/server.rb:57:in `new'"
153
+ # ]
154
+ # },
155
+ # ]
156
+ #
157
+ return_array = []
158
+ buf.each_with_index do |b, i|
159
+ if b.match(/\A /)
160
+ return_array[-1][:notes] << b
161
+ else
162
+ return_array << { subject: b, notes: [] }
163
+ end
164
+ end
165
+ return return_array.reverse
166
+ end
167
+
134
168
  def detached_command(cmd)
135
- Bundler.with_clean_env do
169
+ thread = Bundler.with_clean_env do
136
170
  pid = spawn(cmd)
137
171
  Process.detach(pid)
138
172
  end
139
- sleep 1 # NOTE/FIXME: too early return will be caused incorrect status report, "sleep 1" is a adhoc hack
173
+ thread.join
174
+ thread.value.exitstatus.zero?
140
175
  end
141
176
  end
142
177
  end
@@ -2,7 +2,6 @@ class Fluentd
2
2
  class Agent
3
3
  class TdAgent
4
4
  module Macosx
5
-
6
5
  def start
7
6
  backup_running_config do
8
7
  detached_command("launchctl load #{plist}") && pid_from_launchctl
@@ -14,7 +13,11 @@ class Fluentd
14
13
  end
15
14
 
16
15
  def restart
17
- stop && start
16
+ dryrun && stop && start
17
+ end
18
+
19
+ def dryrun
20
+ detached_command("/usr/sbin/td-agent --dry-run -q --use-v1-config -c #{config_file}")
18
21
  end
19
22
 
20
23
  private
@@ -17,6 +17,10 @@ class Fluentd
17
17
  # https://github.com/treasure-data/td-agent/blob/master/debian/td-agent.init#L156
18
18
  detached_command('/etc/init.d/td-agent restart')
19
19
  end
20
+
21
+ def dryrun
22
+ detached_command('/etc/init.d/td-agent configtest')
23
+ end
20
24
  end
21
25
  end
22
26
  end
@@ -6,7 +6,7 @@ class Fluentd
6
6
 
7
7
  KEYS = [
8
8
  :match,
9
- :aws_key_id, :aws_sec_key, :s3_bucket, :s3_endpoint, :path,
9
+ :aws_key_id, :aws_sec_key, :s3_bucket, :s3_region, :path,
10
10
  # :reduced_redundancy, :check_apikey_on_start, :command_parameter, # not configurable?
11
11
  :format, :include_time_key, :time_key, :delimiter, :label_delimiter, :add_newline, :output_tag, :output_time,
12
12
  :time_slice_format, :time_slice_wait, :time_format, :utc, :store_as, :proxy_uri, :use_ssl,
@@ -27,7 +27,7 @@ class Fluentd
27
27
 
28
28
  def self.initial_params
29
29
  {
30
- s3_endpoint: "s3-us-west-1.amazonaws.com",
30
+ s3_region: "us-west-1",
31
31
  output_tag: true,
32
32
  output_time: true,
33
33
  use_ssl: true,
@@ -37,7 +37,7 @@ class Fluentd
37
37
  def common_options
38
38
  [
39
39
  :match, :aws_key_id, :aws_sec_key,
40
- :s3_endpoint, :s3_bucket, :use_ssl, :path,
40
+ :s3_region, :s3_bucket, :use_ssl, :path,
41
41
  ]
42
42
  end
43
43
 
@@ -0,0 +1,20 @@
1
+ class Fluentd
2
+ module SettingArchive
3
+ class BackupFile
4
+ include Archivable
5
+ attr_reader :note
6
+
7
+ FILE_EXTENSION = ".conf".freeze
8
+
9
+ def self.find_by_file_id(backup_dir, file_id)
10
+ note = Note.find_by_file_id(backup_dir, file_id) rescue nil
11
+ new(file_path_of(backup_dir, file_id), note)
12
+ end
13
+
14
+ def initialize(file_path, note = nil)
15
+ @file_path = file_path
16
+ @note = note || Note.create(file_path.sub(/#{Regexp.escape(FILE_EXTENSION)}\z/, Note::FILE_EXTENSION))
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ class Fluentd
2
+ module SettingArchive
3
+ class Note
4
+ include Archivable
5
+
6
+ FILE_EXTENSION = ".note".freeze
7
+
8
+ def self.find_by_file_id(backup_dir, file_id)
9
+ new(file_path_of(backup_dir, file_id))
10
+ end
11
+
12
+ def self.create(file_path)
13
+ FileUtils.touch(file_path)
14
+ new(file_path)
15
+ end
16
+
17
+ def initialize(file_path)
18
+ @file_path = file_path
19
+ end
20
+
21
+ def update!(content)
22
+ File.open(@file_path, "w") do |f|
23
+ f.write content
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -68,13 +68,11 @@ class Plugin
68
68
  end
69
69
 
70
70
  def summary
71
- target_version = self.version || latest_version
72
- JSON.parse(gem_versions).find {|ver| ver["number"] == target_version }.try(:[], "summary")
71
+ property("summary")
73
72
  end
74
73
 
75
74
  def authors
76
- target_version = self.version || latest_version
77
- JSON.parse(gem_versions).find {|ver| ver["number"] == target_version }.try(:[], "authors")
75
+ property("authors")
78
76
  end
79
77
 
80
78
  def inspect
@@ -110,11 +108,11 @@ class Plugin
110
108
  end
111
109
 
112
110
  def self.installing
113
- processing.find_all{|data| data[:type] == :install }.map{|data| data[:plugin] }
111
+ processing_state(:install)
114
112
  end
115
113
 
116
114
  def self.uninstalling
117
- processing.find_all{|data| data[:type] == :uninstall }.map{|data| data[:plugin] }
115
+ processing_state(:uninstall)
118
116
  end
119
117
 
120
118
  def gem_versions
@@ -137,6 +135,14 @@ class Plugin
137
135
  end
138
136
 
139
137
  private
138
+ def self.processing_state(state)
139
+ processing.find_all{|data| data[:type] == state }.map{ |data| data[:plugin] }
140
+ end
141
+
142
+ def property(prop)
143
+ target_version = self.version || latest_version
144
+ JSON.parse(gem_versions).find {|ver| ver["number"] == target_version }.try(:[], prop)
145
+ end
140
146
 
141
147
  def gem_install
142
148
  data = { plugin: self, state: :running, type: :install }
@@ -1,6 +1,17 @@
1
- %ul
2
- - @backup_files.each do |file|
3
- %li
4
- = link_to(file.name, daemon_setting_history_path(id: file.file_id))
5
- %label= t('terms.backup_time')
6
- = file.ctime.strftime(I18n.t 'time.formats.default')
1
+ %table.table.table-hover.table-bordered
2
+ %thead
3
+ %tr
4
+ %th= t('terms.backup_file')
5
+ %th= t('terms.backup_time')
6
+ %th= t('terms.note')
7
+ %tbody
8
+ - @backup_files.each do |file|
9
+ %tr
10
+ %td= link_to(file.name, daemon_setting_history_path(id: file.file_id))
11
+ %td.datetime= file.ctime.strftime t('time.formats.default')
12
+ %td
13
+ = form_for :note, url: daemon_setting_note_path(id: file.note.file_id), method: :patch do |f|
14
+ .form-group.input-group
15
+ = f.text_field :content, value: file.note.content, class: "note-content form-control", id: nil
16
+ %span.input-group-btn
17
+ = submit_tag t('terms.save'), class: 'btn btn-default'
@@ -1,8 +1,18 @@
1
- - page_title t('.page_title', label: @fluentd.label) do
2
- - link_to reuse_daemon_setting_history_path(id: @backup_file.file_id), method: 'post', class: "btn btn-primary pull-right" do
1
+ - page_title t('.page_title', label: @fluentd.label)
2
+
3
+ %p.pull-right
4
+ = link_to configtest_daemon_setting_history_path(id: @backup_file.file_id), method: "post", class: "btn btn-default" do
5
+ = icon('fa-legal')
6
+ = t("terms.configtest")
7
+ = link_to reuse_daemon_setting_history_path(id: @backup_file.file_id), method: 'post', class: "btn btn-primary" do
3
8
  = icon('fa-pencil')
4
9
  = t("terms.reuse")
5
10
 
11
+ - if @backup_file.note.content.present?
12
+ .row
13
+ .col-xs-12
14
+ %p= @backup_file.note.content
15
+
6
16
  .row
7
17
  .col-xs-12
8
18
  %pre
@@ -1,6 +1,11 @@
1
- - page_title t('.page_title', label: @fluentd.label) do
2
- - if @backup_file.content
3
- - link_to reuse_daemon_setting_running_backup_path, method: 'post', class: "btn btn-primary pull-right" do
1
+ - page_title t('.page_title', label: @fluentd.label)
2
+
3
+ - if @backup_file.content
4
+ %p.pull-right
5
+ = link_to configtest_daemon_setting_running_backup_path, method: 'post', class: "btn btn-default" do
6
+ = icon('fa-legal')
7
+ = t("terms.configtest")
8
+ = link_to reuse_daemon_setting_running_backup_path, method: 'post', class: "btn btn-primary" do
4
9
  = icon('fa-pencil')
5
10
  = t("terms.reuse")
6
11
 
@@ -46,7 +46,7 @@
46
46
 
47
47
  <div class="navbar-default navbar-static-side" role="navigation">
48
48
  <div class="sidebar-collapse">
49
- <%= render partial: "shared/global_nav" %>
49
+ <%= render partial: "shared/global_nav" %>
50
50
  <!-- /#side-menu -->
51
51
  </div>
52
52
  <!-- /.sidebar-collapse -->
@@ -5,25 +5,27 @@
5
5
  - else
6
6
  = form_tag(bulk_upgrade_plugins_path, method: :patch) do
7
7
  %table{class: "table table-striped table-hover"}
8
- %tr
9
- %th.col-xs-2= t('plugins.common.name')
10
- %th.col-xs-2= t('plugins.common.authors')
11
- %th.col-xs-6= t('plugins.common.summary')
12
- %th.col-xs-1= t('plugins.common.installed_version')
13
- %th.col-xs-1= t('plugins.common.latest_version')
14
- - @plugins.each do |plugin|
8
+ %thead
15
9
  %tr
16
- %td
17
- = check_box_tag("plugins[]", plugin.gem_name, false, id: "plugin_#{plugin.gem_name}")
18
- %label{for: "plugin_#{plugin.gem_name}"}
19
- = plugin.gem_name
20
- %td
21
- = plugin.authors
22
- %td
23
- = plugin.summary
24
- %td
25
- = plugin.installed_version
26
- %td
27
- = plugin.latest_version
10
+ %th.col-xs-2= t('plugins.common.name')
11
+ %th.col-xs-2= t('plugins.common.authors')
12
+ %th.col-xs-6= t('plugins.common.summary')
13
+ %th.col-xs-1= t('plugins.common.installed_version')
14
+ %th.col-xs-1= t('plugins.common.latest_version')
15
+ %tbody
16
+ - @plugins.each do |plugin|
17
+ %tr
18
+ %td
19
+ = check_box_tag("plugins[]", plugin.gem_name, false, id: "plugin_#{plugin.gem_name}")
20
+ %label{for: "plugin_#{plugin.gem_name}"}
21
+ = plugin.gem_name
22
+ %td
23
+ = plugin.authors
24
+ %td
25
+ = plugin.summary
26
+ %td
27
+ = plugin.installed_version
28
+ %td
29
+ = plugin.latest_version
28
30
  = submit_tag t("terms.install_latest"), class: "btn btn-primary"
29
31
 
@@ -8,3 +8,6 @@
8
8
  - if flash[:info]
9
9
  %p.alert.alert-info
10
10
  =raw flash[:info]
11
+ - if flash[:danger]
12
+ %p.alert.alert-danger
13
+ =raw flash[:danger]
@@ -12,6 +12,8 @@ en:
12
12
  fluentd_status_running: Running
13
13
  fluentd_status_stopped: Stopped
14
14
  config_successfully_copied: "Config has been copied successfully. Please restart %{brand} to use the new config"
15
+ note_updating_success: "Note successfully updated."
16
+ dryrun_is_passed: config test passed
15
17
 
16
18
  terms: &terms
17
19
  name: Name
@@ -59,8 +61,11 @@ en:
59
61
  notice_restart_for_config_edit: "NOTICE: running %{brand} will restart after update config"
60
62
  lines: Lines
61
63
  languages: Language
64
+ backup_file: Backup File
62
65
  backup_time: Backed up at
66
+ note: Note
63
67
  reuse: reuse
68
+ configtest: config test
64
69
 
65
70
  plugins:
66
71
  view_on_rubygems_org: View on rubygems.org