fluent-plugin-calyptia-monitoring 0.1.0.rc6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc96c5b09c542854a7fc86e735d01c1b8d15d6ffcacc35d21bc4e02578f7d379
4
- data.tar.gz: 1deccf93ccb4b41f802099d72b33670459d78c65917af979dd074041de6b964f
3
+ metadata.gz: d30951908ffe3e99416a83ed235545394503652e2052ff85423bbb2216d68c8c
4
+ data.tar.gz: c0d7fa6e044914592e8dc35bb88c3868e97d0344adf01640c2f517441e32bfc6
5
5
  SHA512:
6
- metadata.gz: ba2e21ff1a791fcf81d33d3c568874ac672c3b9882e942007e57c403f2f0d0a12d211b473244bff8303f58bb5b853f2d9acb6c2d527e0d9623484c0a626f26b1
7
- data.tar.gz: 62b0c374c5917ca03d8b836fdf2508838e4cc134d04e25873021fd972fa9914f5a38888e2de62d335b5576883307c343ec72b3f00d5959eb502cf9cd8ec9e87d
6
+ metadata.gz: fe9a55bda096a86b3dd945a42d147da4cd39ace0a11c53ec8effeb70512334104fc2a22c9b853c4fd4a8dd5691a1a0139c7a6a16f2b0029d1bf4b8d98397ecb4
7
+ data.tar.gz: 7274a5ad7cce4240861e71e480b3706c2b43b782abcfc7c5173ff10a9f3ee22810cba67d31521c54e29c0e414b4cc08f858f1dba11aeb92c939f8663519f3ca0
data/README.md CHANGED
@@ -40,10 +40,11 @@ $ bundle
40
40
 
41
41
  |parameter|type|description|default|
42
42
  |---|---|---|---|
43
- |endpoint|string (optional)|The endpoint for Monitoring API HTTP request, e.g. http://example.com/api|`TBD`|
43
+ |endpoint|string (optional)|The endpoint for Monitoring API HTTP request, e.g. http://example.com/api|`"https://cloud-api.calyptia.com"`|
44
44
  |api_key|string (required)|The API KEY for Monitoring API HTTP request||
45
45
  |rate|time (optional)|Emit monitoring values interval. (minimum interval is 30 seconds.)|`30`|
46
46
  |pending_metrics_size|size (optional)|Setup pending metrics capacity size|`100`|
47
+ |fluentd_conf_path|string (optional)|Specify Fluentd config file path for RPC not to be available case|`nil`|
47
48
 
48
49
  ### Example
49
50
 
@@ -84,8 +85,70 @@ And enabling RPC and configDump endpoint is required if sending Fluentd configur
84
85
  </source>
