fluent-plugin-http-cwm 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fd32dfa032f161178f7cdbced98e810a58150161c8549505225951197c8b335
4
- data.tar.gz: 18a3d8dcde2bd06e01bcefbc405ed7457f6dffae68c84d43e0e69b67b3e0708e
3
+ metadata.gz: ee799e3ac189ac3437e101b229bf0372b46b853312f45c36c89252f7928e3682
4
+ data.tar.gz: 2ec2f5a36742eb61f7365436d1e19d6ede930b20ad9c08f5cd2612a9af42ee1f
5
5
  SHA512:
6
- metadata.gz: 69211562baa2f6e837823bd92bf58b6aa3be9d55657cc0b2a44aef1e718bbe248c44097df3cc91ef510fa851e9b109122e732e57cfa2743cc83f46a60613c5b0
7
- data.tar.gz: bc0b0cee0e7b24b254f6d432804530399bdcfffb86e1b98bafc52d3f25f74a3ee8c0dcff004b322ea1ce791db356ebf8ae66d2ba43d65618127b37e05f870888
6
+ metadata.gz: f98f46b4cd8e5864bbcd0ea2c1801bda9a18de1116904feaba035a3ece3f2c710cdc525d9f202bd15599c39b978c02e137e9a9c9b42f5b07c5bce529b7f8d17e
7
+ data.tar.gz: 90b110133ed9377e746b81f784fad358830c15660961f2f7cc142a6d5817da2e8d2f8d70018a1614b10e373a49c96c32c23f6f37145c51e9e61a076eeab573ae
@@ -11,7 +11,7 @@ on:
11
11
 
12
12
  jobs:
13
13
  publish:
14
- if: github.event.workflow_run.conclusion == 'success' #&& startsWith(github.ref, 'refs/tags/v')
14
+ if: github.event.workflow_run.conclusion == 'success' && startsWith(github.ref, 'refs/tags/v')
15
15
 
16
16
  name: Publish Gem
17
17
  runs-on: ubuntu-18.04
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-http-cwm (0.2.0)
4
+ fluent-plugin-http-cwm (0.3.0)
5
5
  fluentd (>= 0.14.10, < 2)
6
6
  json (~> 2.3, >= 2.3.0)
7
7
  redis (~> 4.2, >= 4.2.5)
@@ -12,7 +12,7 @@ GEM
12
12
  concurrent-ruby (1.1.8)
13
13
  cool.io (1.7.1)
14
14
  docile (1.3.5)
15
- fluentd (1.12.2)
15
+ fluentd (1.12.3)
16
16
  bundler
17
17
  cool.io (>= 1.4.5, < 2.0.0)
18
18
  http_parser.rb (>= 0.5.1, < 0.7.0)
data/README.md CHANGED
@@ -10,6 +10,17 @@
10
10
  ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/iamAzeem/fluent-plugin-http-cwm?style=flat-square)
