gitlab-fluent-plugin-redis-slowlog 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8fc7a7afc37728bd3e9ae94eeaa408103bf28f00a87c6e931a4568f675bab927
4
+ data.tar.gz: 3e7fc4b3bc8dbb082f84f211f4de09ceb9b415b2d9d7c0c59b67316498586730
5
+ SHA512:
6
+ metadata.gz: 4e315c9db4c5d3b70c196fcb9dd912304ea8619766f8d9bbc8c00eeb1d4389f96fd37f1279f061e1c3d977944a972209763cadf417bb1dc18c98b12aceeeb9c9
7
+ data.tar.gz: 59f9771844039b0a250c9f6bcbf342ea42163d2710d79b9121f222c39736d3cb8f40e2978cf40a2e86496b507ef1da549fdfbeadea47098c9c6dc86efffb8739
@@ -0,0 +1 @@
1
+ *.gem
@@ -0,0 +1,21 @@
1
+ test:
2
+ image: ruby:2.6
3
+ stage: test
4
+ script:
5
+ - gem install bundler
6
+ - bundle install
7
+ - bundle exec rake
8
+
9
+ deploy:
10
+ stage: deploy
11
+ script:
12
+ - tools/deploy-rubygem.sh
13
+ only:
14
+ - tags
15
+
16
+ release:
17
+ stage: deploy
18
+ script:
19
+ - tools/update-changelog.rb "${CI_COMMIT_TAG}"
20
+ only:
21
+ - tags
@@ -0,0 +1,17 @@
1
+ inherit_gem:
2
+ gitlab-styles:
3
+ - rubocop-default.yml
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.6
7
+
8
+ # Let's just pick something from the beginning
9
+ Style/StringLiterals:
10
+ Enabled: true
11
+ EnforcedStyle: double_quotes
12
+
13
+ # This isn't Rails, so diable these
14
+ Rails/RakeEnvironment:
15
+ Enabled: false
16
+ CodeReuse/ActiveRecord:
17
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,103 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ gitlab-fluent-plugin-redis-slowlog (0.0.0)
5
+ fluentd (>= 0.14.10, < 2)
6
+ redis (>= 4.1.3, < 5)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ ast (2.4.0)
12
+ coderay (1.1.2)
13
+ concurrent-ruby (1.1.6)
14
+ cool.io (1.6.0)
15
+ diff-lcs (1.3)
16
+ fluentd (1.10.4)
17
+ cool.io (>= 1.4.5, < 2.0.0)
18
+ http_parser.rb (>= 0.5.1, < 0.7.0)
19
+ msgpack (>= 1.3.1, < 2.0.0)
20
+ serverengine (>= 2.0.4, < 3.0.0)
21
+ sigdump (~> 0.2.2)
22
+ strptime (>= 0.2.2, < 1.0.0)
23
+ tzinfo (>= 1.0, < 3.0)
24
+ tzinfo-data (~> 1.0)
25
+ yajl-ruby (~> 1.0)
26
+ gitlab-styles (3.2.0)
27
+ rubocop (~> 0.74.0)
28
+ rubocop-gitlab-security (~> 0.1.0)
29
+ rubocop-performance (~> 1.4.1)
30
+ rubocop-rails (~> 2.0)
31
+ rubocop-rspec (~> 1.36)
32
+ http_parser.rb (0.6.0)
33
+ jaro_winkler (1.5.4)
34
+ method_source (0.9.2)
35
+ msgpack (1.3.3)
36
+ parallel (1.19.1)
37
+ parser (2.7.1.2)
38
+ ast (~> 2.4.0)
39
+ power_assert (1.1.3)
40
+ pry (0.12.2)
41
+ coderay (~> 1.1.0)
42
+ method_source (~> 0.9.0)
43
+ rack (2.2.2)
44
+ rainbow (3.0.0)
45
+ rake (12.3.3)
46
+ redis (4.1.4)
47
+ rspec (3.9.0)
48
+ rspec-core (~> 3.9.0)
49
+ rspec-expectations (~> 3.9.0)
50
+ rspec-mocks (~> 3.9.0)
51
+ rspec-core (3.9.2)
52
+ rspec-support (~> 3.9.3)
53
+ rspec-expectations (3.9.2)
54
+ diff-lcs (>= 1.2.0, < 2.0)
55
+ rspec-support (~> 3.9.0)
56
+ rspec-mocks (3.9.1)
57
+ diff-lcs (>= 1.2.0, < 2.0)
58
+ rspec-support (~> 3.9.0)
59
+ rspec-support (3.9.3)
60
+ rubocop (0.74.0)
61
+ jaro_winkler (~> 1.5.1)
62
+ parallel (~> 1.10)
63
+ parser (>= 2.6)
64
+ rainbow (>= 2.2.2, < 4.0)
65
+ ruby-progressbar (~> 1.7)
66
+ unicode-display_width (>= 1.4.0, < 1.7)
67
+ rubocop-gitlab-security (0.1.1)
68
+ rubocop (>= 0.51)
69
+ rubocop-performance (1.4.1)
70
+ rubocop (>= 0.71.0)
71
+ rubocop-rails (2.4.0)
72
+ rack (>= 1.1)
73
+ rubocop (>= 0.72.0)
74
+ rubocop-rspec (1.37.0)
75
+ rubocop (>= 0.68.1)
76
+ ruby-progressbar (1.10.1)
77
+ serverengine (2.2.1)
78
+ sigdump (~> 0.2.2)
79
+ sigdump (0.2.4)
80
+ strptime (0.2.4)
81
+ test-unit (3.2.9)
82
+ power_assert
83
+ tzinfo (2.0.2)
84
+ concurrent-ruby (~> 1.0)
85
+ tzinfo-data (1.2020.1)
86
+ tzinfo (>= 1.0.0)
87
+ unicode-display_width (1.6.1)
88
+ yajl-ruby (1.4.1)
89
+
90
+ PLATFORMS
91
+ ruby
92
+
93
+ DEPENDENCIES
94
+ bundler (~> 2.1.4)
95
+ gitlab-fluent-plugin-redis-slowlog!
96
+ gitlab-styles (~> 3.2.0)
97
+ pry (~> 0.12.2)
98
+ rake (~> 12.0)
99
+ rspec (~> 3.9.0)
100
+ test-unit (~> 3.2.9)
101
+
102
+ BUNDLED WITH
103
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016-2020 GitLab B.V.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,133 @@
1
+ # fluent-plugin-redis-slowlog
2
+
3
+ [Fluentd](https://fluentd.org/) input plugin to write redis-slowlog
4
+ events to fluentd.
5
+
6
+ The plugin works by issuing a
7
+ [`SLOWLOG`](https://redis.io/commands/slowlog) command at an
8
+ interval. The new slowlog entries will be emitted to fluentd.
9
+
10
+ The output looks like this:
11
+
12
+ ```
13
+ 2020-05-26 10:52:27.000000000 +0200 redis.slowlog: {"id":21733,"timestamp":"2020-05-26 10:52:25 +0200","exec_time":5,"command":["SCAN","0"]}
14
+ 2020-05-26 10:52:37.000000000 +0200 redis.slowlog: {"id":21734,"timestamp":"2020-05-26 10:52:27 +0200","exec_time":197,"command":["slowlog","get","128"]}
15
+ 2020-05-26 10:52:37.000000000 +0200 redis.slowlog: {"id":21735,"timestamp":"2020-05-26 10:52:32 +0200","exec_time":3,"command":["SET","hello","world"]}
16
+ 2020-05-26 10:52:47.000000000 +0200 redis.slowlog: {"id":21736,"timestamp":"2020-05-26 10:52:37 +0200","exec_time":259,"command":["slowlog","get","128"]}
17
+ 2020-05-26 10:52:47.000000000 +0200 redis.slowlog: {"id":21737,"timestamp":"2020-05-26 10:52:42 +0200","exec_time":5,"command":["SCAN","0"]}
18
+ ```
19
+
20
+ This is based on the work by @andrewn in
21
+ https://github.com/suprememoocow/fluent-plugin-redis-slowlog, which
22
+ was forked from https://github.com/mominosin/fluent-plugin-redis-slowlog
23
+
24
+ ## Installation
25
+
26
+ ### RubyGems
27
+
28
+ ```
29
+ $ gem install fluent-plugin-redis-slowlog
30
+ ```
31
+
32
+ ### Bundler
33
+
34
+ Add following line to your Gemfile:
35
+
36
+ ```ruby
37
+ gem "fluent-plugin-redis-slowlog"
38
+ ```
39
+
40
+ And then execute:
41
+
42
+ ```
43
+ $ bundle
44
+ ```
45
+
46
+ ## Configuration
47
+
48
+ ### tag (string) (required)
49
+
50
+ The tag to be used for the events
51
+
52
+ #### Redis connection parameters
53
+
54
+ This allows configuring the connection parameters. If nothing is
55
+ configured, falling back to the default of localhost:6379.
56
+
57
+ For more information see the
58
+ [`redis-rb`](https://github.com/redis/redis-rb#getting-started).
59
+
60
+ ### url (string) (optional)
61
+
62
+ A [`redis://`-URL](https://www.iana.org/assignments/uri-schemes/prov/redis).
63
+
64
+ ### path (string) (optional)
65
+
66
+ Path to connect to Redis listening on a Unix socket
67
+
68
+ ### host (string) (optional)
69
+
70
+ Host to connect to Redis
71
+
72
+ Default value: `localhost`.
73
+
74
+ ### port (integer) (optional)
75
+
76
+ Port to connect to Redis, used in combination with the `host` parameter
77
+
78
+ Default value: `6379`.
79
+
80
+ ### password (string) (optional)
81
+
82
+ The password to use for connecting to redis.
83
+
84
+ Default value: `nil`.
85
+
86
+ ### logsize (integer) (optional)
87
+
88
+ The number of slowlog entries to get in 1 call.
89
+
90
+ Default value: `128`.
91
+
92
+ ### interval (integer) (optional)
93
+
94
+ The time in seconds to wait between `SLOWLOG` commands.
95
+
96
+ Default value: `10`.
97
+
98
+ ## Development
99
+
100
+ After checking out the repository, run `bundle install` to install all
101
+ dependencies.
102
+
103
+ After that, you can run `bundle exec rake` to run all lints and
104
+ specs.
105
+
106
+ Other rake tasks:
107
+
108
+ ```
109
+ rake build # Build gitlab-fluent-plugin-redis-slowlog-0.gem into the pkg directory
110
+ rake clean # Remove any temporary products
111
+ rake clobber # Remove any generated files
112
+ rake console # Start an interactive console with the gem loaded
113
+ rake install # Build and install gitlab-fluent-plugin-redis-slowlog-0.gem into system gems
114
+ rake install:local # Build and install gitlab-fluent-plugin-redis-slowlog-0.gem into system gems without network access
115
+ rake release[remote] # Create tag v0 and build and push gitlab-fluent-plugin-redis-slowlog-0.gem to rubygems.org
116
+ rake spec # Run RSpec code examples
117
+ rake verify # Run RuboCop
118
+ rake verify:auto_correct # Auto-correct RuboCop offenses
119
+ ```
120
+
121
+
122
+ ### Releasing a new version
123
+
124
+ Releasing a new version can be done by pushing a new tag, or creating
125
+ it from the
126
+ [interface](https://gitlab.com/gitlab-org/fluent-plugin-redis-slowlog/-/tags).
127
+
128
+ A new changelog will automatically be added to the release on Gitlab.
129
+
130
+ The new version will automatically be published to
131
+ [rubygems](https://rubygems.org/gems/gitlab-labkit) when the pipeline
132
+ for the tag completes. It might take a few minutes before the update
133
+ is available.
@@ -0,0 +1,17 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "rubocop/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new(:verify)
7
+
8
+ desc "Start an interactive console with the gem loaded"
9
+ task :console do
10
+ require "pry"
11
+ require "fluent/env"
12
+ require "fluent/plugin/in_redis_slowlog"
13
+
14
+ Pry.start
15
+ end
16
+
17
+ task default: [:verify, :spec]
@@ -0,0 +1,35 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "gitlab-fluent-plugin-redis-slowlog"
6
+ spec.version = "0.0.0" # `git describe --tags`.chomp.gsub(/^v/, "")
7
+ spec.metadata = { "source_code_uri" => "https://gitlab.com/gitlab-org/fluent-plugin-redis-slowlog" }
8
+ spec.authors = ["Bob Van Landuyt"]
9
+ spec.email = ["bob@gitlab.com"]
10
+
11
+ spec.required_ruby_version = ">= 2.6"
12
+
13
+ spec.summary = "Emit redis slowlog entries into fluentd"
14
+ spec.homepage = "http://gitlab.com/gitlab-org/gitlab-fluent-plugin-redis-slowlog"
15
+ spec.license = "MIT"
16
+
17
+ test_files, files = `git ls-files -z`.split("\x0").partition do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.files = files
21
+ spec.executables = files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = test_files
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_development_dependency "bundler", "~> 2.1.4"
26
+ spec.add_development_dependency "gitlab-styles", "~> 3.2.0"
27
+ spec.add_development_dependency "pry", "~> 0.12.2"
28
+ spec.add_development_dependency "rake", "~> 12.0"
29
+ spec.add_development_dependency "rspec", "~> 3.9.0"
30
+ # required for the fluent test helpers
31
+ spec.add_development_dependency "test-unit", "~> 3.2.9"
32
+
33
+ spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
34
+ spec.add_runtime_dependency "redis", [">= 4.1.3", "< 5"]
35
+ end
@@ -0,0 +1,93 @@
1
+ require "fluent/plugin/input"
2
+ require "redis"
3
+
4
+ module Fluent
5
+ module Plugin
6
+ class RedisSlowlogInput < Fluent::Plugin::Input
7
+ Fluent::Plugin.register_input("redis_slowlog", self)
8
+
9
+ config_param :tag, :string
10
+ config_param :url, :string, default: nil
11
+ config_param :path, :string, default: nil
12
+ config_param :host, :string, default: "localhost"
13
+ config_param :port, :integer, default: 6379
14
+ config_param :password, :string, default: nil
15
+ config_param :logsize, :integer, default: 128
16
+ config_param :interval, :integer, default: 10
17
+
18
+ def initialize
19
+ super
20
+
21
+ @current_log_id = 0
22
+ end
23
+
24
+ def configure(conf)
25
+ super
26
+
27
+ @redis = Redis.new(
28
+ url: url,
29
+ host: host,
30
+ port: port,
31
+ path: path,
32
+ password: password
33
+ )
34
+ end
35
+
36
+ def start
37
+ super
38
+
39
+ if redis.ping != "PONG"
40
+ raise Redis::CannotConnectError,
41
+ "Could not connect to redis"
42
+ end
43
+
44
+ self.watching = true
45
+ self.watcher = Thread.new(&method(:watch))
46
+ end
47
+
48
+ def shutdown
49
+ super
50
+
51
+ self.watching = false
52
+ redis.quit
53
+ end
54
+
55
+ private
56
+
57
+ attr_reader :redis, :interval
58
+ attr_accessor :watcher, :watching, :current_log_id
59
+
60
+ def watch
61
+ while watching
62
+ sleep interval
63
+
64
+ self.current_log_id = output(current_log_id)
65
+ end
66
+ end
67
+
68
+ def output(last_id = 0)
69
+ slowlogs = redis.slowlog("get", logsize)
70
+ return last_id if slowlogs.empty?
71
+
72
+ emit_slowlog(slowlogs)
73
+
74
+ # Return the id of the last slowlog entry we've logged
75
+ # The first entry is the one that occurred last
76
+ slowlogs.first.first
77
+ end
78
+
79
+ def emit_slowlog(slowlogs)
80
+ slowlogs.reverse_each do |log|
81
+ # Don't emit logs for entries we've already logged
82
+ next if log.first <= current_log_id
83
+
84
+ log_hash = { "id" => log[0],
85
+ "timestamp" => Time.at(log[1]),
86
+ "exec_time" => log[2],
87
+ "command" => log[3] }
88
+ router.emit(tag, Time.now.to_i, log_hash)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,119 @@
1
+ require "spec_helper"
2
+
3
+ describe Fluent::Plugin::RedisSlowlogInput do
4
+ let(:config) do
5
+ { tag: "redis.slowlog" }
6
+ end
7
+
8
+ let(:plugin) { driver.instance }
9
+ let(:slowlog) { [] }
10
+ let(:fake_redis) { instance_double(Redis, ping: "PONG", quit: "OK", slowlog: slowlog) }
11
+
12
+ subject(:driver) do
13
+ config_string = config.map { |key, value| "#{key} #{value}" }.join("\n")
14
+ Fluent::Test::Driver::Input.new(described_class).configure(config_string)
15
+ end
16
+
17
+ before do
18
+ Fluent::Test.setup
19
+ end
20
+
21
+ context "when redis can't be reached" do
22
+ it "raises an error" do
23
+ expect { driver.run }.to raise_error(Redis::CannotConnectError)
24
+ end
25
+ end
26
+
27
+ context "when specifying redis connection attributes" do
28
+ let(:config) do
29
+ { tag: "redis.slowlog",
30
+ url: "redis://:p4ssw0rd@10.0.1.1:6380/15",
31
+ path: "/path/to/redis.sock",
32
+ host: "localhost",
33
+ port: 1234,
34
+ password: "5iveL!fe" }
35
+ end
36
+
37
+ it "delegates all of them to redis-rb" do
38
+ redis_params = [:url, :path, :host, :port, :password]
39
+
40
+ expect(Redis).to receive(:new).with(config.slice(*redis_params)).and_return(fake_redis)
41
+
42
+ driver.run
43
+ end
44
+ end
45
+
46
+ context "when redis is available" do
47
+ let(:config) do
48
+ {
49
+ tag: "redis.slowlog",
50
+ interval: 0,
51
+ logsize: 10
52
+ }
53
+ end
54
+
55
+ before do
56
+ allow(plugin).to receive(:redis).and_return(fake_redis)
57
+ end
58
+
59
+ after do
60
+ # Wait for the thread polling redis to finish
61
+ plugin.__send__(:watcher).join
62
+ end
63
+
64
+ it "does not raise errors" do
65
+ expect { driver.run }.not_to raise_error
66
+ end
67
+
68
+ it "polls the slowlog at with the configured interval and size" do
69
+ expect(plugin).to receive(:sleep).with(0).ordered
70
+ expect(fake_redis).to receive(:slowlog).with("get", 10).ordered
71
+ expect(plugin).to receive(:sleep).with(0).ordered
72
+ expect(fake_redis).to receive(:slowlog).with("get", 10).ordered
73
+
74
+ # Limit to 2 cycles
75
+ allow(plugin).to receive(:watching).thrice.and_return(true, true, false)
76
+
77
+ driver.run
78
+ end
79
+
80
+ context "when the slowlog returns entries" do
81
+ let(:slowlog) do
82
+ [
83
+ [25640, 1590522258, 1, %w[ping]],
84
+ [25639, 1590522249, 1, %w[ping]],
85
+ [25638, 1590522208, 5, %w[SCAN 0]]
86
+ ]
87
+ end
88
+
89
+ let(:expected_entries) do
90
+ slowlog.map(&method(:log_entry)).sort_by { |event| event["id"] }
91
+ end
92
+
93
+ let(:emitted_entries) { driver.events.map(&:last) }
94
+
95
+ it "emits an event for each slowlog in reverse order" do
96
+ driver.run(expect_emits: 3)
97
+
98
+ expect(driver.events.size).to eq(3)
99
+ expect(emitted_entries).to eq(expected_entries)
100
+ end
101
+
102
+ it "does not log the same event twice" do
103
+ expect(fake_redis).to receive(:slowlog).and_return(slowlog.last(1), slowlog)
104
+
105
+ driver.run(expect_emits: 3)
106
+
107
+ expect(driver.events.size).to eq(3)
108
+ expect(emitted_entries).to eq(expected_entries)
109
+ end
110
+ end
111
+ end
112
+
113
+ def log_entry(slowlog_entry)
114
+ { "id" => slowlog_entry.first,
115
+ "timestamp" => Time.at(slowlog_entry[1]),
116
+ "exec_time" => slowlog_entry[2],
117
+ "command" => slowlog_entry.last }
118
+ end
119
+ end
@@ -0,0 +1,15 @@
1
+ require "rspec"
2
+ require "fluent/test"
3
+ require "fluent/test/driver/input"
4
+ require "fluent/test/helpers"
5
+ require "pry"
6
+
7
+ Dir.glob(File.expand_path("../lib/**/*.rb", __dir__)).each(&method(:require))
8
+
9
+ # Test::Unit is required for fluent/test, but we don't want it to autorun when
10
+ # required
11
+ Test::Unit::AutoRunner.need_auto_run = false
12
+
13
+ RSpec.configure do |config|
14
+ config.include Fluent::Test::Helpers
15
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -euo pipefail
4
+ IFS=$'\n\t'
5
+
6
+ mkdir -p ~/.gem/
7
+ temp_file=$(mktemp)
8
+
9
+ # Revert change the credentials file
10
+ function revert_gem_cred_switch {
11
+ mv "$temp_file" ~/.gem/credentials
12
+ }
13
+
14
+ if [[ -f ~/.gem/credentials ]]; then
15
+ echo "Temporarily moving existing credentials to $temp_file"
16
+ mv ~/.gem/credentials "$temp_file"
17
+ trap revert_gem_cred_switch EXIT
18
+ fi
19
+
20
+ cat <<EOD > ~/.gem/credentials
21
+ ---
22
+ :rubygems_api_key: $RUBYGEMS_API_KEY
23
+ EOD
24
+ chmod 600 ~/.gem/credentials
25
+
26
+ set -x
27
+ rm -rf pkg/
28
+ mkdir -p pkg/
29
+ bundle install
30
+ bundle exec rake verify build
31
+ gem push pkg/*.gem
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "uri"
4
+ require "net/http"
5
+ require "openssl"
6
+ require "json"
7
+ require "optparse"
8
+
9
+ GitlabError = Class.new(StandardError)
10
+ GitlabClientError = Class.new(GitlabError)
11
+
12
+ def gitlab_client(path, method, body = nil)
13
+ url = URI("https://gitlab.com#{path}")
14
+
15
+ http = Net::HTTP.new(url.host, url.port)
16
+ http.use_ssl = true
17
+
18
+ request = case method
19
+ when :get
20
+ Net::HTTP::Get.new(url)
21
+ when :post
22
+ Net::HTTP::Post.new(url)
23
+ when :put
24
+ Net::HTTP::Put.new(url)
25
+ else
26
+ raise "Unknown method: #{method}"
27
+ end
28
+
29
+ request["content-type"] = "application/json"
30
+ request["PRIVATE-TOKEN"] = ENV["GITLAB_TOKEN"]
31
+ request.body = JSON.dump(body) if body
32
+
33
+ response = http.request(request)
34
+
35
+ case response
36
+ when Net::HTTPSuccess
37
+ JSON.parse(response.read_body)
38
+ when Net::HTTPClientError
39
+ raise GitlabClientError, "HTTP #{response.code} for #{method} #{url}: #{response.read_body}"
40
+ else
41
+ raise GitLabError, "HTTP #{response.code} for #{method} #{url}: #{response.read_body}"
42
+ end
43
+ end
44
+
45
+ def list_commits_for_tag(tag)
46
+ commits = `git rev-list --no-merges $(git describe --tags --abbrev=0 #{tag}^)..#{tag}`.lines
47
+ commits.map(&:chomp)
48
+ end
49
+
50
+ def get_mrs_for_commit(commit_id)
51
+ gitlab_client("/api/v4/projects/gitlab-org%2ffluent-plugin-redis-slowlog/repository/commits/#{commit_id}/merge_requests", :get)
52
+ end
53
+
54
+ def create_release_for_tag(tag, description)
55
+ req_body = { tag_name: tag, description: description }
56
+ gitlab_client("/api/v4/projects/gitlab-org%2ffluent-plugin-redis-slowlog/releases", :post, req_body)
57
+ end
58
+
59
+ def update_release_for_tag(tag, description)
60
+ req_body = { description: description }
61
+ gitlab_client("/api/v4/projects/gitlab-org%2ffluent-plugin-redis-slowlog/releases/#{tag}", :put, req_body)
62
+ end
63
+
64
+ def get_unique_mrs_for_tag(tag)
65
+ commit_ids = list_commits_for_tag(tag)
66
+ dup_mrs = commit_ids.map { |commit_id| get_mrs_for_commit(commit_id) }.flatten
67
+ uniq_mrs = dup_mrs.uniq { |mr| mr["iid"] }
68
+
69
+ uniq_mrs.sort { |mr| mr["iid"] }.reverse
70
+ end
71
+
72
+ options = {}
73
+ OptionParser.new do |opts|
74
+ opts.banner = "Usage: update-changelog.rb [options] tag"
75
+
76
+ opts.on("-d", "--[no-]dry-run", "Display only. Do not update release notes.") do |d|
77
+ options[:dry_run] = d
78
+ end
79
+ end.parse!
80
+
81
+ # Check required conditions
82
+ unless ARGV.length == 1
83
+ puts optparse
84
+ exit(-1)
85
+ end
86
+
87
+ tag = ARGV.first
88
+
89
+ changelog = get_unique_mrs_for_tag(tag).map { |mr| "* #{mr['web_url']}: #{mr['title']}" }.join("\n")
90
+
91
+ raise "No new changes found" if changelog.empty?
92
+
93
+ changelog = "## Changes in #{tag}\n\n" + changelog
94
+
95
+ if options[:dry_run]
96
+ puts changelog
97
+ exit
98
+ end
99
+
100
+ begin
101
+ create_release_for_tag(tag, changelog)
102
+ puts "Created release: https://gitlab.com/gitlab-org/fluent-plugin-redis-slowlog/-/releases##{tag}"
103
+ rescue GitlabClientError
104
+ update_release_for_tag(tag, changelog)
105
+ puts "Updated release: https://gitlab.com/gitlab-org/fluent-plugin-redis-slowlog/-/releases##{tag}"
106
+ end
metadata ADDED
@@ -0,0 +1,184 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gitlab-fluent-plugin-redis-slowlog
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Bob Van Landuyt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.4
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: gitlab-styles
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.2.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.12.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.12.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '12.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '12.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 3.9.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 3.9.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: test-unit
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 3.2.9
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 3.2.9
97
+ - !ruby/object:Gem::Dependency
98
+ name: fluentd
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 0.14.10
104
+ - - "<"
105
+ - !ruby/object:Gem::Version
106
+ version: '2'
107
+ type: :runtime
108
+ prerelease: false
109
+ version_requirements: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: 0.14.10
114
+ - - "<"
115
+ - !ruby/object:Gem::Version
116
+ version: '2'
117
+ - !ruby/object:Gem::Dependency
118
+ name: redis
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: 4.1.3
124
+ - - "<"
125
+ - !ruby/object:Gem::Version
126
+ version: '5'
127
+ type: :runtime
128
+ prerelease: false
129
+ version_requirements: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: 4.1.3
134
+ - - "<"
135
+ - !ruby/object:Gem::Version
136
+ version: '5'
137
+ description:
138
+ email:
139
+ - bob@gitlab.com
140
+ executables: []
141
+ extensions: []
142
+ extra_rdoc_files: []
143
+ files:
144
+ - ".gitignore"
145
+ - ".gitlab-ci.yml"
146
+ - ".rubocop.yml"
147
+ - Gemfile
148
+ - Gemfile.lock
149
+ - LICENSE
150
+ - README.md
151
+ - Rakefile
152
+ - gitlab-fluent-plugin-redis-slowlog.gemspec
153
+ - lib/fluent/plugin/in_redis_slowlog.rb
154
+ - spec/fluent/plugin/redis_slowlog_input_spec.rb
155
+ - spec/spec_helper.rb
156
+ - tools/deploy-rubygem.sh
157
+ - tools/update-changelog.rb
158
+ homepage: http://gitlab.com/gitlab-org/gitlab-fluent-plugin-redis-slowlog
159
+ licenses:
160
+ - MIT
161
+ metadata:
162
+ source_code_uri: https://gitlab.com/gitlab-org/fluent-plugin-redis-slowlog
163
+ post_install_message:
164
+ rdoc_options: []
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - ">="
170
+ - !ruby/object:Gem::Version
171
+ version: '2.6'
172
+ required_rubygems_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ requirements: []
178
+ rubygems_version: 3.0.3
179
+ signing_key:
180
+ specification_version: 4
181
+ summary: Emit redis slowlog entries into fluentd
182
+ test_files:
183
+ - spec/fluent/plugin/redis_slowlog_input_spec.rb
184
+ - spec/spec_helper.rb