85
86
  ```
86
87
 
88
+ And also retrieving configuration from actual file is also supported:
89
+
90
+ ```aconf
91
+ <system>
92
+ # If users want to use multi workers feature which corresponds to logical number of CPUs, please comment out this line.
93
+ # workers "#{require 'etc'; Etc.nprocessors}"
94
+ enable_input_metrics true
95
+ # This record size measuring settings might impact for performance.
96
+ # Please be careful for high loaded environment to turn on.
97
+ enable_size_metrics true
98
+ <metrics>
99
+ @type cmetrics
100
+ </metrics>
101
+ </system>
102
+ # And other configurations....
103
+
104
+ ## Fill YOUR_API_KEY with your Calyptia API KEY
105
+ <source>
106
+ @type calyptia_monitoring
107
+ @id input_caplyptia_moniroting
108
+ <cloud_monitoring>
109
+ # endpoint http://development-environment-or-production.fqdn:5000
110
+ api_key YOUR_API_KEY
111
+ rate 30
112
+ pending_metrics_size 100 # Specify capacity for pending metrics
113
+ fluentd_conf_path /path/to/fluent.conf
114
+ </cloud_monitoring>
115
+ <storage>
116
+ @type local
117
+ path /path/to/agent/accessible/directories/agent_states
118
+ </storage>
119
+ </source>
120
+ ```
121
+
122
+ **Note:** We recommend to use RPC version due to some circumstances should differ between a loaded configuration and a saved Fluentd configuration.
123
+ This is because calling dumping config RPC feature can obtain from configuration contents which are loaded on memory. But retrieving configuration from the specified file is just read from the file contents and it cannot handle/retrieve loaded configurations on Fluentd.
124
+ When users just update their Fluentd configurations and forgot to restart/reload their Fluentd instances, loaded configurations differ from just edited ones.
125
+
126
+ ## Calyptia Monitoring API config generator
127
+
128
+ Usage:
129
+
130
+ ```
131
+ Usage: calyptia-config-generator api_key [options]
132
+
133
+ Generate Calyptia monitoring plugin config definitions
134
+
135
+ Arguments:
136
+ api_key: Specify your API_KEY
137
+
138
+ Options:
139
+ --endpoint URL API Endpoint URL (default: nil, and if omitted, using default endpoint)
140
+ --rpc-endpoint URL Specify RPC Endpoint URL (default: 127.0.0.1:24444)
141
+ --disable-input-metrics Disable Input plugin metrics. Input metrics is enabled by default
142
+ --enable-size-metrics Enable event size metrics. Size metrics is disabled by default.
143
+ --disable-get-dump Disable RPC getDump procedure. getDump is enabled by default.
144
+ --storage-agent-token-dir DIR
145
+ Specify accesible storage token dir. (default: /path/to/accesible/dir)
146
+ --fluentd-conf-path PATH Specify fluentd configuration file path. (default: nil)
147
+ ```
148
+
87
149
  ## Copyright
88
150
 
89
- * Copyright(c) 2021- Hiroshi Hatake
151
+ * Copyright(c) 2021- Calyptia Inc.
152
+ * Maintainer: Hiroshi Hatake <hatake@calyptia.com>
90
153
  * License
91
154
  * Apache License, Version 2.0
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift(File.join(__dir__, 'lib'))
3
+ require 'fluent/command/config_generator'
4
+
5
+ CalyptiaConfigGenerator.new.call
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = "fluent-plugin-calyptia-monitoring"
6
- spec.version = "0.1.0.rc6"
6
+ spec.version = "0.1.0"
7
7
  spec.authors = ["Hiroshi Hatake"]
8
8
  spec.email = ["hatake@calyptia.com"]
9
9
 
@@ -23,6 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", "~> 2.2.15"
24
24
  spec.add_development_dependency "rake", "~> 13.0"
25
25
  spec.add_development_dependency "test-unit", "~> 3.3"
26
- spec.add_runtime_dependency "fluentd", [">= 1.13.0", "< 2"]
26
+ spec.add_runtime_dependency "fluentd", [">= 1.14.0", "< 2"]
27
27
  spec.add_runtime_dependency "fluent-plugin-metrics-cmetrics", ">= 0.1.0.rc3"
28
28
  end
@@ -0,0 +1,144 @@
1
+ #
2
+ # fluent-plugin-calyptia-monitoring
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require "erb"
17
+ require "optparse"
18
+ require "pathname"
19
+ require "fluent/plugin"
20
+ require "fluent/env"
21
+ require "fluent/engine"
22
+ require "fluent/system_config"
23
+ require "fluent/config/element"
24
+ require 'fluent/version'
25
+
26
+ class CalyptiaConfigGenerator
27
+ def initialize(argv = ARGV)
28
+ @argv = argv
29
+ @api_key = nil
30
+ @endpoint = nil
31
+ @enable_input_metrics = true
32
+ @enable_size_metrics = false
33
+ @enable_get_dump = true
34
+ @rpc_endpoint = "127.0.0.1:24444"
35
+ @storage_agent_token_dir = default_storage_dir
36
+ @fluentd_conf_path = nil
37
+ @disable_rpc = false
38
+
39
+ prepare_option_parser
40
+ end
41
+
42
+ def default_storage_dir
43
+ if Fluent.windows?
44
+ "C:/path/to/accesible/dir"
45
+ else
46
+ "/path/to/accesible/dir"
47
+ end
48
+ end
49
+
50
+ def call
51
+ parse_options!
52
+
53
+ puts dump_configuration_for_calyptia
54
+ end
55
+
56
+ def dump_configuration_for_calyptia
57
+ dumped = ""
58
+ template = template_path("calyptia-conf.erb").read
59
+
60
+ dumped <<
61
+ if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
62
+ ERB.new(template, trim_mode: "-")
63
+ else
64
+ ERB.new(template, nil, "-")
65
+ end.result(binding)
66
+ dumped
67
+ end
68
+ private
69
+
70
+ def prepare_option_parser
71
+ @parser = OptionParser.new
72
+ @parser.version = Fluent::VERSION
73
+ @parser.banner = <<BANNER
74
+ Usage: #{$0} api_key [options]
75
+
76
+ Generate Calyptia monitoring plugin config definitions
77
+
78
+ Arguments:
79
+ \tapi_key: Specify your API_KEY
80
+
81
+ Options:
82
+ BANNER
83
+ @parser.on("--endpoint URL", "API Endpoint URL (default: nil, and if omitted, using default endpoint)") do |s|
84
+ @endpoint = s
85
+ end
86
+ @parser.on("--rpc-endpoint URL", "Specify RPC Endpoint URL (default: 127.0.0.1:24444)") do |s|
87
+ @rpc_endpoint = s
88
+ end
89
+ @parser.on("--disable-input-metrics", "Disable Input plugin metrics. Input metrics is enabled by default") do
90
+ @enable_input_metrics = false
91
+ end
92
+ @parser.on("--enable-size-metrics", "Enable event size metrics. Size metrics is disabled by default.") do
93
+ @enable_size_metrics = true
94
+ end
95
+ @parser.on("--disable-get-dump", "Disable RPC getDump procedure. getDump is enabled by default.") do
96
+ @enable_get_dump = false
97
+ end
98
+ @parser.on("--storage-agent-token-dir DIR", "Specify accesible storage token dir. (default: #{default_storage_dir})") do |s|
99
+ @storage_agent_token_dir = s
100
+ end
101
+ @parser.on("--fluentd-conf-path PATH", "Specify fluentd configuration file path. (default: nil)") do |s|
102
+ @fluentd_conf_path = s
103
+ @disable_rpc = true
104
+ end
105
+ end
106
+
107
+ def usage(message = nil)
108
+ puts @parser.to_s
109
+ puts
110
+ puts "Error: #{message}" if message
111
+ exit(false)
112
+ end
113
+
114
+ def parse_options!
115
+ @parser.parse!(@argv)
116
+
117
+ raise "Must specify api_key" unless @argv.size == 1
118
+
119
+ host, port = @rpc_endpoint.split(':')
120
+ if @enable_get_dump && (!host || !port)
121
+ puts "Error: invalid rpc_endpoint format. Specify `host:port' form."
122
+ exit(false)
123
+ end
124
+
125
+ @api_key, = @argv
126
+ @options = {
127
+ api_key: @api_key,
128
+ endpoint: @endpoint,
129
+ rpc_endpoint: @rpc_endpoint,
130
+ input_metrics: @enable_input_metrics,
131
+ size_metrics: @enable_size_metrics,
132
+ enable_get_dump: @enable_get_dump,
133
+ storage_agent_token_dir: @storage_agent_token_dir,
134
+ fluentd_conf_path: @fluentd_conf_path,
135
+ disable_rpc: @disable_rpc,
136
+ }
137
+ rescue => e
138
+ usage(e)
139
+ end
140
+
141
+ def template_path(name)
142
+ (Pathname(__dir__) + "../../../templates/#{name}").realpath
143
+ end
144
+ end
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fluent/env'
4
+ require 'fluent/engine'
5
+ require 'fluent/log'
6
+ require 'fluent/config'
7
+ require 'fluent/configurable'
8
+ require 'fluent/system_config'
9
+ require 'fluent/config/element'
10
+ require 'serverengine'
11
+ require 'stringio'
12
+
13
+ include Fluent::Configurable
14
+
15
+ def init_log
16
+ dl_opts = {}
17
+ dl_opts[:log_level] = ServerEngine::DaemonLogger::WARN
18
+ @sio = StringIO.new('', 'r+')
19
+ logger = ServerEngine::DaemonLogger.new(@sio, dl_opts)
20
+ $log = Fluent::Log.new(logger)
21
+ end
22
+
23
+ init_log
24
+
25
+ File.open(ENV["FLUENT_CONFIG_PATH"], "r") do |f|
26
+ config = Fluent::Config.parse(f.read, '(supervisor)', '(readFromFile)', true)
27
+ system_config = Fluent::SystemConfig.create(config)
28
+ Fluent::Engine.init(system_config, supervisor_mode: true)
29
+ Fluent::Engine.run_configure(config, dry_run: true)
30
+ confs = []
31
+ masked_element = config.to_masked_element
32
+ masked_element.elements.each{|e|
33
+ confs << e.to_s
34
+ }
35
+ puts confs.join
36
+ end
@@ -0,0 +1,87 @@
1
+ #
2
+ # fluent-plugin-calyptia-monitoring
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'fluent/plugin/in_monitor_agent'
17
+
18
+ module Fluent::Plugin
19
+ class CalyptiaMonitoringBufferExtInput < MonitorAgentInput
20
+ CALYPTIA_PLUGIN_BUFFER_METRIC_INFO = {
21
+ 'buffer_total_queued_size' => ->() {
22
+ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer)
23
+ @buffer.total_queued_size_metrics.cmetrics.to_msgpack
24
+ },
25
+ 'buffer_stage_length' => ->() {
26
+ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer)
27
+ @buffer.stage_length_metrics.cmetrics.to_msgpack
28
+ },
29
+ 'buffer_stage_byte_size' => ->() {
30
+ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer)
31
+ @buffer.stage_size_metrics.cmetrics.to_msgpack
32
+ },
33
+ 'buffer_queue_length' => ->() {
34
+ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer)
35
+ @buffer.queue_length_metrics.cmetrics.to_msgpack
36
+ },
37
+ 'buffer_queue_byte_size' => ->() {
38
+ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer)
39
+ @buffer.queue_size_metrics.cmetrics.to_msgpack
40
+ },
41
+ 'available_buffer_space_ratios' => ->() {
42
+ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer)
43
+ @buffer.available_buffer_space_ratios_metrics.cmetrics.to_msgpack
44
+ },
45
+ 'newest_timekey' => ->() {
46
+ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer)
47
+ @buffer.newest_timekey_metrics.cmetrics.to_msgpack
48
+ },
49
+ 'oldest_timekey' => ->() {
50
+ throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer)
51
+ @buffer.oldest_timekey_metrics.cmetrics.to_msgpack
52
+ },
53
+ }
54
+
55
+ def get_monitor_info(pe, opts = {})
56
+ obj = {}
57
+
58
+ obj['metrics'] = get_plugin_metric(pe)
59
+
60
+ obj
61
+ end
62
+
63
+ def get_plugin_metric(pe)
64
+ # Nop for non output plugin
65
+ return {} if plugin_category(pe) != "output"
66
+
67
+ metrics = {}
68
+
69
+ if pe.respond_to?(:statistics)
70
+ # Force to update buffers' metrics values
71
+ pe.statistics
72
+ end
73
+
74
+ CALYPTIA_PLUGIN_BUFFER_METRIC_INFO.each_pair { |key, code|
75
+ begin
76
+ v = pe.instance_exec(&code)
77
+ unless v.nil?
78
+ metrics[key] = v
79
+ end
80
+ rescue
81
+ end
82
+ }
83
+
84
+ metrics
85
+ end
86
+ end
87
+ end
@@ -37,12 +37,17 @@ module Fluent::Plugin
37
37
  ENV['HTTPS_PROXY'] || ENV['HTTP_PROXY'] || ENV['http_proxy'] || ENV['https_proxy']
