gitlab-fluent-plugin-redis-slowlog 0.0.1.pre → 0.1.2
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 +4 -4
- data/.gitignore +1 -0
- data/.gitlab-ci.yml +42 -0
- data/.rubocop.yml +17 -0
- data/README.md +36 -0
- data/Rakefile +12 -7
- data/gitlab-fluent-plugin-redis-slowlog.gemspec +2 -2
- data/lib/fluent/plugin/in_redis_slowlog.rb +42 -24
- data/spec/fluent/plugin/redis_slowlog_input_spec.rb +176 -0
- data/spec/spec_helper.rb +15 -0
- data/tools/deploy-rubygem.sh +31 -0
- data/tools/update-changelog.rb +106 -0
- metadata +13 -10
- data/Gemfile.lock +0 -110
- data/test/helper.rb +0 -8
- data/test/plugin/test_in_redis_slowlog.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c64f62b09c3902e94875fa90ca310357fda747eb68960f81c28f4f0e566ed0d
|
4
|
+
data.tar.gz: 3ccbe9ea9af8e67dc6e0b226538494462889bedebb7e9706fb88efebf2001999
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c394e1220236241046c06ef56a7fb59e823e46a9d4fa0382b589b4d7af035b7d9832a5c3c2daa207341e368b9f208707ed502617bcd7c6c55de9cf2af253093
|
7
|
+
data.tar.gz: 3b03fe4132255c47dccfff8411a31bd94b5a41ceb3806e96f1fd6875963d68560f47a61180c683b700c5f96556e9b860f204ae78240aa7c910beccf753e8cd8c
|
data/.gitignore
CHANGED
data/.gitlab-ci.yml
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
workflow:
|
2
|
+
rules:
|
3
|
+
# For merge requests, create a pipeline.
|
4
|
+
- if: '$CI_MERGE_REQUEST_IID'
|
5
|
+
# For `master` branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
|
6
|
+
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
7
|
+
# For tags, create a pipeline.
|
8
|
+
- if: '$CI_COMMIT_TAG'
|
9
|
+
|
10
|
+
.test_template: &test_definition
|
11
|
+
stage: test
|
12
|
+
script:
|
13
|
+
- gem install bundler
|
14
|
+
- bundle install
|
15
|
+
- bundle exec rake
|
16
|
+
|
17
|
+
test2.6:
|
18
|
+
image: ruby:2.6
|
19
|
+
<<: *test_definition
|
20
|
+
test2.5:
|
21
|
+
image: ruby:2.5
|
22
|
+
<<: *test_definition
|
23
|
+
test2.4:
|
24
|
+
image: ruby:2.4
|
25
|
+
<<: *test_definition
|
26
|
+
|
27
|
+
deploy:
|
28
|
+
image: ruby:2.6
|
29
|
+
stage: deploy
|
30
|
+
script:
|
31
|
+
- gem install bundler
|
32
|
+
- tools/deploy-rubygem.sh
|
33
|
+
only:
|
34
|
+
- tags
|
35
|
+
|
36
|
+
release:
|
37
|
+
image: ruby:2.6
|
38
|
+
stage: deploy
|
39
|
+
script:
|
40
|
+
- tools/update-changelog.rb "${CI_COMMIT_TAG}"
|
41
|
+
only:
|
42
|
+
- tags
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
inherit_gem:
|
2
|
+
gitlab-styles:
|
3
|
+
- rubocop-default.yml
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
TargetRubyVersion: 2.4
|
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 disable these
|
14
|
+
Rails/RakeEnvironment:
|
15
|
+
Enabled: false
|
16
|
+
CodeReuse/ActiveRecord:
|
17
|
+
Enabled: false
|
data/README.md
CHANGED
@@ -94,3 +94,39 @@ Default value: `128`.
|
|
94
94
|
The time in seconds to wait between `SLOWLOG` commands.
|
95
95
|
|
96
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
|
+
### Releasing a new version
|
122
|
+
|
123
|
+
Releasing a new version can be done by pushing a new tag, or creating
|
124
|
+
it from the
|
125
|
+
[interface](https://gitlab.com/gitlab-org/fluent-plugin-redis-slowlog/-/tags).
|
126
|
+
|
127
|
+
A new changelog will automatically be added to the release on GitLab.
|
128
|
+
|
129
|
+
The new version will automatically be published to
|
130
|
+
[rubygems](https://rubygems.org/gems/gitlab-fluent-plugin-redis-slowlog)
|
131
|
+
when the pipeline for the tag completes. It might take a few minutes
|
132
|
+
before the update is available.
|
data/Rakefile
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require "rubocop/rake_task"
|
2
4
|
|
3
|
-
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
RuboCop::RakeTask.new(:verify)
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
10
15
|
end
|
11
16
|
|
12
|
-
task default: [:
|
17
|
+
task default: [:verify, :spec]
|
@@ -3,12 +3,12 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
5
|
spec.name = "gitlab-fluent-plugin-redis-slowlog"
|
6
|
-
spec.version =
|
6
|
+
spec.version = `git describe --tags`.chomp.gsub(/^v/, "")
|
7
7
|
spec.metadata = { "source_code_uri" => "https://gitlab.com/gitlab-org/fluent-plugin-redis-slowlog" }
|
8
8
|
spec.authors = ["Bob Van Landuyt"]
|
9
9
|
spec.email = ["bob@gitlab.com"]
|
10
10
|
|
11
|
-
spec.required_ruby_version = ">= 2.
|
11
|
+
spec.required_ruby_version = ">= 2.4"
|
12
12
|
|
13
13
|
spec.summary = "Emit redis slowlog entries into fluentd"
|
14
14
|
spec.homepage = "http://gitlab.com/gitlab-org/gitlab-fluent-plugin-redis-slowlog"
|
@@ -4,8 +4,12 @@ require "redis"
|
|
4
4
|
module Fluent
|
5
5
|
module Plugin
|
6
6
|
class RedisSlowlogInput < Fluent::Plugin::Input
|
7
|
+
helpers :thread
|
8
|
+
|
7
9
|
Fluent::Plugin.register_input("redis_slowlog", self)
|
8
10
|
|
11
|
+
Entry = Struct.new(:id, :timestamp, :exec_time_us, :command)
|
12
|
+
|
9
13
|
config_param :tag, :string
|
10
14
|
config_param :url, :string, default: nil
|
11
15
|
config_param :path, :string, default: nil
|
@@ -14,12 +18,7 @@ module Fluent
|
|
14
18
|
config_param :password, :string, default: nil
|
15
19
|
config_param :logsize, :integer, default: 128
|
16
20
|
config_param :interval, :integer, default: 10
|
17
|
-
|
18
|
-
def initialize
|
19
|
-
super
|
20
|
-
|
21
|
-
@current_log_id = 0
|
22
|
-
end
|
21
|
+
config_param :timeout, :integer, default: 2
|
23
22
|
|
24
23
|
def configure(conf)
|
25
24
|
super
|
@@ -29,7 +28,8 @@ module Fluent
|
|
29
28
|
host: host,
|
30
29
|
port: port,
|
31
30
|
path: path,
|
32
|
-
password: password
|
31
|
+
password: password,
|
32
|
+
timeout: timeout
|
33
33
|
)
|
34
34
|
end
|
35
35
|
|
@@ -42,7 +42,7 @@ module Fluent
|
|
42
42
|
end
|
43
43
|
|
44
44
|
self.watching = true
|
45
|
-
self.watcher =
|
45
|
+
self.watcher = thread_create(:redis_slowlog_watcher, &method(:watch))
|
46
46
|
end
|
47
47
|
|
48
48
|
def shutdown
|
@@ -55,39 +55,57 @@ module Fluent
|
|
55
55
|
private
|
56
56
|
|
57
57
|
attr_reader :redis, :interval
|
58
|
-
attr_accessor :watcher, :watching
|
58
|
+
attr_accessor :watcher, :watching
|
59
59
|
|
60
60
|
def watch
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
# Check the current id of the slowlog, and start logging from there
|
62
|
+
current_log_id = get_slowlogs(1).first&.id || -1
|
63
|
+
|
64
|
+
begin
|
65
|
+
while watching
|
66
|
+
sleep interval
|
67
|
+
|
68
|
+
current_log_id = output(current_log_id)
|
69
|
+
end
|
70
|
+
rescue Redis::BaseError => e
|
71
|
+
msg = "Error fetching slowlogs: #{e.inspect}"
|
72
|
+
log.error(msg)
|
73
|
+
router.emit("#{tag}.error", Fluent::EventTime.new(Time.now.to_i), { "message" => msg })
|
74
|
+
retry
|
65
75
|
end
|
66
76
|
end
|
67
77
|
|
68
|
-
def output(last_id
|
69
|
-
slowlogs =
|
78
|
+
def output(last_id)
|
79
|
+
slowlogs = get_slowlogs(logsize)
|
70
80
|
return last_id if slowlogs.empty?
|
71
81
|
|
72
|
-
|
82
|
+
# If the latest entry is smaller than what we last saw, redis was restarted
|
83
|
+
# Restart logging from the beginning.
|
84
|
+
last_id = -1 if slowlogs.first.id < last_id
|
85
|
+
|
86
|
+
emit_slowlog(slowlogs, last_id)
|
73
87
|
|
74
88
|
# Return the id of the last slowlog entry we've logged
|
75
89
|
# The first entry is the one that occurred last
|
76
|
-
slowlogs.first.
|
90
|
+
slowlogs.first.id
|
77
91
|
end
|
78
92
|
|
79
|
-
def emit_slowlog(slowlogs)
|
93
|
+
def emit_slowlog(slowlogs, last_id)
|
80
94
|
slowlogs.reverse_each do |log|
|
81
95
|
# Don't emit logs for entries we've already logged
|
82
|
-
next if log.
|
96
|
+
next if log.id <= last_id
|
83
97
|
|
84
|
-
log_hash = { "id" => log
|
85
|
-
"
|
86
|
-
"exec_time" => log
|
87
|
-
"command" => log
|
88
|
-
router.emit(tag,
|
98
|
+
log_hash = { "id" => log.id,
|
99
|
+
"time" => Time.at(log.timestamp.to_i).utc.iso8601(3),
|
100
|
+
"exec_time" => log.exec_time_us,
|
101
|
+
"command" => log.command }
|
102
|
+
router.emit(tag, Fluent::EventTime.new(log.timestamp.to_i), log_hash)
|
89
103
|
end
|
90
104
|
end
|
105
|
+
|
106
|
+
def get_slowlogs(size)
|
107
|
+
redis.slowlog("get", size).map { |slowlog_entry| Entry.new(*slowlog_entry.first(4)) }
|
108
|
+
end
|
91
109
|
end
|
92
110
|
end
|
93
111
|
end
|
@@ -0,0 +1,176 @@
|
|
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(:fake_redis) { instance_double(Redis, ping: "PONG", quit: "OK", slowlog: []) }
|
10
|
+
|
11
|
+
subject(:driver) do
|
12
|
+
config_string = config.map { |key, value| "#{key} #{value}" }.join("\n")
|
13
|
+
Fluent::Test::Driver::Input.new(described_class).configure(config_string)
|
14
|
+
end
|
15
|
+
|
16
|
+
def run(**options)
|
17
|
+
driver.run({ timeout: 1 }.merge(options))
|
18
|
+
end
|
19
|
+
|
20
|
+
before do
|
21
|
+
Fluent::Test.setup
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when redis can't be reached" do
|
25
|
+
it "raises an error" do
|
26
|
+
expect { run }.to raise_error(Redis::CannotConnectError)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when specifying redis connection attributes" do
|
31
|
+
let(:config) do
|
32
|
+
{ tag: "redis.slowlog",
|
33
|
+
url: "redis://:p4ssw0rd@10.0.1.1:6380/15",
|
34
|
+
path: "/path/to/redis.sock",
|
35
|
+
host: "localhost",
|
36
|
+
port: 1234,
|
37
|
+
password: "5iveL!fe",
|
38
|
+
timeout: 2 }
|
39
|
+
end
|
40
|
+
|
41
|
+
it "delegates all of them to redis-rb" do
|
42
|
+
# In ruby 2.5+ this could be config.slice(*[])
|
43
|
+
redis_params = config.select { |name, _| [:url, :path, :host, :port, :password, :timeout].include?(name) }
|
44
|
+
|
45
|
+
expect(Redis).to receive(:new).with(redis_params).and_return(fake_redis)
|
46
|
+
|
47
|
+
run
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when redis is available" do
|
52
|
+
let(:config) do
|
53
|
+
{
|
54
|
+
tag: "redis.slowlog",
|
55
|
+
interval: 0,
|
56
|
+
logsize: 10
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
before do
|
61
|
+
allow(plugin).to receive(:redis).and_return(fake_redis)
|
62
|
+
end
|
63
|
+
|
64
|
+
after do
|
65
|
+
# Wait for the thread polling redis to finish
|
66
|
+
plugin.__send__(:watcher).join
|
67
|
+
end
|
68
|
+
|
69
|
+
it "does not raise errors" do
|
70
|
+
expect { run }.not_to raise_error
|
71
|
+
end
|
72
|
+
|
73
|
+
it "polls the slowlog with the configured interval and size" do
|
74
|
+
# thread_create startup
|
75
|
+
expect(plugin).to receive(:sleep).with(0.1).at_least(:once)
|
76
|
+
# core test
|
77
|
+
expect(fake_redis).to receive(:slowlog).with("get", 1).ordered
|
78
|
+
expect(plugin).to receive(:sleep).with(0).ordered
|
79
|
+
expect(fake_redis).to receive(:slowlog).with("get", 10).ordered
|
80
|
+
expect(plugin).to receive(:sleep).with(0).ordered
|
81
|
+
expect(fake_redis).to receive(:slowlog).with("get", 10).ordered
|
82
|
+
|
83
|
+
# Limit to 2 cycles
|
84
|
+
allow(plugin).to receive(:watching).thrice.and_return(true, true, false)
|
85
|
+
|
86
|
+
run
|
87
|
+
end
|
88
|
+
|
89
|
+
it "retries when a connection error occurs" do
|
90
|
+
# thread_create startup
|
91
|
+
expect(plugin).to receive(:sleep).with(0.1).at_least(:once)
|
92
|
+
# core test
|
93
|
+
expect(fake_redis).to receive(:slowlog).with("get", 1).ordered
|
94
|
+
expect(plugin).to receive(:sleep).with(0).ordered
|
95
|
+
expect(fake_redis).to receive(:slowlog).with("get", 10).ordered.and_raise(Redis::ConnectionError)
|
96
|
+
expect(plugin).to receive(:sleep).with(0).ordered
|
97
|
+
expect(fake_redis).to receive(:slowlog).with("get", 10).ordered
|
98
|
+
|
99
|
+
# Limit to 2 cycles
|
100
|
+
allow(plugin).to receive(:watching).thrice.and_return(true, true, false)
|
101
|
+
|
102
|
+
run
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when the slowlog returns entries", :aggregate_failures do
|
106
|
+
let(:startup_slowlog) { [[25637, 1590522108, 5, %w[SCAN 0]]] }
|
107
|
+
let(:logged_slowlog) do
|
108
|
+
[
|
109
|
+
[25640, 1590522258, 1, %w[ping]],
|
110
|
+
[25639, 1590522249, 1, %w[ping]],
|
111
|
+
[25638, 1590522208, 5, %w[SCAN 0]]
|
112
|
+
]
|
113
|
+
end
|
114
|
+
let(:slowlog) { logged_slowlog + startup_slowlog }
|
115
|
+
|
116
|
+
let(:expected_entries) do
|
117
|
+
logged_slowlog.map(&method(:log_entry)).sort_by { |event| event["id"] }
|
118
|
+
end
|
119
|
+
|
120
|
+
let(:emitted_entries) { driver.events.map(&:last) }
|
121
|
+
|
122
|
+
it "emits an event for each slowlog in reverse order" do
|
123
|
+
expect(fake_redis).to receive(:slowlog).and_return(startup_slowlog, slowlog)
|
124
|
+
|
125
|
+
run(expect_emits: 3)
|
126
|
+
|
127
|
+
expect(driver.events.size).to eq(3)
|
128
|
+
expect(emitted_entries).to eq(expected_entries)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "does not log the same event twice" do
|
132
|
+
expect(fake_redis).to receive(:slowlog).and_return(startup_slowlog, slowlog.last(2), slowlog)
|
133
|
+
|
134
|
+
run(expect_emits: 3)
|
135
|
+
|
136
|
+
expect(driver.events.size).to eq(3)
|
137
|
+
expect(emitted_entries).to eq(expected_entries)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "emits results that can be streamed to fluent using MessagePack" do
|
141
|
+
expect(fake_redis).to receive(:slowlog).and_return(startup_slowlog, slowlog)
|
142
|
+
|
143
|
+
run(expect_emits: 3)
|
144
|
+
|
145
|
+
expect { driver.events.map(&:to_msgpack) }.not_to raise_error
|
146
|
+
end
|
147
|
+
|
148
|
+
context "when redis restarts" do
|
149
|
+
let(:logged_slowlog) { [[25638, 1590522208, 5, %w[SCAN 0]]] }
|
150
|
+
let(:reset_slowlog) do
|
151
|
+
[
|
152
|
+
[2, 1590522258, 1, %w[ping]],
|
153
|
+
[1, 1590522249, 1, %w[ping]]
|
154
|
+
]
|
155
|
+
end
|
156
|
+
|
157
|
+
it "emits all items" do
|
158
|
+
reset_entries = reset_slowlog.map(&method(:log_entry)).sort_by { |e| e["id"] }
|
159
|
+
expect(fake_redis).to receive(:slowlog).and_return(startup_slowlog, slowlog, [], reset_slowlog)
|
160
|
+
|
161
|
+
run(expect_emits: 3)
|
162
|
+
|
163
|
+
expect(emitted_entries.size).to eq(3)
|
164
|
+
expect(emitted_entries).to eq(expected_entries + reset_entries)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def log_entry(slowlog_entry)
|
171
|
+
{ "id" => slowlog_entry.first,
|
172
|
+
"time" => Time.at(slowlog_entry[1].to_i).utc.iso8601(3),
|
173
|
+
"exec_time" => slowlog_entry[2],
|
174
|
+
"command" => slowlog_entry.last }
|
175
|
+
end
|
176
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -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 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
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab-fluent-plugin-redis-slowlog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Van Landuyt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -142,15 +142,18 @@ extensions: []
|
|
142
142
|
extra_rdoc_files: []
|
143
143
|
files:
|
144
144
|
- ".gitignore"
|
145
|
+
- ".gitlab-ci.yml"
|
146
|
+
- ".rubocop.yml"
|
145
147
|
- Gemfile
|
146
|
-
- Gemfile.lock
|
147
148
|
- LICENSE
|
148
149
|
- README.md
|
149
150
|
- Rakefile
|
150
151
|
- gitlab-fluent-plugin-redis-slowlog.gemspec
|
151
152
|
- lib/fluent/plugin/in_redis_slowlog.rb
|
152
|
-
-
|
153
|
-
-
|
153
|
+
- spec/fluent/plugin/redis_slowlog_input_spec.rb
|
154
|
+
- spec/spec_helper.rb
|
155
|
+
- tools/deploy-rubygem.sh
|
156
|
+
- tools/update-changelog.rb
|
154
157
|
homepage: http://gitlab.com/gitlab-org/gitlab-fluent-plugin-redis-slowlog
|
155
158
|
licenses:
|
156
159
|
- MIT
|
@@ -164,17 +167,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
167
|
requirements:
|
165
168
|
- - ">="
|
166
169
|
- !ruby/object:Gem::Version
|
167
|
-
version: '2.
|
170
|
+
version: '2.4'
|
168
171
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
172
|
requirements:
|
170
|
-
- - "
|
173
|
+
- - ">="
|
171
174
|
- !ruby/object:Gem::Version
|
172
|
-
version:
|
175
|
+
version: '0'
|
173
176
|
requirements: []
|
174
177
|
rubygems_version: 3.0.3
|
175
178
|
signing_key:
|
176
179
|
specification_version: 4
|
177
180
|
summary: Emit redis slowlog entries into fluentd
|
178
181
|
test_files:
|
179
|
-
-
|
180
|
-
-
|
182
|
+
- spec/fluent/plugin/redis_slowlog_input_spec.rb
|
183
|
+
- spec/spec_helper.rb
|
data/Gemfile.lock
DELETED
@@ -1,110 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
gitlab-fluent-plugin-redis-slowlog (0.0.1.pre)
|
5
|
-
fluentd (>= 0.14.10, < 2)
|
6
|
-
redis (>= 4.1.3, < 5)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
activesupport (3.2.22.5)
|
12
|
-
i18n (~> 0.6, >= 0.6.4)
|
13
|
-
multi_json (~> 1.0)
|
14
|
-
ast (2.4.0)
|
15
|
-
coderay (1.1.2)
|
16
|
-
concurrent-ruby (1.1.6)
|
17
|
-
cool.io (1.6.0)
|
18
|
-
diff-lcs (1.3)
|
19
|
-
fluentd (1.10.4)
|
20
|
-
cool.io (>= 1.4.5, < 2.0.0)
|
21
|
-
http_parser.rb (>= 0.5.1, < 0.7.0)
|
22
|
-
msgpack (>= 1.3.1, < 2.0.0)
|
23
|
-
serverengine (>= 2.0.4, < 3.0.0)
|
24
|
-
sigdump (~> 0.2.2)
|
25
|
-
strptime (>= 0.2.2, < 1.0.0)
|
26
|
-
tzinfo (>= 1.0, < 3.0)
|
27
|
-
tzinfo-data (~> 1.0)
|
28
|
-
yajl-ruby (~> 1.0)
|
29
|
-
gitlab-styles (3.2.0)
|
30
|
-
rubocop (~> 0.74.0)
|
31
|
-
rubocop-gitlab-security (~> 0.1.0)
|
32
|
-
rubocop-performance (~> 1.4.1)
|
33
|
-
rubocop-rails (~> 2.0)
|
34
|
-
rubocop-rspec (~> 1.36)
|
35
|
-
http_parser.rb (0.6.0)
|
36
|
-
i18n (0.9.5)
|
37
|
-
concurrent-ruby (~> 1.0)
|
38
|
-
jaro_winkler (1.5.4)
|
39
|
-
method_source (0.9.2)
|
40
|
-
msgpack (1.3.3)
|
41
|
-
multi_json (1.14.1)
|
42
|
-
parallel (1.19.1)
|
43
|
-
parser (2.7.1.3)
|
44
|
-
ast (~> 2.4.0)
|
45
|
-
power_assert (1.1.3)
|
46
|
-
pry (0.12.2)
|
47
|
-
coderay (~> 1.1.0)
|
48
|
-
method_source (~> 0.9.0)
|
49
|
-
rack (2.2.2)
|
50
|
-
rainbow (3.0.0)
|
51
|
-
rake (12.3.3)
|
52
|
-
redis (4.1.4)
|
53
|
-
rspec (3.9.0)
|
54
|
-
rspec-core (~> 3.9.0)
|
55
|
-
rspec-expectations (~> 3.9.0)
|
56
|
-
rspec-mocks (~> 3.9.0)
|
57
|
-
rspec-core (3.9.2)
|
58
|
-
rspec-support (~> 3.9.3)
|
59
|
-
rspec-expectations (3.9.2)
|
60
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
61
|
-
rspec-support (~> 3.9.0)
|
62
|
-
rspec-mocks (3.9.1)
|
63
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
64
|
-
rspec-support (~> 3.9.0)
|
65
|
-
rspec-support (3.9.3)
|
66
|
-
rubocop (0.74.0)
|
67
|
-
jaro_winkler (~> 1.5.1)
|
68
|
-
parallel (~> 1.10)
|
69
|
-
parser (>= 2.6)
|
70
|
-
rainbow (>= 2.2.2, < 4.0)
|
71
|
-
ruby-progressbar (~> 1.7)
|
72
|
-
unicode-display_width (>= 1.4.0, < 1.7)
|
73
|
-
rubocop-gitlab-security (0.1.1)
|
74
|
-
rubocop (>= 0.51)
|
75
|
-
rubocop-performance (1.4.1)
|
76
|
-
rubocop (>= 0.71.0)
|
77
|
-
rubocop-rails (2.5.2)
|
78
|
-
activesupport
|
79
|
-
rack (>= 1.1)
|
80
|
-
rubocop (>= 0.72.0)
|
81
|
-
rubocop-rspec (1.39.0)
|
82
|
-
rubocop (>= 0.68.1)
|
83
|
-
ruby-progressbar (1.10.1)
|
84
|
-
serverengine (2.2.1)
|
85
|
-
sigdump (~> 0.2.2)
|
86
|
-
sigdump (0.2.4)
|
87
|
-
strptime (0.2.4)
|
88
|
-
test-unit (3.2.9)
|
89
|
-
power_assert
|
90
|
-
tzinfo (2.0.2)
|
91
|
-
concurrent-ruby (~> 1.0)
|
92
|
-
tzinfo-data (1.2020.1)
|
93
|
-
tzinfo (>= 1.0.0)
|
94
|
-
unicode-display_width (1.6.1)
|
95
|
-
yajl-ruby (1.4.1)
|
96
|
-
|
97
|
-
PLATFORMS
|
98
|
-
ruby
|
99
|
-
|
100
|
-
DEPENDENCIES
|
101
|
-
bundler (~> 2.1.4)
|
102
|
-
gitlab-fluent-plugin-redis-slowlog!
|
103
|
-
gitlab-styles (~> 3.2.0)
|
104
|
-
pry (~> 0.12.2)
|
105
|
-
rake (~> 12.0)
|
106
|
-
rspec (~> 3.9.0)
|
107
|
-
test-unit (~> 3.2.9)
|
108
|
-
|
109
|
-
BUNDLED WITH
|
110
|
-
2.1.4
|
data/test/helper.rb
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.expand_path("../../", __FILE__))
|
2
|
-
require "test-unit"
|
3
|
-
require "fluent/test"
|
4
|
-
require "fluent/test/driver/input"
|
5
|
-
require "fluent/test/helpers"
|
6
|
-
|
7
|
-
Test::Unit::TestCase.include(Fluent::Test::Helpers)
|
8
|
-
Test::Unit::TestCase.extend(Fluent::Test::Helpers)
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require "helper"
|
2
|
-
require "fluent/plugin/in_redis_slowlog.rb"
|
3
|
-
|
4
|
-
class RedisSlowlogInputTest < Test::Unit::TestCase
|
5
|
-
setup do
|
6
|
-
Fluent::Test.setup
|
7
|
-
end
|
8
|
-
|
9
|
-
test "failure" do
|
10
|
-
flunk
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
def create_driver(conf)
|
16
|
-
Fluent::Test::Driver::Input.new(Fluent::Plugin::RedisSlowlogInput).configure(conf)
|
17
|
-
end
|
18
|
-
end
|