11
11
  ![GitHub repo size](https://img.shields.io/github/repo-size/iamAzeem/fluent-plugin-http-cwm?style=flat-square)
12
12
 
13
+ - [Overview](#overview)
14
+ - [Installation](#installation)
15
+ - [RubyGems](#rubygems)
16
+ - [Bundler](#bundler)
17
+ - [Configuration](#configuration)
18
+ - [`<redis>` section (optional) (single)](#redis-section-optional-single)
19
+ - [Sample Configuration](#sample-configuration)
20
+ - [Contribute](#contribute)
21
+ - [Publish the gem](#publish-the-gem)
22
+ - [License](#license)
23
+
13
24
  ## Overview
14
25
 
15
26
  [Fluentd](https://fluentd.org/) HTTP input plugin for
@@ -100,7 +111,7 @@ bundle
100
111
  - Default value: `6379`.
101
112
  - `db` (integer) (optional): The db to use.
102
113
  - Default value: `0`.
103
- - `grace_period` (time) (optional): The grace period for last update.
114
+ - `grace_period` (time) (optional): The grace period for last action update.
104
115
  - Default value: `300s`.
105
116
  - `flush_interval` (time) (optional): The flush interval to send metrics.
106
117
  - Default value: `300s`.
@@ -164,10 +175,21 @@ Example:
164
175
  - Check out the latest `main` branch.
165
176
  - Create a feature or bugfix branch from `main`.
166
177
  - Commit and push your changes.
167
- - Make sure to add tests.
178
+ - Make sure to add and run tests locally: `bundle exec rake test`.
168
179
  - Run Rubocop locally and fix all the lint warnings.
180
+ - Make sure to update [Gemfile.lock](Gemfile.lock): `sudo bundle update`.
169
181
  - Submit the PR.
170
182
 
183
+ ## Publish the gem
184
+
185
+ The gem is published via the [publish.yml](.github/workflows/publish.yml)
186
+ Workflow on tagging. The tag must be of the format `v0.3.0`. This workflow
187
+ depends on the successful completion of the [ci.yml](.github/workflows/ci.yml)
188
+ workflow and then it looks for the tag. So, make sure that all the CI issues are
189
+ resolved before creating a new tag. If there are issues while publishing the gem
190
+ i.e. publish workflow doesn't work properly, you can delete and then recreate
191
+ the tag to retrigger this workflow.
192
+
171
193
  ## License
172
194
 
173
195
  [Apache 2.0](./LICENSE)
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'fluent-plugin-http-cwm'
8
- spec.version = '0.2.0'
8
+ spec.version = '0.3.0'
9
9
  spec.authors = ['Azeem Sajid']
10
10
  spec.email = ['azeem.sajid@gmail.com']
11
11
 
@@ -53,7 +53,7 @@ module Fluent
53
53
  desc 'The db to use.'
54
54
  config_param :db, :integer, default: 0
55
55
 
56
- desc 'The grace period for last update.'
56
+ desc 'The grace period for last action update.'
57
57
  config_param :grace_period, :time, default: '300s'
58
58
 
59
59
  desc 'The flush interval to send metrics.'
@@ -71,6 +71,9 @@ module Fluent
71
71
 
72
72
  @redis = nil
73
73
  @deployment_api_metrics = default_api_metrics_hash
74
+
75
+ @last_action_queue = Queue.new
76
+ @last_action_entry = []
74
77
  end
75
78
 
76
79
  def configure(conf)
@@ -82,18 +85,23 @@ module Fluent
82
85
  def start
83
86
  super
84
87
 
85
- # set up timer for flush interval
86
- timer_execute(:metrics_flush_timer, @redis_config.flush_interval) do
88
+ # start interval timer to flush api metrics
89
+ timer_execute(:api_metrics_flush_timer, @redis_config.flush_interval) do
87
90
  flush_api_metrics
88
91
  end
89
92
 
93
+ # start interval timer to flush last action entry
94
+ timer_execute(:last_action_flush_timer, '1s') do
95
+ flush_last_action
96
+ end
97
+
90
98
  log.info("Starting HTTP server [#{@host}:#{@port}]...")
91
99
  http_server_create_http_server(:http_server, addr: @host, port: @port, logger: log) do |server|
92
100
  server.post("/#{tag}") do |req|
93
101
  data = parse_data(req.body)
94
102
  route(data) if update_deployment_metrics(data)
95
103
 
96
- # return HTTP 200 OK response to MinIO
104
+ # return HTTP 200 OK response with emtpy body
97
105
  [200, { 'Content-Type' => 'text/plain' }, nil]
98
106
  end
99
107
  end
@@ -141,40 +149,62 @@ module Fluent
141
149
  router.emit(@tag, time, record)
142
150
  end
143
151
 
144
- def days_to_seconds(days)
145
- days * 24 * 60 * 60
152
+ def flush_last_action
153
+ if @last_action_entry.empty?
154
+ @last_action_entry = @last_action_queue.deq.split('|')
155
+ log.debug("Dequed last action entry. #{@last_action_entry}")
156
+ else
157
+ deploymentid, last_action = @last_action_entry
158
+ @last_action_entry = [] if update_deployment_last_action(deploymentid, last_action)
159
+ end
146
160
  end
147
161
 
148
- def update_deployment_last_action(deploymentid)
149
- log.debug('Updating deployment last action')
162
+ def datetime_diff_in_secs(dt_begin, dt_end)
163
+ seconds = ((dt_end - dt_begin) * 24 * 60 * 60)
164
+ seconds.to_i
165
+ end
150
166
 
167
+ def update_deployment_last_action(deploymentid, last_action)
151
168
  key = "#{@redis_config.last_update_prefix}:#{deploymentid}"
152
- curdt = DateTime.now
153
-
154
- begin
155
- log.debug("checking existing last action entry [key: #{key}]")
156
- lastval = @redis.get(key)
157
-
158
- is_grace_period_expired = false
159
- if lastval
160
- lastdt = DateTime.parse(lastval, FMT_DATETIME)
161
- dt_diff_secs = days_to_seconds((curdt - lastdt).to_f)
162
- if dt_diff_secs > @redis_config.grace_period
163
- is_grace_period_expired = true
164
- log.debug("grace period [#{@redis_config.grace_period}] expired [#{lastdt} => #{curdt}]")
165
- end
166
- else
167
- log.debug('last action entry not found. going to be set for the first time.')
169
+ log.debug("Checking existing last action entry [key: #{key}]")
170
+ lastval = @redis.get(key)
171
+
172
+ is_grace_period_expired = false
173
+ if lastval
174
+ curdt = DateTime.now
175
+ lastdt = DateTime.parse(lastval, FMT_DATETIME)
176
+ dt_diff_secs = datetime_diff_in_secs(lastdt, curdt)
177
+ log.debug("Current Data/Time: #{curdt}")
178
+ log.debug("Previous Date/Time: #{lastdt}")
179
+ log.debug("Date/Time diff (s): #{dt_diff_secs}")
180
+
181
+ if dt_diff_secs >= @redis_config.grace_period
182
+ is_grace_period_expired = true
183
+ log.debug("Grace period expired for last action update. [#{@redis_config.grace_period}]")
168
184
  end
185
+ else
186
+ log.debug('Last action entry does not exist. It will be set for the first time.')
187
+ end
169
188
 
170
- if lastdt.nil? || is_grace_period_expired
171
- last_action = curdt.strftime(FMT_DATETIME)
172
- @redis.set(key, last_action)
173
- log.debug("Updated last action entry [#{key} => #{last_action}]")
174
- end
175
- rescue StandardError => e
176
- log.error("Unable to update last action! ERROR: '#{e}'.")
189
+ if lastdt.nil? || is_grace_period_expired
190
+ log.debug('Updating deployment last action')
191
+ last_action = DateTime.parse(last_action, FMT_DATETIME)
192
+ @redis.set(key, last_action)
193
+ log.debug("Updated last action entry [#{key} => #{last_action}]")
194
+ true
195
+ else
196
+ false
177
197
  end
198
+ rescue StandardError => e
199
+ log.error("Unable to update last action! ERROR: '#{e}'.")
200
+ false
201
+ end
202
+
203
+ def enque_last_action_entry(deploymentid)
204
+ last_action = DateTime.now
205
+ entry = "#{deploymentid}|#{last_action}"
206
+ @last_action_queue.enq(entry)
207
+ log.debug("Enqued last action entry. [#{entry}]")
178
208
  end
179
209
 
180
210
  def validate_and_get_value(data_hash, key)
@@ -191,7 +221,7 @@ module Fluent
191
221
  deploymentid = validate_and_get_value(data, 'deploymentid')
192
222
  return false unless deploymentid
193
223
 
194
- update_deployment_last_action(deploymentid)
224
+ enque_last_action_entry(deploymentid)
195
225
 
196
226
  api_data = validate_and_get_value(data, 'api')
197
227
  return false unless api_data
@@ -8,9 +8,26 @@ class CwmHttpInputTest < Test::Unit::TestCase
8
8
  setup do
9
9
  Fluent::Test.setup
10
10
 
11
- @default_conf = %(
12
- tag test
13
- )
11
+ @default_conf = config_element('ROOT', '', { 'tag' => 'test' })
12
+ @custom_conf = config_element('ROOT', '', { 'tag' => 'test' }, [
13
+ config_element('redis', '', {
14
+ 'grace_period' => '1s',
15
+ 'flush_interval' => '1s'
16
+ })
17
+ ])
18
+
19
+ @expected_redis_output = {
20
+ 'deploymentid:last_action:docker-compose-http' => '',
21
+ 'deploymentid:last_action:docker-compose-https' => '',
22
+ 'deploymentid:minio-metrics:docker-compose-http:bytes_in' => '61852',
23
+ 'deploymentid:minio-metrics:docker-compose-https:bytes_in' => '14875',
24
+ 'deploymentid:minio-metrics:docker-compose-http:bytes_out' => '112012',
25
+ 'deploymentid:minio-metrics:docker-compose-https:bytes_out' => '2755',
26
+ 'deploymentid:minio-metrics:docker-compose-http:num_requests_out' => '7',
27
+ 'deploymentid:minio-metrics:docker-compose-http:num_requests_in' => '10',
28
+ 'deploymentid:minio-metrics:docker-compose-https:num_requests_in' => '5',
29
+ 'deploymentid:minio-metrics:docker-compose-http:num_requests_misc' => '5'
30
+ }.freeze
14
31
  end
15
32
 
16
33
  def create_driver(conf)
@@ -27,13 +44,7 @@ class CwmHttpInputTest < Test::Unit::TestCase
27
44
  end
28
45
 
29
46
  test 'redis default configuration test' do
30
- conf = %(
31
- tag test
32
- <redis>
33
- </redis>
34
- )
35
-
36
- driver = create_driver(conf)
47
+ driver = create_driver(@default_conf)
37
48
  plugin = driver.instance
38
49
  redis = plugin.redis_config
39
50
  assert_equal 'localhost', redis.host
@@ -47,7 +58,9 @@ class CwmHttpInputTest < Test::Unit::TestCase
47
58
 
48
59
  sub_test_case 'route#emit' do
49
60
  test 'emit test' do
50
- driver = create_driver(@default_conf)
61
+ driver = create_driver(@custom_conf)
62
+ plugin = driver.instance
63
+ redis = plugin.redis_config
51
64
 
52
65
  res_codes = []
53
66
  lines = 0
@@ -63,6 +76,25 @@ class CwmHttpInputTest < Test::Unit::TestCase
63
76
  assert_equal lines, res_codes.size
64
77
  assert_equal '200', res_codes[0]
65
78
  assert_equal 1, res_codes.uniq.size
79
+
80
+ # run and test private flushing methods
81
+ `redis-cli FLUSHALL`
82
+ sleep(redis.grace_period)
83
+ driver.events.each do
84
+ plugin.send(:flush_api_metrics)
85
+ plugin.send(:flush_last_action)
86
+ end
87
+
88
+ # verify from Redis server
89
+ @expected_redis_output.each do |key, expected_value|
90
+ if key.include? 'last_action'
91
+ exists = `redis-cli EXISTS #{key}`.chomp
92
+ assert_equal '1', exists
93
+ else
94
+ actual_value = `redis-cli GET #{key}`.chomp
95
+ assert_equal expected_value, actual_value
96
+ end
97
+ end
66
98
  end
67
99
  end
68
100
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-http-cwm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Azeem Sajid
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-07 00:00:00.000000000 Z
11
+ date: 2021-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,22 +108,22 @@ dependencies:
108
108
  name: json
109
109
  requirement: !ruby/object:Gem::Requirement
110
110
  requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- version: 2.3.0
114
111
  - - "~>"
115
112
  - !ruby/object:Gem::Version
116
113
  version: '2.3'
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: 2.3.0
117
117
  type: :runtime
118
118
  prerelease: false
119
119
  version_requirements: !ruby/object:Gem::Requirement
120
120
  requirements:
121
- - - ">="
122
- - !ruby/object:Gem::Version
123
- version: 2.3.0
124
121
  - - "~>"
125
122
  - !ruby/object:Gem::Version
126
123
  version: '2.3'
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: 2.3.0
127
127
  - !ruby/object:Gem::Dependency
128
128
  name: redis
129
129
  requirement: !ruby/object:Gem::Requirement
@@ -185,7 +185,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
185
  - !ruby/object:Gem::Version
186
186
  version: '0'
187
187
  requirements: []
188
- rubygems_version: 3.0.3.1
188
+ rubyforge_project:
189
+ rubygems_version: 2.7.6
189
190
  signing_key:
190
191
  specification_version: 4
191
192
  summary: fluentd HTTP Input Plugin for CloudWebManage Logging Component