38
38
  end
39
39
 
40
+ def create_go_semver(version)
41
+ version.gsub(/.(?<prever>(rc|alpha|beta|pre))/,
42
+ '-\k<prever>')
43
+ end
44
+
40
45
  def agent_metadata(current_config)
41
46
  metadata = {
42
47
  "name" => Socket.gethostname,
43
48
  "type" => "fluentd",
44
49
  "rawConfig" => current_config,
45
- "version" => Fluent::VERSION,
50
+ "version" => create_go_semver(Fluent::VERSION),
46
51
  "edition" => "community".freeze,
47
52
  }
48
53
  if system_config.workers.to_i > 1
@@ -27,9 +27,25 @@ module Fluent::Plugin
27
27
  @emit_records_metrics.cmetrics.to_msgpack
28
28
  },
29
29
  'retry_count' => ->(){
30
- throw(:skip) unless instance_variable_defined?(:@buffer) && !@buffer.nil? && @buffer.is_a?(::Fluent::Plugin::Buffer)
30
+ throw(:skip) if @num_errors_metrics.get.nil?
31
31
  @num_errors_metrics.cmetrics.to_msgpack
32
32
  },
33
+ 'write_count' => ->(){
34
+ throw(:skip) if @write_count_metrics.get.nil?
35
+ @write_count_metrics.cmetrics.to_msgpack
36
+ },
37
+ 'rollback_count' => ->(){
38
+ throw(:skip) if @rollback_count_metrics.get.nil?
39
+ @rollback_count_metrics.cmetrics.to_msgpack
40
+ },
41
+ 'flush_time_count' => ->(){
42
+ throw(:skip) if @flush_time_count_metrics.get.nil?
43
+ @flush_time_count_metrics.cmetrics.to_msgpack
44
+ },
45
+ 'slow_flush_count' => ->(){
46
+ throw(:skip) if @slow_flush_count_metrics.get.nil?
47
+ @slow_flush_count_metrics.cmetrics.to_msgpack
48
+ },
33
49
  }
