logstash-output-charrington 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8166adfa6e084d6e0fd56921edbc8b71dae22e6e5e282c86f73753692f14dbf
4
- data.tar.gz: 5b0286ebc0540a5152a11ffacd441d465c6cc44b7c67e66a4b08f5c825588dca
3
+ metadata.gz: fbbae45d9c763ffa27448320f7150f9827732ef5b20823c078664d6deb8ab652
4
+ data.tar.gz: c18245e0ac6cbb11e30a824fdaf2a39dcf466e4631f307a9b1bd6aa9484bb5e1
5
5
  SHA512:
6
- metadata.gz: b977663c714b04890525419c98773e80f2e55993ff3cfc0e50ca3dee6d2b06e81a948a39d1e0004ba156ed219482592ddb0f604514310a95fd6e9ac66312db5d
7
- data.tar.gz: 32a8eee42bf6a88c3c3a244805546edc2a5cbe67626bd5b12450c2c963b1967f7aea2821cfbd068478a71a2364f4ca24e1fc5759c76f7ebb6bdffb64c5011e43
6
+ metadata.gz: d139e03b049aae067a3e5827c520eaa855e33fb889e33f51cec8cf308bb0923f04cca2b01b1b561c2578ccbe1c2ec731e6cf59918cbb101df055058403ef99c7
7
+ data.tar.gz: 898bb2a57d84e835a3b2e4933ebb387d1f0e030f6dc06f5c98c284aea4c51b5b6401401d85fb6bb842988d7c15497331d960735a7e57e5d9dd43c79d3f30a284
data/README.md CHANGED
@@ -1,94 +1,55 @@
1
- # logstash-output-jdbc
2
-
3
- [![Build Status](https://travis-ci.org/theangryangel/logstash-output-jdbc.svg?branch=master)](https://travis-ci.org/theangryangel/logstash-output-jdbc) [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=the_angry_angel&url=https://github.com/the_angry_angel/logstash-output-jdbc&title=logstash-output-jdbc&language=&tags=github&category=software)
4
-
5
- This plugin is provided as an external plugin and is not part of the Logstash project.
6
-
7
- This plugin allows you to output to SQL databases, using JDBC adapters.
8
- See below for tested adapters, and example configurations.
9
-
10
- This has not yet been extensively tested with all JDBC drivers and may not yet work for you.
11
-
12
- If you do find this works for a JDBC driver without an example, let me know and provide a small example configuration if you can.
13
-
14
- This plugin does not bundle any JDBC jar files, and does expect them to be in a
15
- particular location. Please ensure you read the 4 installation lines below.
16
-
17
- ## Support & release schedule
18
- I no longer have time at work to maintain this plugin in step with Logstash's releases, and I am not completely immersed in the Logstash ecosystem. If something is broken for you I will do my best to help, but I cannot guarantee timeframes.
19
-
20
- Pull requests are always welcome.
21
-
22
- ## Changelog
23
- See CHANGELOG.md
24
-
25
- ## Versions
26
- Released versions are available via rubygems, and typically tagged.
27
-
28
- For development:
29
- - See master branch for logstash v5 & v6 :warning: This is untested under Logstash 6.3 at this time, and there has been 1 unverified report of an issue. Please use at your own risk until I can find the time to evaluate and test 6.3.
30
- - See v2.x branch for logstash v2
31
- - See v1.5 branch for logstash v1.5
32
- - See v1.4 branch for logstash 1.4
33
-
34
- ## Installation
35
- - Run `bin/logstash-plugin install logstash-output-charrington` in your logstash installation directory
36
- - Now either:
37
- - Use driver_jar_path in your configuraton to specify a path to your jar file
38
- - Or:
39
- - Create the directory vendor/jar/jdbc in your logstash installation (`mkdir -p vendor/jar/jdbc/`)
40
- - Add JDBC jar files to vendor/jar/jdbc in your logstash installation
41
- - And then configure (examples can be found in the examples directory)
42
-
43
- ## Configuration options
44
-
45
- | Option | Type | Description | Required? | Default |
46
- | ------ | ---- | ----------- | --------- | ------- |
47
- | driver_class | String | Specify a driver class if autoloading fails | No | |
48
- | driver_auto_commit | Boolean | If the driver does not support auto commit, you should set this to false | No | True |
49
- | driver_jar_path | String | File path to jar file containing your JDBC driver. This is optional, and all JDBC jars may be placed in $LOGSTASH_HOME/vendor/jar/jdbc instead. | No | |
50
- | connection_string | String | JDBC connection URL | Yes | |
51
- | connection_test | Boolean | Run a JDBC connection test. Some drivers do not function correctly, and you may need to disable the connection test to supress an error. Cockroach with the postgres JDBC driver is such an example. | No | Yes |
52
- | connection_test_query | String | Connection test and init query string, required for some JDBC drivers that don't support isValid(). Typically you'd set to this "SELECT 1" | No | |
53
- | username | String | JDBC username - this is optional as it may be included in the connection string, for many drivers | No | |
54
- | password | String | JDBC password - this is optional as it may be included in the connection string, for many drivers | No | |
55
- | statement | Array | An array of strings representing the SQL statement to run. Index 0 is the SQL statement that is prepared, all other array entries are passed in as parameters (in order). A parameter may either be a property of the event (i.e. "@timestamp", or "host") or a formatted string (i.e. "%{host} - %{message}" or "%{message}"). If a key is passed then it will be automatically converted as required for insertion into SQL. If it's a formatted string then it will be passed in verbatim. | Yes | |
56
- | unsafe_statement | Boolean | If yes, the statement is evaluated for event fields - this allows you to use dynamic table names, etc. **This is highly dangerous** and you should **not** use this unless you are 100% sure that the field(s) you are passing in are 100% safe. Failure to do so will result in possible SQL injections. Example statement: [ "insert into %{table_name_field} (column) values(?)", "fieldname" ] | No | False |
57
- | max_pool_size | Number | Maximum number of connections to open to the SQL server at any 1 time | No | 5 |
58
- | connection_timeout | Number | Number of milliseconds before a SQL connection is closed | No | 10000 |
59
- | flush_size | Number | Maximum number of entries to buffer before sending to SQL - if this is reached before idle_flush_time | No | 1000 |
60
- | max_flush_exceptions | Number | Number of sequential flushes which cause an exception, before the set of events are discarded. Set to a value less than 1 if you never want it to stop. This should be carefully configured with respect to retry_initial_interval and retry_max_interval, if your SQL server is not highly available | No | 10 |
61
- | retry_initial_interval | Number | Number of seconds before the initial retry in the event of a failure. On each failure it will be doubled until it reaches retry_max_interval | No | 2 |
62
- | retry_max_interval | Number | Maximum number of seconds between each retry | No | 128 |
63
- | retry_sql_states | Array of strings | An array of custom SQL state codes you wish to retry until `max_flush_exceptions`. Useful if you're using a JDBC driver which returns retry-able, but non-standard SQL state codes in it's exceptions. | No | [] |
64
- | event_as_json_keyword | String | The magic key word that the plugin looks for to convert the entire event into a JSON object. As Logstash does not support this out of the box with it's `sprintf` implementation, you can use whatever this field is set to in the statement parameters | No | @event |
65
- | enable_event_as_json_keyword | Boolean | Enables the magic keyword set in the configuration option `event_as_json_keyword`. Without this enabled the plugin will not convert the `event_as_json_keyword` into JSON encoding of the entire event. | No | False |
66
- | schema | String | Database schema | No | False |
67
-
68
- ## Example configurations
69
- Example logstash configurations, can now be found in the examples directory. Where possible we try to link every configuration with a tested jar.
70
-
71
- If you have a working sample configuration, for a DB thats not listed, pull requests are welcome.
72
-
73
- ## Development and Running tests
74
- For development tests are recommended to run inside a virtual machine (Vagrantfile is included in the repo), as it requires
75
- access to various database engines and could completely destroy any data in a live system.
76
-
77
- If you have vagrant available (this is temporary whilst I'm hacking on v5 support. I'll make this more streamlined later):
78
- - `vagrant up`
79
- - `vagrant ssh`
80
- - `cd /vagrant`
81
- - `gem install bundler`
82
- - `cd /vagrant && bundle install && bundle exec rake vendor && bundle exec rake install_jars`
83
- - `./scripts/travis-before_script.sh && source ./scripts/travis-variables.sh`
84
- - `bundle exec rspec`
85
-
86
- ## Releasing
87
- - Update Changelog
88
- - Bump version in gemspec
89
- - Commit
90
- - Create tag `git tag v<version-number-in-gemspec>`
91
- - `bundle exec rake install_jars`
92
- - `bundle exec rake pre_release_checks`
93
- - `gem build logstash-output-jdbc.gemspec`
94
- - `gem push`
1
+ # Logstash Output Charrington
2
+
3
+ Logstash Output Plugin to handle batching messages and dynamically create and alter tables.
4
+
5
+ Forked From [logstash-output-jdbc](https://github.com/theangryangel/logstash-output-jdbc)
6
+ ## Configure
7
+ Example Logstash Config
8
+ ```bash
9
+ input {
10
+ kafka {
11
+ auto_offset_reset => earliest
12
+ bootstrap_servers => "${LS_KAFKA_BOOTSTRAP_SERVERS:kafka:9092}"
13
+ codec => json
14
+ group_id => "winston_ls_pg_sinks_cg"
15
+ topics => [
16
+ "orwell.analytics.v1.json"
17
+ ]
18
+ }
19
+ }
20
+
21
+ filter {
22
+ if "_jsonparsefailure" in [tags] {
23
+ drop { }
24
+ }
25
+
26
+ ruby {
27
+ code => "
28
+ hash = event.to_hash
29
+ hash.each do |k,v|
30
+ if v == nil
31
+ event.remove(k)
32
+ end
33
+ end
34
+ "
35
+ }
36
+ }
37
+
38
+ output {
39
+ charrington {
40
+ driver_jar_path => "${DRIVER_PATH:/usr/share/logstash/vendor/jar/jdbc/postgresql-42.2.5.jar}"
41
+ connection_string => "jdbc:postgresql://${WINSTON_DATABASE_HOST}:5432/${WINSTON_DATABASE}?user=${WINSTON_DATABASE_USERNAME}&password=${WINSTON_DATABASE_PASSWORD}"
42
+ schema => "dea"
43
+ }
44
+
45
+ if "${LS_SHOW_DEBUG_OUTPUT}" == "true" {
46
+ stdout { codec => rubydebug }
47
+ }
48
+ }
49
+ ```
50
+
51
+ ## Build & Publish
52
+ ```bash
53
+ gem build logstash-output-charrington.gemspec # build
54
+ gem push logstash-output-charrington-x.x.x.gem # publish
55
+ ```
@@ -23,27 +23,10 @@ require File.join(File.dirname(__FILE__), "charrington/insert")
23
23
 
24
24
  class LogStash::Outputs::Charrington < LogStash::Outputs::Base
25
25
  concurrency :shared
26
+ config_name 'charrington'
26
27
 
27
28
  STRFTIME_FMT = '%Y-%m-%d %T.%L'.freeze
28
29
 
29
- # RETRYABLE_SQLSTATE_CLASSES = [
30
- # # Classes of retryable SQLSTATE codes
31
- # # Not all in the class will be retryable. However, this is the best that
32
- # # we've got right now.
33
- # # If a custom state code is required, set it in retry_sql_states.
34
- # '08', # Connection Exception
35
- # '24', # Invalid Cursor State (Maybe retry-able in some circumstances)
36
- # '25', # Invalid Transaction State
37
- # '40', # Transaction Rollback
38
- # '53', # Insufficient Resources
39
- # '54', # Program Limit Exceeded (MAYBE)
40
- # '55', # Object Not In Prerequisite State
41
- # '57', # Operator Intervention
42
- # '58', # System Error
43
- # ].freeze
44
-
45
- config_name 'charrington'
46
-
47
30
  # Driver class - Reintroduced for https://github.com/theangryangel/logstash-output-jdbc/issues/26
48
31
  config :driver_class, validate: :string
49
32
 
@@ -120,8 +103,11 @@ class LogStash::Outputs::Charrington < LogStash::Outputs::Base
120
103
  schema: @schema,
121
104
  max_retries: @max_flush_exceptions,
122
105
  retry_initial_interval: @retry_initial_interval }
123
-
124
106
  Charrington::Process.call(connection, event, opts)
107
+ rescue => e
108
+ @logger.error("Unable to process event. Event dropped. #{e.message}")
109
+ next
110
+ ensure
125
111
  connection.close unless connection.nil?
126
112
  end
127
113
  end
@@ -201,8 +187,6 @@ class LogStash::Outputs::Charrington < LogStash::Outputs::Base
201
187
  log_method = (retrying ? 'warn' : 'error')
202
188
 
203
189
  loop do
204
- # TODO reformat event output so that it only shows the fields necessary.
205
-
206
190
  @logger.send(log_method, log_text, :exception => current_exception, :event => event)
207
191
 
208
192
  if current_exception.respond_to? 'getNextException'
@@ -14,7 +14,7 @@ module Charrington
14
14
 
15
15
  def initialize(connection, event, table_name, columns)
16
16
  @connection = connection
17
- @event = event
17
+ @event = event.to_hash
18
18
  @table_name = table_name
19
19
  @columns = columns
20
20
  @column_types = []
@@ -77,7 +77,7 @@ module Charrington
77
77
  stmt = connection.prepareStatement(prep_sql(sql))
78
78
  stmt.execute()
79
79
  rescue Java::OrgPostgresqlUtil::PSQLException => e
80
- # @logger.error("#{e.message}")
80
+ puts "PSQLException: #{e.message}"
81
81
  ensure
82
82
  stmt.close unless stmt.nil?
83
83
  end
@@ -17,7 +17,7 @@ module Charrington
17
17
  @event = event.to_hash
18
18
  @table_name = table_name
19
19
  @columns = columns
20
- @column_types = []
20
+ @column_types = initial_columns
21
21
  end
22
22
 
23
23
  def call
@@ -53,6 +53,11 @@ module Charrington
53
53
  end
54
54
  end
55
55
 
56
+ def initial_columns
57
+ # Postgres
58
+ ["id SERIAL PRIMARY KEY", "inserted_at TIMESTAMP DEFAULT NOW()"]
59
+ end
60
+
56
61
  def create_table
57
62
  execute("CREATE TABLE IF NOT EXISTS #{table_name} (#{column_types.join(', ')})")
58
63
  end
@@ -61,7 +66,7 @@ module Charrington
61
66
  statement = connection.prepareStatement( sql.gsub(/\s+/, " ").strip )
62
67
  statement.execute()
63
68
  rescue Java::OrgPostgresqlUtil::PSQLException => e
64
- # @logger.error("#{e.message}")
69
+ puts "PSQLException: #{e.message}"
65
70
  ensure
66
71
  statement.close unless statement.nil?
67
72
  end
@@ -133,7 +133,7 @@ module Charrington
133
133
  statement = connection.prepareStatement( sql.gsub(/\s+/, " ").strip )
134
134
  statement.execute()
135
135
  rescue Java::OrgPostgresqlUtil::PSQLException => e
136
- @logger.error("#{e.message}")
136
+ puts "PSQLException: #{e.message}"
137
137
  ensure
138
138
  statement.close unless statement.nil?
139
139
  end
@@ -9,14 +9,17 @@ module Charrington
9
9
  Error = Class.new(StandardError)
10
10
  EventNil = Class.new(Error)
11
11
  TableNameNil = Class.new(Error)
12
+ ColumnBlacklist = Class.new(Error)
12
13
 
13
- KEY_BLACKLIST = ['host','path','jwt']
14
+ KEY_FILTER_BLACKLIST = ['host','path','jwt','sequence']
15
+ KEY_RAISE_BLACKLIST = ['id', 'inserted_at']
14
16
 
15
17
  def initialize(event)
16
18
  raise EventNil, "Event is nil" if event.nil?
17
- event = event.is_a?(Hash) ? event : event.to_hash
19
+ event = event.to_hash
18
20
  @event = drop_keys(event)
19
21
  @top_level_keys = @event.keys
22
+ check_blacklist
20
23
  end
21
24
 
22
25
  def call
@@ -28,8 +31,14 @@ module Charrington
28
31
 
29
32
  private
30
33
 
34
+ def check_blacklist
35
+ arr = []
36
+ KEY_RAISE_BLACKLIST.each { |k| arr << k if event.keys.include?(k) }
37
+ raise ColumnBlacklist, "Event contains these blacklisted keys: #{arr.join(",")}" unless arr.empty?
38
+ end
39
+
31
40
  def drop_keys(event)
32
- event.delete_if {|k, _v| k.start_with?("@") || KEY_BLACKLIST.include?(k) }
41
+ event.delete_if {|k, _v| k.start_with?("@") || KEY_FILTER_BLACKLIST.include?(k) }
33
42
  end
34
43
 
35
44
  def flatten_hash(hash)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-charrington'
3
- s.version = '0.2.0'
3
+ s.version = '0.2.1'
4
4
 
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = 'This plugin allows you to output to SQL, via JDBC'
@@ -30,4 +30,5 @@ Gem::Specification.new do |s|
30
30
  s.add_development_dependency 'rubocop', '0.41.2'
31
31
  s.add_development_dependency 'logstash-input-generator'
32
32
  s.add_development_dependency 'logstash-codec-json'
33
+ s.add_development_dependency 'insist'
33
34
  end
@@ -1,4 +1,5 @@
1
1
  require_relative '../charrington_spec_helper'
2
+ require 'insist'
2
3
 
3
4
  describe LogStash::Outputs::Charrington do
4
5
  describe 'when initializing' do
@@ -9,36 +10,55 @@ describe LogStash::Outputs::Charrington do
9
10
  end
10
11
  end
11
12
 
13
+ # describe 'integration tests with agent' do
14
+ # config <<-HEREDOC
15
+ # input {
16
+ # generator {
17
+ # message => '{"app_name": "Web App", "event": "From Agent"}'
18
+ # codec => 'json'
19
+ # count => 1
20
+ # }
21
+ # }
22
+
23
+ # output {
24
+ # charrington {
25
+ # connection_string => 'jdbc:postgresql://localhost:5432/winston?user=postgres&password=postgres'
26
+ # driver_jar_path => '/projects/logstash-output-charrington/vendor/postgresql-42.2.5.jar'
27
+ # schema => 'dea'
28
+ # }
29
+ # }
30
+ # HEREDOC
31
+
32
+ # agent do
33
+ # puts "IT'S WORKING!!!!!"
34
+ # end
35
+ # end
36
+
12
37
  describe 'integration tests' do
13
- config <<-CONFIG
14
- input {
15
- generator {
16
- message => '{"id": "abc", "app_name": "Web App", "event": "Hi - Dan"}'
17
- codec => 'json'
18
- count => 1
38
+ let(:config) do <<-CONFIG
39
+ input {
40
+ generator {
41
+ message => '{"app_name": "Web App", "event": "Hi - Dan"}'
42
+ codec => 'json'
43
+ count => 1
44
+ }
19
45
  }
20
- }
21
46
 
22
- output {
23
- charrington {
24
- connection_string => 'jdbc:postgresql://localhost:5432/winston?user=postgres&password=postgres'
25
- driver_jar_path => '/projects/logstash-output-charrington/vendor/postgresql-42.2.5.jar'
26
- schema => 'dea'
47
+ output {
48
+ charrington {
49
+ connection_string => 'jdbc:postgresql://localhost:5432/winston?user=postgres&password=postgres'
50
+ driver_jar_path => '/projects/logstash-output-charrington/vendor/postgresql-42.2.5.jar'
51
+ schema => 'dea'
52
+ }
27
53
  }
28
- }
29
- CONFIG
54
+ CONFIG
55
+ end
30
56
 
31
- agent do
32
- puts "IT'S WORKING!!!!!"
57
+ it("isn't effed") do
58
+ pipeline = new_pipeline_from_string(config)
59
+ pipeline.run
33
60
  end
34
61
  end
35
-
36
- # context 'running' do
37
- # it 'should transform some JSON' do
38
- # transformed = Charrington::Transform.call({"a" => 1})
39
- # puts transformed
40
- # end
41
- # end
42
62
  end
43
63
 
44
64
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-charrington
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - dconger
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-06-17 00:00:00.000000000 Z
13
+ date: 2019-06-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  requirement: !ruby/object:Gem::Requirement
@@ -130,6 +130,20 @@ dependencies:
130
130
  - - ">="
131
131
  - !ruby/object:Gem::Version
132
132
  version: '0'
133
+ - !ruby/object:Gem::Dependency
134
+ requirement: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ name: insist
140
+ prerelease: false
141
+ type: :development
142
+ version_requirements: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
133
147
  description: This gem is a logstash plugin required to be installed on top of the
134
148
  Logstash core pipeline using $LS_HOME/bin/logstash-plugin install 'logstash-output-charrington'.
135
149
  This gem is not a stand-alone program
@@ -144,6 +158,8 @@ files:
144
158
  - README.md
145
159
  - THANKS.md
146
160
  - lib/com/zaxxer/HikariCP/2.7.2/HikariCP-2.7.2.jar
161
+ - lib/commons-io/commons-io/2.4/commons-io-2.4.jar
162
+ - lib/de/flapdoodle/embed/de.flapdoodle.embed.process/2.0.2/de.flapdoodle.embed.process-2.0.2.jar
147
163
  - lib/logstash-output-charrington_jars.rb
148
164
  - lib/logstash/outputs/charrington.rb
149
165
  - lib/logstash/outputs/charrington/alter_table.rb
@@ -152,9 +168,16 @@ files:
152
168
  - lib/logstash/outputs/charrington/process.rb
153
169
  - lib/logstash/outputs/charrington/service.rb
154
170
  - lib/logstash/outputs/charrington/transform.rb
171
+ - lib/net/java/dev/jna/jna-platform/4.0.0/jna-platform-4.0.0.jar
172
+ - lib/net/java/dev/jna/jna/4.0.0/jna-4.0.0.jar
173
+ - lib/org/apache/commons/commons-compress/1.10/commons-compress-1.10.jar
174
+ - lib/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar
155
175
  - lib/org/apache/logging/log4j/log4j-api/2.6.2/log4j-api-2.6.2.jar
156
176
  - lib/org/apache/logging/log4j/log4j-slf4j-impl/2.6.2/log4j-slf4j-impl-2.6.2.jar
177
+ - lib/org/postgresql/postgresql/42.2.5/postgresql-42.2.5.jar
157
178
  - lib/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar
179
+ - lib/ru/yandex/qatools/embed/postgresql-embedded/2.10/postgresql-embedded-2.10.jar
180
+ - lib/ru/yandex/qatools/embed/postgresql-embedded/2.8/postgresql-embedded-2.8.jar
158
181
  - logstash-output-charrington.gemspec
159
182
  - spec/charrington_spec_helper.rb
160
183
  - spec/outputs/charrington_mysql_spec.rb