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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9fd4d916e4d8cc9ebb39d62e847de1c2dca1ce0175d738ca55430a962b3283ab
4
- data.tar.gz: b3e6baacf5bd683c39eca587c55ea0326ffe18a55d3b4f8b23ba435642641b8c
3
+ metadata.gz: 002b7169e3f3ac6493eb09dca5c2e3820a944f38c64a0b45641f3cdbd1717ddf
4
+ data.tar.gz: eac3646a2404665924c4fa30114b91ecce49dbadef3919d89eab458450568328
5
5
  SHA512:
6
- metadata.gz: 2e783b77515eb3ec55b4684e11d3014fdea761b057d22fb3935eafd7064d9fcb7038b8f78f7fa7e9aa238d339c8a5c3d1cac358a430c207f6ba9cd19bf8ae55a
7
- data.tar.gz: 77dace38e2de7a851547ee25502943f0d610cceefa8ee4d1194e084301852bf3b1e8fd93e79144f6c81865d7aadfe3c3705a210f3ca4dee2029e2daa5fbdf989
6
+ metadata.gz: 354478f3573f0934dcee72305069aa8f25333087d1667fc4e127963b8f8f955b66a02462925e4672f27f80e43b772640a68a4760266f461704bd9486ad66a3ef
7
+ data.tar.gz: f6d89c2db73d337b1aa52e9838ab08f6f3bda80e7053307482fa5b284b4b6f81ae0389e2a20411fbcc383c878b5309a320946d5849d43fa466e469037b9d5102
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,10 @@
1
+ image: "ruby:2.7"
2
+
3
+ test:
4
+ before_script:
5
+ - bundle install --jobs $(nproc)
6
+ script:
7
+ - bundle exec rake test
8
+ cache:
9
+ paths:
10
+ - vendor/ruby
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-postgresql-csvlog (0.0.1)
4
+ fluent-plugin-postgresql-csvlog (0.0.2)
5
5
  fluentd (>= 1.0, < 2)
6
6
  pg_query (~> 1.3)
7
7
 
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.1'
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
@@ -13,3 +13,4 @@ Test::Unit::TestCase.include(Fluent::Test::Helpers)
13
13
 
14
14
  require 'fluent/plugin/filter_postgresql_slowlog'
15
15
  require 'fluent/plugin/filter_postgresql_redactor'
16
+ require 'fluent/plugin/filter_marginalia'
@@ -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.1
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-10 00:00:00.000000000 Z
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