34
50
 
35
51
  def get_monitor_info(pe, opts = {})
@@ -56,8 +56,7 @@ module Fluent::Plugin
56
56
  @log.info "MachineID is not retrived from ioreg. Using UUID instead."
57
57
  "#{SecureRandom.uuid}:#{@worker_id}"
58
58
  else
59
- # TODO: The prefix should be removed?
60
- "#{SecureRandom.hex(10)}_#{o.strip}:#{@worker_id}"
59
+ "#{o.strip}:#{@worker_id}"
61
60
  end
62
61
  end
63
62
 
@@ -72,8 +71,7 @@ module Fluent::Plugin
72
71
  @log.info "MachineID is not retrived from #{DBUS_MACHINE_ID_PATH} or #{ETC_MACHINE_ID_PATH}. Using UUID instead."
73
72
  "#{SecureRandom.uuid}:#{@worker_id}"
74
73
  else
75
- # TODO: The prefix should be removed?
76
- "#{SecureRandom.hex(10)}_#{machine_id}:#{@worker_id}"
74
+ "#{machine_id}:#{@worker_id}"
77
75
  end
78
76
  end
79
77
 
@@ -88,8 +86,7 @@ module Fluent::Plugin
88
86
  @log.info "MachineID is not retrived from Registry. Using UUID instead."
89
87
  "#{SecureRandom.uuid}:#{@worker_id}"
90
88
  else
91
- # TODO: The prefix should be removed?
92
- "#{SecureRandom.hex(10)}_#{machine_id}:#{@worker_id}"
89
+ "#{machine_id}:#{@worker_id}"
93
90
  end
