fluent-plugin-postgresql-csvlog 0.0.1 → 0.0.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/.gitlab-ci.yml +10 -0
- data/Gemfile.lock +1 -1
- data/README.md +6 -1
- data/Rakefile +12 -0
- data/fluent-plugin-postgresql-csvlog.gemspec +1 -1
- data/lib/fluent/plugin/filter_marginalia.rb +85 -0
- data/test/helper.rb +1 -0
- data/test/plugin/test_filter_marginalia.rb +76 -0
- metadata +11 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 002b7169e3f3ac6493eb09dca5c2e3820a944f38c64a0b45641f3cdbd1717ddf
|
4
|
+
data.tar.gz: eac3646a2404665924c4fa30114b91ecce49dbadef3919d89eab458450568328
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 354478f3573f0934dcee72305069aa8f25333087d1667fc4e127963b8f8f955b66a02462925e4672f27f80e43b772640a68a4760266f461704bd9486ad66a3ef
|
7
|
+
data.tar.gz: f6d89c2db73d337b1aa52e9838ab08f6f3bda80e7053307482fa5b284b4b6f81ae0389e2a20411fbcc383c878b5309a320946d5849d43fa466e469037b9d5102
|
data/.gitlab-ci.yml
ADDED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -6,6 +6,7 @@ parse PostgreSQL CSV log files and extract slow log information:
|
|
6
6
|
- `MultilineCSVParser`: Parses CSV files that span multiple lines
|
7
7
|
- `PostgreSQLSlowLog`: Extracts slow log entries into `duration_s` and `statement` fields
|
8
8
|
- `PostgreSQLRedactor`: Normalizes the SQL query and redacts sensitive information
|
9
|
+
- `Marginalia`: Parses [Marginalia comments](https://github.com/basecamp/marginalia) into key-value pairs and stores them
|
9
10
|
|
10
11
|
## Installation
|
11
12
|
|
@@ -28,7 +29,6 @@ The configuration below shows how you might use these filters to
|
|
28
29
|
ingest and parse PostgreSQL CSV logs:
|
29
30
|
|
30
31
|
```conf
|
31
|
-
## PostgreSQL csvlog (enabled with
|
32
32
|
<source>
|
33
33
|
@type tail
|
34
34
|
tag postgres.postgres_csv
|
@@ -53,6 +53,11 @@ ingest and parse PostgreSQL CSV logs:
|
|
53
53
|
@type postgresql_redactor
|
54
54
|
</filter>
|
55
55
|
|
56
|
+
<filter postgres.postgres_csv>
|
57
|
+
@type marginalia
|
58
|
+
key sql
|
59
|
+
</filter>
|
60
|
+
|
56
61
|
# Output resulting JSON file to a directory in /tmp
|
57
62
|
<match postgres.*>
|
58
63
|
@type file
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rake/testtask'
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |test|
|
7
|
+
test.libs << 'lib' << 'test'
|
8
|
+
test.test_files = FileList['test/**/test_*.rb']
|
9
|
+
test.verbose = true
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => [:build]
|
@@ -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.0.
|
5
|
+
s.version = '0.0.2'
|
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'
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fluent/plugin/filter'
|
4
|
+
|
5
|
+
module Fluent
|
6
|
+
module Plugin
|
7
|
+
# Filters SQL statements for Marginalia comments.
|
8
|
+
#
|
9
|
+
# Examples:
|
10
|
+
# SELECT COUNT(*) FROM "projects" /*application:sidekiq,correlation_id:d67cae54c169e0cab7d73389e2934f0e,jid:52a1c8a9e4c555ea573f20f0,job_class:Geo::MetricsUpdateWorker*/
|
11
|
+
# /*application:sidekiq,correlation_id:d67cae54c169e0cab7d73389e2934f0e,jid:52a1c8a9e4c555ea573f20f0,job_class:Geo::MetricsUpdateWorker*/ SELECT COUNT(*) FROM "projects"
|
12
|
+
#
|
13
|
+
class Marginalia < Filter
|
14
|
+
Fluent::Plugin.register_filter('marginalia', self)
|
15
|
+
|
16
|
+
desc 'Field to parse for Marginalia comments (key1:value1,key2:value2)'
|
17
|
+
config_param :key, :string, default: 'sql'
|
18
|
+
|
19
|
+
MARGINALIA_PREPENDED_REGEXP = %r{^(?<comment>/\*.*\*/).*}m.freeze
|
20
|
+
MARGINALIA_APPENDED_REGEXP = %r{.*(?<comment>/\*.*\*/)$}m.freeze
|
21
|
+
MARGINALIA_KEY_VALUE_REGEXP = /^(?<key>.*):?(?<value>.*)$/.freeze
|
22
|
+
|
23
|
+
def filter(_tag, _time, record)
|
24
|
+
parse_comments(record)
|
25
|
+
|
26
|
+
record
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def parse_comments(record)
|
32
|
+
sql = record[@key]
|
33
|
+
|
34
|
+
return unless sql
|
35
|
+
|
36
|
+
comment_match = match_marginalia_comment(sql)
|
37
|
+
|
38
|
+
return unless comment_match
|
39
|
+
|
40
|
+
entries = extract_entries(comment_match['comment'])
|
41
|
+
|
42
|
+
entries.each do |component|
|
43
|
+
data = component.split(':', 2)
|
44
|
+
|
45
|
+
break unless data.length == 2
|
46
|
+
|
47
|
+
stored_key = store_key(record, data[0])
|
48
|
+
record[stored_key] = data[1]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def match_marginalia_comment(sql)
|
53
|
+
matched = MARGINALIA_PREPENDED_REGEXP.match(sql)
|
54
|
+
|
55
|
+
return matched if matched
|
56
|
+
|
57
|
+
MARGINALIA_APPENDED_REGEXP.match(sql)
|
58
|
+
end
|
59
|
+
|
60
|
+
def extract_entries(comment)
|
61
|
+
comment = scrub_comment(comment)
|
62
|
+
|
63
|
+
return [] unless comment
|
64
|
+
|
65
|
+
comment.split(',')
|
66
|
+
end
|
67
|
+
|
68
|
+
def scrub_comment(comment)
|
69
|
+
return unless comment
|
70
|
+
|
71
|
+
comment.strip!
|
72
|
+
comment.gsub!(%r{^/\*}, '')
|
73
|
+
comment.gsub!(%r{\*/$}, '')
|
74
|
+
end
|
75
|
+
|
76
|
+
def store_key(record, component_key)
|
77
|
+
if record.key?(component_key)
|
78
|
+
"#{@key}_#{component_key}"
|
79
|
+
else
|
80
|
+
component_key
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/test/helper.rb
CHANGED
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../helper'
|
4
|
+
|
5
|
+
class Marginalia < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
Fluent::Test.setup
|
8
|
+
@tag = 'test.tag'
|
9
|
+
end
|
10
|
+
|
11
|
+
CONFIG = '
|
12
|
+
key statement
|
13
|
+
'
|
14
|
+
|
15
|
+
def create_driver(conf = CONFIG)
|
16
|
+
Fluent::Test::Driver::Filter.new(Fluent::Plugin::Marginalia).configure(conf)
|
17
|
+
end
|
18
|
+
|
19
|
+
test 'parses appended Marginalia comments' do
|
20
|
+
d = create_driver
|
21
|
+
|
22
|
+
inputs = [
|
23
|
+
{ 'statement' => 'SELECT * FROM projects' },
|
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*/' }
|
26
|
+
]
|
27
|
+
|
28
|
+
d.run(default_tag: @tag) do
|
29
|
+
inputs.each { |input| d.feed(input) }
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_equal(inputs[0].merge, d.filtered[0].last)
|
33
|
+
assert_equal(inputs[1].merge, d.filtered[1].last)
|
34
|
+
assert_equal(inputs[2].merge(
|
35
|
+
{
|
36
|
+
'application' => 'sidekiq',
|
37
|
+
'correlation_id' => 'd67cae54c169e0cab7d73389e2934f0e',
|
38
|
+
'jid' => '52a1c8a9e4c555ea573f20f0',
|
39
|
+
'job_class' => 'Geo::MetricsUpdateWorker'
|
40
|
+
}
|
41
|
+
),
|
42
|
+
d.filtered[2].last)
|
43
|
+
end
|
44
|
+
|
45
|
+
test 'parses prepended Marginalia comments' do
|
46
|
+
d = create_driver
|
47
|
+
|
48
|
+
inputs = [
|
49
|
+
{ 'statement' => '/* this is just a comment */ SELECT COUNT(*) FROM "projects"' },
|
50
|
+
{ 'statement' => '/*application:sidekiq,correlation_id:d67cae54c169e0cab7d73389e2934f0e,jid:52a1c8a9e4c555ea573f20f0,job_class:Geo::MetricsUpdateWorker*/ SELECT COUNT(*) FROM "projects"' },
|
51
|
+
{ 'statement' => '/*application:sidekiq*/ SELECT COUNT(*) FROM "projects"',
|
52
|
+
'application' => 'test-conflict' }
|
53
|
+
]
|
54
|
+
|
55
|
+
d.run(default_tag: @tag) do
|
56
|
+
inputs.each { |input| d.feed(input) }
|
57
|
+
end
|
58
|
+
|
59
|
+
assert_equal(inputs[0].merge, d.filtered[0].last)
|
60
|
+
assert_equal(inputs[1].merge(
|
61
|
+
{
|
62
|
+
'application' => 'sidekiq',
|
63
|
+
'correlation_id' => 'd67cae54c169e0cab7d73389e2934f0e',
|
64
|
+
'jid' => '52a1c8a9e4c555ea573f20f0',
|
65
|
+
'job_class' => 'Geo::MetricsUpdateWorker'
|
66
|
+
}
|
67
|
+
),
|
68
|
+
d.filtered[1].last)
|
69
|
+
assert_equal(inputs[2].merge(
|
70
|
+
{
|
71
|
+
'statement_application' => 'sidekiq'
|
72
|
+
}
|
73
|
+
),
|
74
|
+
d.filtered[2].last)
|
75
|
+
end
|
76
|
+
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.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- stanhu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -79,15 +79,19 @@ executables: []
|
|
79
79
|
extensions: []
|
80
80
|
extra_rdoc_files: []
|
81
81
|
files:
|
82
|
+
- ".gitlab-ci.yml"
|
82
83
|
- Gemfile
|
83
84
|
- Gemfile.lock
|
84
85
|
- LICENSE
|
85
86
|
- README.md
|
87
|
+
- Rakefile
|
86
88
|
- fluent-plugin-postgresql-csvlog.gemspec
|
89
|
+
- lib/fluent/plugin/filter_marginalia.rb
|
87
90
|
- lib/fluent/plugin/filter_postgresql_redactor.rb
|
88
91
|
- lib/fluent/plugin/filter_postgresql_slowlog.rb
|
89
92
|
- lib/fluent/plugin/parser_multiline_csv.rb
|
90
93
|
- test/helper.rb
|
94
|
+
- test/plugin/test_filter_marginalia.rb
|
91
95
|
- test/plugin/test_filter_postgresql_redactor.rb
|
92
96
|
- test/plugin/test_filter_postgresql_slowlog.rb
|
93
97
|
homepage: https://gitlab.com/gitlab-org/fluent-plugin-postgresql-csvlog
|
@@ -112,4 +116,8 @@ rubygems_version: 3.1.4
|
|
112
116
|
signing_key:
|
113
117
|
specification_version: 4
|
114
118
|
summary: fluentd plugins to work with PostgreSQL CSV logs
|
115
|
-
test_files:
|
119
|
+
test_files:
|
120
|
+
- test/helper.rb
|
121
|
+
- test/plugin/test_filter_marginalia.rb
|
122
|
+
- test/plugin/test_filter_postgresql_redactor.rb
|
123
|
+
- test/plugin/test_filter_postgresql_slowlog.rb
|