fluent-plugin-postgresql-csvlog 0.1.0 → 0.2.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 +4 -4
- data/README.md +3 -1
- data/fluent-plugin-postgresql-csvlog.gemspec +1 -1
- data/lib/fluent/plugin/filter_postgresql_redactor.rb +8 -5
- data/lib/fluent/plugin/filter_postgresql_slowlog.rb +4 -1
- data/test/plugin/test_filter_marginalia.rb +21 -2
- data/test/plugin/test_filter_postgresql_redactor.rb +28 -9
- data/test/plugin/test_filter_postgresql_slowlog.rb +26 -2
- metadata +2 -3
- data/Gemfile.lock +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5dda962fe3d98ea5f101183e982959b78c92142ca2b9a7807e51567a2bc75819
|
4
|
+
data.tar.gz: 3efd68ecdc6bcdb0a3341b2a5961452508ea92b10a2e5eeba6843cb29f27009a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47099891a7c455ce85e98239b3c69990b7c14b5450f2be9d643902c00ac29a6bbb7a5f34678380b1e310414308e80514f8915b0865f92ef7524221d35fc75ca8
|
7
|
+
data.tar.gz: 22bd0a3a4f2bf5ef903c3f90d11d0f92a5822887a07cd048eca701a4cb270c8be4f1c43f5fa2e9f3529ec26896874f9156dc0eac457c07028f41e03e3e7bf34a
|
data/README.md
CHANGED
@@ -47,11 +47,13 @@ ingest and parse PostgreSQL CSV logs:
|
|
47
47
|
|
48
48
|
<filter postgres.postgres_csv>
|
49
49
|
@type postgresql_slowlog
|
50
|
+
output_key query
|
50
51
|
</filter>
|
51
52
|
|
52
53
|
<filter postgres.postgres_csv>
|
53
54
|
@type postgresql_redactor
|
54
|
-
|
55
|
+
input_key query
|
56
|
+
output_key sql
|
55
57
|
fingerprint_key fingerprint
|
56
58
|
</filter>
|
57
59
|
|
@@ -2,7 +2,7 @@ $:.push File.expand_path('lib', __dir__)
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'fluent-plugin-postgresql-csvlog'
|
5
|
-
s.version = '0.
|
5
|
+
s.version = '0.2.0'
|
6
6
|
s.authors = ['stanhu']
|
7
7
|
s.email = ['stanhu@gmail.com']
|
8
8
|
s.homepage = 'https://gitlab.com/gitlab-org/fluent-plugin-postgresql-csvlog'
|
@@ -7,22 +7,25 @@ module Fluent::Plugin
|
|
7
7
|
class PostgreSQLRedactor < Filter
|
8
8
|
Fluent::Plugin.register_filter('postgresql_redactor', self)
|
9
9
|
|
10
|
-
desc '
|
11
|
-
config_param :
|
10
|
+
desc 'Input field to parse for SQL queries'
|
11
|
+
config_param :input_key, :string, default: 'query'
|
12
|
+
|
13
|
+
desc 'Output field to store SQL queries'
|
14
|
+
config_param :output_key, :string, default: 'sql'
|
12
15
|
|
13
16
|
desc 'Name of field to store SQL query fingerprint'
|
14
17
|
config_param :fingerprint_key, :string, default: 'fingerprint'
|
15
18
|
|
16
19
|
def filter(_tag, _time, record)
|
17
|
-
statement = record[
|
20
|
+
statement = record[@input_key]
|
18
21
|
|
19
22
|
return record unless statement
|
20
23
|
|
21
24
|
normalized = PgQuery.normalize(statement)
|
22
25
|
record[@fingerprint_key] = PgQuery.parse(normalized).fingerprint if @fingerprint_key
|
23
26
|
|
24
|
-
record.delete(
|
25
|
-
record[@
|
27
|
+
record.delete(@input_key)
|
28
|
+
record[@output_key] = normalized
|
26
29
|
record.delete('message')
|
27
30
|
|
28
31
|
record
|
@@ -12,6 +12,9 @@ module Fluent
|
|
12
12
|
class PostgreSQLSlowLog < Filter
|
13
13
|
Fluent::Plugin.register_filter('postgresql_slowlog', self)
|
14
14
|
|
15
|
+
desc 'Field to output SQL queries'
|
16
|
+
config_param :output_key, :string, default: 'query'
|
17
|
+
|
15
18
|
SLOWLOG_REGEXP = /^duration: (\d+(?:\.\d+)?) ms .*?:\s*(.*)/m.freeze
|
16
19
|
|
17
20
|
def filter(_tag, _time, record)
|
@@ -20,7 +23,7 @@ module Fluent
|
|
20
23
|
# rubocop:disable Style/PerlBackrefs
|
21
24
|
if record['message'] =~ SLOWLOG_REGEXP
|
22
25
|
record['duration_s'] = $1.to_f / 1000.0
|
23
|
-
record[
|
26
|
+
record[@output_key] = $2
|
24
27
|
end
|
25
28
|
# rubocop:enable Style/PerlBackrefs
|
26
29
|
|
@@ -22,7 +22,8 @@ class Marginalia < Test::Unit::TestCase
|
|
22
22
|
inputs = [
|
23
23
|
{ 'statement' => 'SELECT * FROM projects' },
|
24
24
|
{ 'statement' => 'SELECT COUNT(*) FROM "projects" /* this is just a comment */' },
|
25
|
-
{ 'statement' => 'SELECT COUNT(*) FROM "projects" /*application:sidekiq,correlation_id:d67cae54c169e0cab7d73389e2934f0e,jid:52a1c8a9e4c555ea573f20f0,job_class:Geo::MetricsUpdateWorker*/' }
|
25
|
+
{ 'statement' => 'SELECT COUNT(*) FROM "projects" /*application:sidekiq,correlation_id:d67cae54c169e0cab7d73389e2934f0e,jid:52a1c8a9e4c555ea573f20f0,job_class:Geo::MetricsUpdateWorker*/' },
|
26
|
+
{ 'statement' => 'SELECT COUNT(*) FROM "projects" /*application:web,correlation_id:01F1D2T1SC9DM82A4865ATG1CP,endpoint_id:POST /api/:version/groups/:id/-/packages/mavenpath/:file_name*/' }
|
26
27
|
]
|
27
28
|
|
28
29
|
d.run(default_tag: @tag) do
|
@@ -40,10 +41,19 @@ class Marginalia < Test::Unit::TestCase
|
|
40
41
|
}
|
41
42
|
),
|
42
43
|
d.filtered[2].last)
|
44
|
+
assert_equal(inputs[3].merge(
|
45
|
+
{
|
46
|
+
'application' => 'web',
|
47
|
+
'correlation_id' => '01F1D2T1SC9DM82A4865ATG1CP',
|
48
|
+
'endpoint_id' => 'POST /api/:version/groups/:id/-/packages/mavenpath/:file_name'
|
49
|
+
}
|
50
|
+
),
|
51
|
+
d.filtered[3].last)
|
43
52
|
|
44
53
|
assert_equal('SELECT * FROM projects', d.filtered[0].last['statement'])
|
45
54
|
assert_equal('SELECT COUNT(*) FROM "projects"', d.filtered[1].last['statement'])
|
46
55
|
assert_equal('SELECT COUNT(*) FROM "projects"', d.filtered[2].last['statement'])
|
56
|
+
assert_equal('SELECT COUNT(*) FROM "projects"', d.filtered[3].last['statement'])
|
47
57
|
end
|
48
58
|
|
49
59
|
test 'parses prepended Marginalia comments' do
|
@@ -52,6 +62,7 @@ class Marginalia < Test::Unit::TestCase
|
|
52
62
|
inputs = [
|
53
63
|
{ 'statement' => '/* this is just a comment */ SELECT COUNT(*) FROM "projects"' },
|
54
64
|
{ 'statement' => '/*application:sidekiq,correlation_id:d67cae54c169e0cab7d73389e2934f0e,jid:52a1c8a9e4c555ea573f20f0,job_class:Geo::MetricsUpdateWorker*/ SELECT COUNT(*) FROM "projects"' },
|
65
|
+
{ 'statement' => '/*application:web,correlation_id:01F1D2T1SC9DM82A4865ATG1CP,endpoint_id:POST /api/:version/groups/:id/-/packages/mavenpath/:file_name*/ SELECT COUNT(*) FROM "projects"' },
|
55
66
|
{ 'statement' => '/*application:sidekiq*/ SELECT COUNT(*) FROM "projects"',
|
56
67
|
'application' => 'test-conflict' }
|
57
68
|
]
|
@@ -72,10 +83,18 @@ class Marginalia < Test::Unit::TestCase
|
|
72
83
|
d.filtered[1].last)
|
73
84
|
assert_equal(inputs[2].merge(
|
74
85
|
{
|
75
|
-
'
|
86
|
+
'application' => 'web',
|
87
|
+
'correlation_id' => '01F1D2T1SC9DM82A4865ATG1CP',
|
88
|
+
'endpoint_id' => 'POST /api/:version/groups/:id/-/packages/mavenpath/:file_name'
|
76
89
|
}
|
77
90
|
),
|
78
91
|
d.filtered[2].last)
|
92
|
+
assert_equal(inputs[3].merge(
|
93
|
+
{
|
94
|
+
'statement_application' => 'sidekiq'
|
95
|
+
}
|
96
|
+
),
|
97
|
+
d.filtered[3].last)
|
79
98
|
|
80
99
|
assert_equal('SELECT COUNT(*) FROM "projects"', d.filtered[0].last['statement'])
|
81
100
|
assert_equal('SELECT COUNT(*) FROM "projects"', d.filtered[1].last['statement'])
|
@@ -8,11 +8,7 @@ class PostgreSQLRedactorTest < Test::Unit::TestCase
|
|
8
8
|
@tag = 'test.tag'
|
9
9
|
end
|
10
10
|
|
11
|
-
CONFIG = '
|
12
|
-
<filter test.tag>
|
13
|
-
@type postgresql_redactor
|
14
|
-
</filter>
|
15
|
-
'
|
11
|
+
CONFIG = ''
|
16
12
|
|
17
13
|
def create_driver(conf = CONFIG)
|
18
14
|
Fluent::Test::Driver::Filter.new(Fluent::Plugin::PostgreSQLRedactor).configure(conf)
|
@@ -23,7 +19,7 @@ class PostgreSQLRedactorTest < Test::Unit::TestCase
|
|
23
19
|
|
24
20
|
inputs = [
|
25
21
|
{ 'message' => 'duration: 2357.1 ms execute <unnamed>: SELECT * FROM projects WHERE id = 1',
|
26
|
-
'
|
22
|
+
'query' => %(SELECT * FROM projects WHERE id = 1),
|
27
23
|
'duration_s' => 2.3571 }
|
28
24
|
]
|
29
25
|
|
@@ -38,13 +34,36 @@ class PostgreSQLRedactorTest < Test::Unit::TestCase
|
|
38
34
|
test 'handles parse errors' do
|
39
35
|
d = create_driver
|
40
36
|
|
41
|
-
input = { '
|
37
|
+
input = { 'query' => 'create index something test (bla) include (bar)' }
|
42
38
|
|
43
39
|
d.run(default_tag: @tag) do
|
44
40
|
d.feed(input)
|
45
41
|
end
|
46
42
|
|
47
|
-
assert_equal(%w[pg_query_error
|
48
|
-
assert_equal(input['
|
43
|
+
assert_equal(%w[pg_query_error query], d.filtered[0].last.keys.sort)
|
44
|
+
assert_equal(input['query'], d.filtered[0].last['query'])
|
45
|
+
end
|
46
|
+
|
47
|
+
test 'uses configured input and output keys' do
|
48
|
+
d = create_driver(<<~CONF
|
49
|
+
input_key sql
|
50
|
+
output_key out_sql
|
51
|
+
CONF
|
52
|
+
)
|
53
|
+
|
54
|
+
inputs = [
|
55
|
+
{
|
56
|
+
'message' => 'duration: 2357.1 ms execute <unnamed>: SELECT * FROM projects WHERE id = 1',
|
57
|
+
'sql' => %(SELECT * FROM projects WHERE id = 1),
|
58
|
+
'duration_s' => 2.3571
|
59
|
+
}
|
60
|
+
]
|
61
|
+
|
62
|
+
d.run(default_tag: @tag) do
|
63
|
+
inputs.each { |input| d.feed(input) }
|
64
|
+
end
|
65
|
+
|
66
|
+
assert_equal(%w[duration_s fingerprint out_sql], d.filtered[0].last.keys.sort)
|
67
|
+
assert_equal('SELECT * FROM projects WHERE id = $1', d.filtered[0].last['out_sql'])
|
49
68
|
end
|
50
69
|
end
|
@@ -32,14 +32,14 @@ class PostgreSQLSlowLogTest < Test::Unit::TestCase
|
|
32
32
|
|
33
33
|
assert_equal(inputs[0].merge(
|
34
34
|
{
|
35
|
-
'
|
35
|
+
'query' => 'SELECT * FROM projects',
|
36
36
|
'duration_s' => 2.3571
|
37
37
|
}
|
38
38
|
),
|
39
39
|
d.filtered[0].last)
|
40
40
|
assert_equal(inputs[1].merge(
|
41
41
|
{
|
42
|
-
'
|
42
|
+
'query' => 'SELECT COUNT(*) FROM "projects" /*application:sidekiq,correlation_id:d67cae54c169e0cab7d73389e2934f0e,jid:52a1c8a9e4c555ea573f20f0,job_class:Geo::MetricsUpdateWorker*/',
|
43
43
|
'duration_s' => 1.873345
|
44
44
|
}
|
45
45
|
),
|
@@ -56,4 +56,28 @@ class PostgreSQLSlowLogTest < Test::Unit::TestCase
|
|
56
56
|
|
57
57
|
assert_equal(input, d.filtered[0].last)
|
58
58
|
end
|
59
|
+
|
60
|
+
test 'outputs slow log entries to configured output key' do
|
61
|
+
d = create_driver(
|
62
|
+
<<~CONF
|
63
|
+
output_key my_key
|
64
|
+
CONF
|
65
|
+
)
|
66
|
+
|
67
|
+
inputs = [
|
68
|
+
{ 'message' => 'duration: 2357.1 ms execute <unnamed>: SELECT * FROM projects' }
|
69
|
+
]
|
70
|
+
|
71
|
+
d.run(default_tag: @tag) do
|
72
|
+
inputs.each { |input| d.feed(input) }
|
73
|
+
end
|
74
|
+
|
75
|
+
assert_equal(inputs[0].merge(
|
76
|
+
{
|
77
|
+
'my_key' => 'SELECT * FROM projects',
|
78
|
+
'duration_s' => 2.3571
|
79
|
+
}
|
80
|
+
),
|
81
|
+
d.filtered[0].last)
|
82
|
+
end
|
59
83
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-postgresql-csvlog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- stanhu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -81,7 +81,6 @@ extra_rdoc_files: []
|
|
81
81
|
files:
|
82
82
|
- ".gitlab-ci.yml"
|
83
83
|
- Gemfile
|
84
|
-
- Gemfile.lock
|
85
84
|
- LICENSE
|
86
85
|
- README.md
|
87
86
|
- Rakefile
|
data/Gemfile.lock
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
fluent-plugin-postgresql-csvlog (0.1.0)
|
5
|
-
fluentd (>= 1.0, < 2)
|
6
|
-
pg_query (~> 2.0)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
concurrent-ruby (1.1.8)
|
12
|
-
cool.io (1.7.1)
|
13
|
-
fluentd (1.12.1)
|
14
|
-
bundler
|
15
|
-
cool.io (>= 1.4.5, < 2.0.0)
|
16
|
-
http_parser.rb (>= 0.5.1, < 0.7.0)
|
17
|
-
msgpack (>= 1.3.1, < 2.0.0)
|
18
|
-
serverengine (>= 2.2.2, < 3.0.0)
|
19
|
-
sigdump (~> 0.2.2)
|
20
|
-
strptime (>= 0.2.2, < 1.0.0)
|
21
|
-
tzinfo (>= 1.0, < 3.0)
|
22
|
-
tzinfo-data (~> 1.0)
|
23
|
-
yajl-ruby (~> 1.0)
|
24
|
-
google-protobuf (3.15.6-universal-darwin)
|
25
|
-
http_parser.rb (0.6.0)
|
26
|
-
msgpack (1.4.2)
|
27
|
-
pg_query (2.0.1)
|
28
|
-
google-protobuf (~> 3.15.5)
|
29
|
-
power_assert (2.0.0)
|
30
|
-
rake (13.0.3)
|
31
|
-
serverengine (2.2.3)
|
32
|
-
sigdump (~> 0.2.2)
|
33
|
-
sigdump (0.2.4)
|
34
|
-
strptime (0.2.5)
|
35
|
-
test-unit (3.4.0)
|
36
|
-
power_assert
|
37
|
-
tzinfo (2.0.4)
|
38
|
-
concurrent-ruby (~> 1.0)
|
39
|
-
tzinfo-data (1.2021.1)
|
40
|
-
tzinfo (>= 1.0.0)
|
41
|
-
yajl-ruby (1.4.1)
|
42
|
-
|
43
|
-
PLATFORMS
|
44
|
-
ruby
|
45
|
-
|
46
|
-
DEPENDENCIES
|
47
|
-
fluent-plugin-postgresql-csvlog!
|
48
|
-
rake
|
49
|
-
test-unit (~> 3.2)
|
50
|
-
|
51
|
-
BUNDLED WITH
|
52
|
-
2.1.4
|