94
91
  end
95
92
  end
@@ -17,10 +17,11 @@ require 'net/http'
17
17
  require 'monitor'
18
18
  require 'time'
19
19
  require 'fluent/version'
20
- require 'fluent/config/element'
21
- require 'fluent/plugin/metrics'
20
+ require 'fluent/env'
22
21
  require "fluent/plugin/input"
22
+ require "serverengine"
23
23
  require_relative "calyptia_monitoring_ext"
24
+ require_relative "calyptia_monitoring_buffer_ext"
24
25
  require_relative "calyptia_monitoring_calyptia_api_requester"
25
26
 
26
27
  module Fluent
@@ -31,7 +32,7 @@ module Fluent
31
32
  class CreateAgentError < Fluent::ConfigError; end
32
33
  class UpdateAgentError < Fluent::ConfigError; end
33
34
 
34
- helpers :timer, :storage
35
+ helpers :timer, :storage, :child_process
35
36
 
36
37
  RPC_CONFIG_DUMP_ENDPOINT = "/api/config.getDump".freeze
37
38
  DEFAULT_STORAGE_TYPE = 'local'
@@ -52,6 +53,8 @@ module Fluent
52
53
  config_param :rate, :time, default: 30
53
54
  desc 'Setup pending metrics capacity size'
54
55
  config_param :pending_metrics_size, :size, default: DEFAULT_PENDING_METRICS_SIZE
56
+ desc 'Specify Fluentd config file path for RPC not to be available case'
57
+ config_param :fluentd_conf_path, :string, default: nil
55
58
  end
56
59
 
57
60
  def multi_workers_ready?
@@ -67,6 +70,7 @@ module Fluent
67
70
 
68
71
  def configure(conf)
69
72
  super
73
+
70
74
  config = conf.elements.select{|e| e.name == 'storage' }.first
71
75
  @storage_agent = storage_create(usage: 'calyptia_monitoring_agent', conf: config, default_type: DEFAULT_STORAGE_TYPE)
72
76
  end
@@ -83,6 +87,43 @@ module Fluent
83
87
  confs.join
84
88
  end
85
89
 
90
+ def get_masked_conf_from_conf_file
91
+ return "" unless File.exist?(@cloud_monitoring.fluentd_conf_path) # check file existence.
92
+
93
+ conf = ""
94
+ callback = ->(status) {
95
+ if status && status.success?
96
+ #nop
97
+ elsif status
98
+ log.warn "config dumper exits with error code", prog: prog, status: status.exitstatus, signal: status.termsig
99
+ else
100
+ log.warn "config dumper unexpectedly exits without exit status", prog: prog
101
+ end
102
+ }
103
+ spawn_command, arguments = if Fluent.windows?
104
+ [::ServerEngine.ruby_bin_path, File.join(File.dirname(__FILE__), "calyptia_config_dumper.rb")]
105
+ else
106
+ [File.join(File.dirname(__FILE__), "calyptia_config_dumper.rb")]
107
+ end
108
+
109
+ retval = child_process_execute(:exec_calyptia_config_dumper, spawn_command, arguments: arguments, immediate: true,
110
+ env: {"FLUENT_CONFIG_PATH" => @cloud_monitoring.fluentd_conf_path}, parallel: true, mode: [:read_with_stderr],
111
+ on_exit_callback: callback) do |io|
112
+ io.set_encoding(Encoding::ASCII_8BIT)
113
+ conf = io.read
114
+ end
115
+ unless retval.nil?
116
+ begin
117
+ Timeout.timeout(10) do
118
+ sleep 0.1 until !conf.empty?
119
+ end
120
+ rescue Timeout::Error
121
+ log.warn "cannot retrive configuration contents on #{@cloud_monitoring.fluentd_conf_path} within 10 seconds."
122
+ end
123
+ end
124
+ conf
125
+ end
126
+
86
127
  def start
87
128
  super
88
129
 
@@ -93,13 +134,16 @@ module Fluent
93
134
  end
94
135
  raise Fluent::ConfigError, "cmetrics plugin should be used to collect metrics on Calyptia Cloud" unless enabled_cmetrics
95
136
  @monitor_agent = Fluent::Plugin::CalyptiaMonitoringExtInput.new
137
+ @monitor_agent_buffer = Fluent::Plugin::CalyptiaMonitoringBufferExtInput.new
96
138
  @api_requester = Fluent::Plugin::CalyptiaAPI::Requester.new(@cloud_monitoring.endpoint,
97
139
  @cloud_monitoring.api_key,
98
140
  log,
99
141
  fluentd_worker_id)
100
- if check_config_sending_usability
101
- @current_config = get_current_config_from_rpc
102
- end
142
+ @current_config = if !@cloud_monitoring.fluentd_conf_path.nil?
143
+ get_masked_conf_from_conf_file
144
+ elsif check_config_sending_usability
145
+ get_current_config_from_rpc
146
+ end
103
147
 
104
148
  if @cloud_monitoring.rate < 30
105
149
  log.warn "High frequency events ingestion is not supported. Set up 30s as ingestion interval"
@@ -114,7 +158,7 @@ module Fluent
114
158
 
115
159
  def create_agent(current_config)
116
160
  code, agent, machine_id = @api_requester.create_agent(current_config)
117
- if agent["error"].nil?
161
+ if code.to_s.start_with?("2")
118
162
  @storage_agent.put(:agent, agent)
119
163
  @storage_agent.put(:machine_id, machine_id)
120
164
  return true
@@ -222,6 +266,12 @@ module Fluent
222
266
  buffer += v
223
267
  end
224
268
  }
269
+ @monitor_agent_buffer.plugins_info_all(opts).each {|record|
270
+ metrics = record["metrics"]
271
+ metrics.each_pair do |k, v|
272
+ buffer += v
273
+ end
274
+ }
225
275
  if buffer.empty?
226
276
  log.debug "No initialized metrics is found. Trying to send cmetrics on the next tick."
227
277
  else
@@ -0,0 +1,28 @@
1
+ <system>
2
+ <metrics>
3
+ @type cmetrics
4
+ </metrics>
5
+ enable_input_metrics <%= @enable_input_metrics %>
6
+ enable_size_metrics <%= @enable_size_metrics %>
7
+ <%- unless @disable_rpc -%>
8
+ rpc_endpoint <%= @rpc_endpoint %>
9
+ enable_get_dump <%= @enable_get_dump %>
10
+ <%- end -%>
11
+ <system>
12
+ <source>
13
+ @type calyptia_monitoring
14
+ @id input_caplyptia_monitoring
15
+ <cloud_monitoring>
16
+ <%- if @endpoint -%>
17
+ endpoint <%= @endpoint %>
18
+ <%- end -%>
19
+ api_key <%= @api_key %>
20
+ <%- if @fluentd_conf_path -%>
21
+ fluentd_conf_path <%= @fluentd_conf_path %>
22
+ <%- end -%>
23
+ </cloud_monitoring>
24
+ <storage>
25
+ @type local
26
+ path <%= @storage_agent_token_dir %>/agent_state
27
+ </storage>
28
+ </source>
@@ -0,0 +1,230 @@
1
+ require 'helper'
2
+ require 'tmpdir'
3
+ require 'fluent/command/config_generator'
4
+
5
+ class TestCalyptiaConfigGenerator < Test::Unit::TestCase
6
+ def stringio_stdout
7
+ out = StringIO.new
8
+ $stdout = out
9
+ yield
10
+ out.string.force_encoding('utf-8')
11
+ ensure
12
+ $stdout = STDOUT
13
+ end
14
+
15
+ def default_storage_dir
16
+ if Fluent.windows?
17
+ "C:/path/to/accesible/dir"
18
+ else
19
+ "/path/to/accesible/dir"
20
+ end
21
+ end
22
+
23
+ sub_test_case "generate configuration" do
24
+ test "with only api_key" do
25
+ dumped_config = capture_stdout do
26
+ CalyptiaConfigGenerator.new(["YOUR_API_KEY"]).call
27
+ end
28
+ expected =<<TEXT
29
+ <system>
30
+ <metrics>
31
+ @type cmetrics
32
+ </metrics>
33
+ enable_input_metrics true
34
+ enable_size_metrics false
35
+ rpc_endpoint 127.0.0.1:24444
36
+ enable_get_dump true
37
+ <system>
38
+ <source>
39
+ @type calyptia_monitoring
40
+ @id input_caplyptia_monitoring
41
+ <cloud_monitoring>
42
+ api_key YOUR_API_KEY
43
+ </cloud_monitoring>
44
+ <storage>
45
+ @type local
46
+ path #{default_storage_dir}/agent_state
47
+ </storage>
48
+ </source>
49
+ TEXT
50
+ assert_equal(expected, dumped_config)
51
+ end
52
+
53
+ test "with api_key and enable_input_metrics" do
54
+ dumped_config = capture_stdout do
55
+ CalyptiaConfigGenerator.new(["YOUR_API_KEY", "--disable-input-metrics"]).call
56
+ end
57
+ expected =<<TEXT
58
+ <system>
59
+ <metrics>
60
+ @type cmetrics
61
+ </metrics>
62
+ enable_input_metrics false
63
+ enable_size_metrics false
64
+ rpc_endpoint 127.0.0.1:24444
65
+ enable_get_dump true
66
+ <system>
67
+ <source>
68
+ @type calyptia_monitoring
69
+ @id input_caplyptia_monitoring
70
+ <cloud_monitoring>
71
+ api_key YOUR_API_KEY
72
+ </cloud_monitoring>
73
+ <storage>
74
+ @type local
75
+ path #{default_storage_dir}/agent_state
76
+ </storage>
77
+ </source>
78
+ TEXT
79
+ assert_equal(expected, dumped_config)
80
+ end
81
+
82
+ test "with api_key and rpc-endpoint" do
83
+ dumped_config = capture_stdout do
84
+ CalyptiaConfigGenerator.new(["YOUR_API_KEY", "--rpc-endpoint", "localhost:24445"]).call
85
+ end
86
+ expected =<<TEXT
87
+ <system>
88
+ <metrics>
89
+ @type cmetrics
90
+ </metrics>
91
+ enable_input_metrics true
92
+ enable_size_metrics false
93
+ rpc_endpoint localhost:24445
94
+ enable_get_dump true
95
+ <system>
96
+ <source>
97
+ @type calyptia_monitoring
98
+ @id input_caplyptia_monitoring
99
+ <cloud_monitoring>
100
+ api_key YOUR_API_KEY
101
+ </cloud_monitoring>
102
+ <storage>
103
+ @type local
104
+ path #{default_storage_dir}/agent_state
105
+ </storage>
106
+ </source>
107
+ TEXT
108
+ assert_equal(expected, dumped_config)
109
+ end
110
+
111
+ test "with api_key and enable_size_metrics" do
112
+ dumped_config = capture_stdout do
113
+ CalyptiaConfigGenerator.new(["YOUR_API_KEY", "--enable-size-metrics"]).call
114
+ end
115
+ expected =<<TEXT
116
+ <system>
117
+ <metrics>
118
+ @type cmetrics
119
+ </metrics>
120
+ enable_input_metrics true
121
+ enable_size_metrics true
122
+ rpc_endpoint 127.0.0.1:24444
123
+ enable_get_dump true
124
+ <system>
125
+ <source>
126
+ @type calyptia_monitoring
127
+ @id input_caplyptia_monitoring
128
+ <cloud_monitoring>
129
+ api_key YOUR_API_KEY
130
+ </cloud_monitoring>
131
+ <storage>
132
+ @type local
133
+ path #{default_storage_dir}/agent_state
134
+ </storage>
135
+ </source>
136
+ TEXT
137
+ assert_equal(expected, dumped_config)
138
+ end
139
+
140
+ test "with api_key and disable_get_dump" do
141
+ dumped_config = capture_stdout do
142
+ CalyptiaConfigGenerator.new(["YOUR_API_KEY", "--disable-get-dump"]).call
143
+ end
144
+ expected =<<TEXT
145
+ <system>
146
+ <metrics>
147
+ @type cmetrics
148
+ </metrics>
149
+ enable_input_metrics true
150
+ enable_size_metrics false
151
+ rpc_endpoint 127.0.0.1:24444
152
+ enable_get_dump false
153
+ <system>
154
+ <source>
155
+ @type calyptia_monitoring
156
+ @id input_caplyptia_monitoring
157
+ <cloud_monitoring>
158
+ api_key YOUR_API_KEY
159
+ </cloud_monitoring>
160
+ <storage>
161
+ @type local
162
+ path #{default_storage_dir}/agent_state
163
+ </storage>
164
+ </source>
165
+ TEXT
166
+ assert_equal(expected, dumped_config)
167
+ end
168
+
169
+ test "with api_key and storage_agent_token_dir" do
170
+ storage_dir = Dir.tmpdir
171
+ dumped_config = capture_stdout do
172
+ CalyptiaConfigGenerator.new(["YOUR_API_KEY", "--storage_agent_token_dir", storage_dir]).call
173
+ end
174
+ expected =<<TEXT
175
+ <system>
176
+ <metrics>
177
+ @type cmetrics
178
+ </metrics>
179
+ enable_input_metrics true
180
+ enable_size_metrics false
181
+ rpc_endpoint 127.0.0.1:24444
182
+ enable_get_dump true
183
+ <system>
184
+ <source>
185
+ @type calyptia_monitoring
186
+ @id input_caplyptia_monitoring
187
+ <cloud_monitoring>
188
+ api_key YOUR_API_KEY
189
+ </cloud_monitoring>
190
+ <storage>
191
+ @type local
192
+ path #{storage_dir}/agent_state
193
+ </storage>
194
+ </source>
195
+ TEXT
196
+ assert_equal(expected, dumped_config)
197
+ end
198
+
199
+ test "with api_key and fluentd_config_path" do
200
+ storage_dir = Dir.tmpdir
201
+ conf_dir = Dir.tmpdir
202
+ conf_path = File.join(conf_dir, "fluent.conf")
203
+ dumped_config = capture_stdout do
204
+ CalyptiaConfigGenerator.new(["YOUR_API_KEY", "--storage_agent_token_dir", storage_dir, "--fluentd-conf-path", conf_path]).call
205
+ end
206
+ expected =<<TEXT
207
+ <system>
208
+ <metrics>
209
+ @type cmetrics
210
+ </metrics>
211
+ enable_input_metrics true
212
+ enable_size_metrics false
213
+ <system>
214
+ <source>
215
+ @type calyptia_monitoring
216
+ @id input_caplyptia_monitoring
217
+ <cloud_monitoring>
218
+ api_key YOUR_API_KEY
219
+ fluentd_conf_path #{conf_path}
220
+ </cloud_monitoring>
221
+ <storage>
222
+ @type local
223
+ path #{storage_dir}/agent_state
224
+ </storage>
225
+ </source>
226
+ TEXT
227
+ assert_equal(expected, dumped_config)
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,29 @@
1
+ require "helper"
2
+ require "logger"
3
+ require "fluent/plugin/calyptia_monitoring_calyptia_api_requester"
4
+
5
+ class CalyptiaMonitoringMachineIdTest < Test::Unit::TestCase
6
+ API_KEY = 'YOUR_API_KEY'.freeze
7
+ API_ENDPOINT = "https://cloud-api.calyptia.com".freeze
8
+
9
+ setup do
10
+ @log = Logger.new($stdout)
11
+ worker_id = [1,2,3,4,5,6,7,8,9,10,11].sample
12
+ @api_requester = Fluent::Plugin::CalyptiaAPI::Requester.new(API_ENDPOINT,
13
+ API_KEY,
14
+ @log,
15
+ worker_id)
16
+ end
17
+
18
+ data("rc" => ["1.14.0.rc", "1.14.0-rc"],
19
+ "rc2" => ["1.14.0.rc2", "1.14.0-rc2"],
20
+ "alpha" => ["1.14.0.alpha", "1.14.0-alpha"],
21
+ "beta" => ["1.14.0.beta", "1.14.0-beta"],
22
+ "pre" => ["1.14.0.pre", "1.14.0-pre"],
23
+ )
24
+ def test_create_go_semver(data)
25
+ version, expected = data
26
+ actual = @api_requester.create_go_semver(version)
27
+ assert_equal expected, actual
28
+ end
29
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-calyptia-monitoring
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.rc6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi Hatake
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-02 00:00:00.000000000 Z
11
+ date: 2021-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 1.13.0
61
+ version: 1.14.0
62
62
  - - "<"
63
63
  - !ruby/object:Gem::Version
64
64
  version: '2'
@@ -68,7 +68,7 @@ dependencies:
68
68
  requirements:
69
69
  - - ">="
70
70
  - !ruby/object:Gem::Version
71
- version: 1.13.0
71
+ version: 1.14.0
72
72
  - - "<"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '2'
@@ -89,7 +89,8 @@ dependencies:
89
89
  description: Monitoring Fluentd via Calyptia Cloud
90
90
  email:
91
91
  - hatake@calyptia.com
92
- executables: []
92
+ executables:
93
+ - calyptia-config-generator
93
94
  extensions: []
94
95
  extra_rdoc_files: []
95
96
  files:
@@ -98,12 +99,19 @@ files:
98
99
  - LICENSE
99
100
  - README.md
100
101
  - Rakefile
102
+ - bin/calyptia-config-generator
101
103
  - fluent-plugin-calyptia-monitoring.gemspec
104
+ - lib/fluent/command/config_generator.rb
105
+ - lib/fluent/plugin/calyptia_config_dumper.rb
106
+ - lib/fluent/plugin/calyptia_monitoring_buffer_ext.rb
102
107
  - lib/fluent/plugin/calyptia_monitoring_calyptia_api_requester.rb
103
108
  - lib/fluent/plugin/calyptia_monitoring_ext.rb
104
109
  - lib/fluent/plugin/calyptia_monitoring_machine_id.rb
105
110
  - lib/fluent/plugin/in_calyptia_monitoring.rb
111
+ - templates/calyptia-conf.erb
112
+ - test/command/test_config_generator.rb
106
113
  - test/helper.rb
114
+ - test/plugin/test_calyptia_monitoring_calyptia_api_requester.rb
107
115
  - test/plugin/test_calyptia_montoring_machine_id.rb
108
116
  - test/plugin/test_in_calyptia_monitoring.rb
109
117
  homepage: https://github.com/calyptia/fluent-plugin-calyptia-monitoring
@@ -121,15 +129,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
129
  version: '0'
122
130
  required_rubygems_version: !ruby/object:Gem::Requirement
123
131
  requirements:
124
- - - ">"
132
+ - - ">="
125
133
  - !ruby/object:Gem::Version
126
- version: 1.3.1
134
+ version: '0'
127
135
  requirements: []
128
136
  rubygems_version: 3.2.22
129
137
  signing_key:
130
138
  specification_version: 4
131
139
  summary: Monitoring Fluentd via Calyptia Cloud
132
140
  test_files:
141
+ - test/command/test_config_generator.rb
133
142
  - test/helper.rb
143
+ - test/plugin/test_calyptia_monitoring_calyptia_api_requester.rb
134
144
  - test/plugin/test_calyptia_montoring_machine_id.rb
135
145
  - test/plugin/test_in_calyptia_monitoring.rb