logstash-output-charrington 0.3.24 → 0.3.25

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.
@@ -1,24 +1,25 @@
1
- require File.join(File.dirname(__FILE__), "create_postgres_table")
2
- require File.join(File.dirname(__FILE__), "create_redshift_table")
3
- require File.join(File.dirname(__FILE__), "alter_postgres_table")
4
- require File.join(File.dirname(__FILE__), "alter_redshift_table")
5
- require File.join(File.dirname(__FILE__), "service")
1
+ # frozen_string_literal: true
2
+
3
+ require File.join(File.dirname(__FILE__), 'create_postgres_table')
4
+ require File.join(File.dirname(__FILE__), 'create_redshift_table')
5
+ require File.join(File.dirname(__FILE__), 'alter_postgres_table')
6
+ require File.join(File.dirname(__FILE__), 'alter_redshift_table')
7
+ require File.join(File.dirname(__FILE__), 'service')
6
8
  require 'time'
7
9
 
8
10
  module Charrington
9
- class Insert
10
- # This service assumes that the data is already clean and in a flattened hash format.
11
- # The Transform service should be called before calling this.
12
-
11
+ # This service assumes that the data is already clean and in a flattened hash format.
12
+ # The Transform service should be called before calling this.
13
+ class Insert # rubocop:disable Metrics/ClassLength
13
14
  include Service
14
15
  include LogStash::Util::Loggable
15
16
  attr_accessor :event, :should_retry
16
- attr_reader :connection, :schema, :table_name, :columns, :driver, :opts, :transformer, :tracks
17
- attr_reader :event_as_json_keyword, :enable_event_as_json_keyword
18
- # TODO create a current_table_columns (alter_postgres_table.rb) query on the tracks table to get the current columns
19
- @@redshift_tracks_columns = %w(id action app_name received_at uuid uuid_ts anonymous_id context_ip context_library_name context_library_version context_page_path context_page_referrer context_page_title context_page_url context_user_agent event event_text original_timestamp sent_at timestamp user_id user_uid context_campaign_medium context_campaign_name context_page_search context_campaign_source segment_dedupe_id context_campaign_content)
20
- @@postgres_tracks_columns = %w(anonymous_user app_name event published_at session_ip session_library_name session_library_version session_page_path session_page_referrer session_page_search session_page_title session_page_url session_user_agent user_id user_uid)
21
- @@timestamp_columns = %w(published_at sent_at original_timestamp received_at timestamp)
17
+ attr_reader :connection, :schema, :table_name, :columns, :driver, :opts, :transformer, :tracks, :event_as_json_keyword, :enable_event_as_json_keyword
18
+
19
+ # TODO: create a current_table_columns (alter_postgres_table.rb) query on the tracks table to get the current columns
20
+ REDSHIFT_TRACKS_COLUMNS = %w[id action app_name received_at uuid uuid_ts anonymous_id context_ip context_library_name context_library_version context_page_path context_page_referrer context_page_title context_page_url context_user_agent event event_text original_timestamp sent_at timestamp user_id user_uid context_campaign_medium context_campaign_name context_page_search context_campaign_source segment_dedupe_id context_campaign_content].freeze
21
+ POSTGRES_TRACKS_COLUMNS = %w[anonymous_user app_name event published_at session_ip session_library_name session_library_version session_page_path session_page_referrer session_page_search session_page_title session_page_url session_user_agent user_id user_uid].freeze
22
+ TIMESTAMP_COLUMNS = %w[published_at sent_at original_timestamp received_at timestamp].freeze
22
23
 
23
24
  Error = Class.new(StandardError)
24
25
  EventNil = Class.new(Error)
@@ -26,19 +27,20 @@ module Charrington
26
27
  InsertFailed = Class.new(Error)
27
28
 
28
29
  def initialize(connection, event, opts = {})
29
- raise EventNil, "Table name is nil" if event.nil?
30
+ raise EventNil, 'Table name is nil' if event.nil?
31
+
30
32
  @transformer = opts[:transformer]
31
33
  @event = event.to_hash
32
34
  @tracks = create_tracks(@event)
33
- event_name = event["event"].to_s.strip
34
- raise TableNameNil, "Table name is nil" if event_name.empty?
35
+ event_name = event['event'].to_s.strip
36
+ raise TableNameNil, 'Table name is nil' if event_name.empty?
35
37
 
36
38
  @connection = connection
37
39
  @schema = opts[:schema].empty? ? '' : "#{opts[:schema]}."
38
40
 
39
41
  @table_name = underscore(event_name)
40
42
 
41
- @columns = event.keys.map{|x| underscore(x)}
43
+ @columns = event.keys.map { |x| underscore(x) }
42
44
  @should_retry = false
43
45
  @enable_event_as_json_keyword = opts[:enable_event_as_json_keyword]
44
46
  @event_as_json_keyword = opts[:event_as_json_keyword]
@@ -47,35 +49,34 @@ module Charrington
47
49
  end
48
50
 
49
51
  def call
50
- self.logger.info "Attempting insert into table name: #{table_name}"
52
+ logger.info "Attempting insert into table name: #{table_name}"
51
53
  insert_sql = insert_event_statement
52
54
  insert_stmt = connection.prepareStatement(insert_sql)
53
- self.logger.info "Insert statement passed into prepareStatement is: #{insert_stmt}"
55
+ logger.info "Insert statement passed into prepareStatement is: #{insert_stmt}"
54
56
  insert_stmt = add_statement_event_params(insert_stmt, event)
55
- self.logger.info "Insert statement to be run is: #{insert_stmt.toString}"
57
+ logger.info "Insert statement to be run is: #{insert_stmt.toString}"
56
58
  insert_stmt.execute
57
59
 
58
- self.logger.info "Attempting insert into tracks table"
60
+ logger.info 'Attempting insert into tracks table'
59
61
  do_tracks_insert
60
62
 
61
63
  should_retry
62
64
  rescue Java::JavaSql::SQLException => e
63
- case e.getSQLState()
64
- when "42P01"
65
- self.logger.info "Received Java::JavaSql::SQLException with error sql state of 42P01, moving to create table"
65
+ case e.getSQLState
66
+ when '42P01'
67
+ logger.info 'Received Java::JavaSql::SQLException with error sql state of 42P01, moving to create table'
66
68
  should_retry = create_table
67
- when "42703"
68
- self.logger.info "Received Java::JavaSql::SQLException with error sql state of 42703, moving to alter table"
69
+ when '42703'
70
+ logger.info 'Received Java::JavaSql::SQLException with error sql state of 42703, moving to alter table'
69
71
  should_retry = alter_table
70
72
  else
71
73
  raise InsertFailed, "SQLException (Charrington:Insert) #{e.message} #{insert_sql}"
72
74
  end
73
75
  should_retry
74
-
75
- rescue => e
76
+ rescue StandardError => e
76
77
  raise InsertFailed, "SQLException (Charrington:Insert) #{e.message} #{insert_sql}"
77
78
  ensure
78
- insert_stmt.close unless insert_stmt.nil?
79
+ insert_stmt&.close
79
80
  cleanup
80
81
  end
81
82
 
@@ -83,48 +84,48 @@ module Charrington
83
84
  tracks_sql = insert_tracks_statement
84
85
  tracks_stmt = connection.prepareStatement(tracks_sql)
85
86
  tracks_stmt = add_statement_event_params(tracks_stmt, tracks)
86
- self.logger.info "Insert tracks statment to be run: #{tracks_stmt.toString}"
87
+ logger.info "Insert tracks statment to be run: #{tracks_stmt.toString}"
87
88
  tracks_stmt.execute
88
89
  rescue Java::JavaSql::SQLException => e
89
- self.logger.error("SQLException (Charrington:Insert) Insert tracks entry failed. #{e.message} #{tracks_sql}")
90
+ logger.error("SQLException (Charrington:Insert) Insert tracks entry failed. #{e.message} #{tracks_sql}")
90
91
  ensure
91
- tracks_stmt.close unless tracks_stmt.nil?
92
+ tracks_stmt&.close
92
93
  end
93
94
 
94
95
  private
95
96
 
96
97
  def tracks_columns
97
- is_redshift_transform? ? @@redshift_tracks_columns : @@postgres_tracks_columns
98
+ redshift_transform? ? REDSHIFT_TRACKS_COLUMNS : POSTGRES_TRACKS_COLUMNS
98
99
  end
99
100
 
100
- def is_redshift?
101
+ def redshift?
101
102
  driver == 'redshift'
102
103
  end
103
104
 
104
- def is_postgres?
105
+ def postgres?
105
106
  driver == 'postgres'
106
107
  end
107
108
 
108
- def is_postgres_transform?
109
+ def postgres_transform?
109
110
  transformer == 'postgres'
110
111
  end
111
112
 
112
- def is_redshift_transform?
113
+ def redshift_transform?
113
114
  transformer == 'redshift'
114
115
  end
115
116
 
116
117
  def create_table
117
- if is_postgres?
118
+ if postgres?
118
119
  Charrington::CreatePostgresTable.call(connection, event, schema, table_name, columns, opts)
119
- elsif is_redshift?
120
+ elsif redshift?
120
121
  Charrington::CreateRedshiftTable.call(connection, event, schema, table_name, columns, opts)
121
122
  end
122
123
  end
123
124
 
124
125
  def alter_table
125
- if is_postgres?
126
+ if postgres?
126
127
  Charrington::AlterPostgresTable.call(connection, event, schema, table_name, columns)
127
- elsif is_redshift?
128
+ elsif redshift?
128
129
  Charrington::AlterRedshiftTable.call(connection, event, schema, table_name, columns)
129
130
  end
130
131
  end
@@ -137,7 +138,7 @@ module Charrington
137
138
  ### Set Variables
138
139
  def create_tracks(event)
139
140
  tracks = event.clone
140
- tracks.keys.each do |key|
141
+ tracks.each_key do |key|
141
142
  tracks.delete(key) unless tracks_columns.include?(key)
142
143
  end
143
144
  tracks
@@ -151,7 +152,6 @@ module Charrington
151
152
  @tracks_columns_text ||= arr_to_csv(tracks.keys)
152
153
  end
153
154
 
154
-
155
155
  def value_placeholders(columns)
156
156
  ('?' * columns.length).split('')
157
157
  end
@@ -168,19 +168,19 @@ module Charrington
168
168
  "INSERT INTO #{schema}tracks #{tracks_columns_text} VALUES #{placeholder_text(tracks.keys)}"
169
169
  end
170
170
 
171
- def add_statement_event_params(stmt, map)
171
+ def add_statement_event_params(stmt, map) # rubocop:disable Metrics/CyclomaticComplexity
172
172
  values = []
173
- map.keys.each_with_index do |key, idx|
173
+ map.keys.each_with_index do |key, idx| # rubocop:disable Metrics/BlockLength
174
174
  pos = idx + 1
175
175
  value = map[key]
176
176
  values << value
177
177
 
178
- if @@timestamp_columns.include?(key)
178
+ if TIMESTAMP_COLUMNS.include?(key)
179
179
  begin
180
180
  time = parse_date(value)
181
181
  stmt.setTimestamp(pos, time)
182
182
  next
183
- rescue java.text.ParseException => e
183
+ rescue java.text.ParseException
184
184
  time = parse_date(value, "yyyy-MM-dd'T'HH:mm:ss'Z'")
185
185
  stmt.setTimestamp(pos, time)
186
186
  next
@@ -203,7 +203,7 @@ module Charrington
203
203
  when Float
204
204
  stmt.setFloat(pos, value)
205
205
  when String
206
- stmt.setString(pos, value[0,254]) # truncate at 254 string characters
206
+ stmt.setString(pos, value[0, 254]) # truncate at 254 string characters
207
207
  when Array, Hash
208
208
  stmt.setString(pos, value.to_json)
209
209
  when true, false
@@ -223,7 +223,7 @@ module Charrington
223
223
  end
224
224
 
225
225
  def arr_to_csv(arr)
226
- '(' + arr.join(', ') + ')'
226
+ "(#{arr.join(', ')})"
227
227
  end
228
228
 
229
229
  def clearable(obj)
@@ -231,27 +231,27 @@ module Charrington
231
231
  end
232
232
 
233
233
  def underscore(str)
234
- str.
235
- gsub(/::/, '/').
236
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
237
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
238
- downcase.
239
- gsub(/[^a-z0-9]+/, "_").
240
- gsub(/\A_+/, "").
241
- gsub(/_+\z/, "")[0,64]
234
+ str
235
+ .gsub(/::/, '/')
236
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
237
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
238
+ .downcase
239
+ .gsub(/[^a-z0-9]+/, '_')
240
+ .gsub(/\A_+/, '')
241
+ .gsub(/_+\z/, '')[0, 64]
242
242
  end
243
243
 
244
244
  ### SQL
245
245
 
246
246
  def execute(connection, sql)
247
- statement = connection.prepareStatement( sql.gsub(/\s+/, " ").strip )
248
- statement.execute()
247
+ statement = connection.prepareStatement(sql.gsub(/\s+/, ' ').strip)
248
+ statement.execute
249
249
  rescue Java::OrgPostgresqlUtil::PSQLException => e
250
- self.logger.error "PSQLException: #{e.message}, with SQL: #{sql}"
250
+ logger.error "PSQLException: #{e.message}, with SQL: #{sql}"
251
251
  rescue Java::JavaSql::SQLException => e
252
- self.logger.error "Redshift SQLException: #{e.message}, with SQL: #{sql}"
252
+ logger.error "Redshift SQLException: #{e.message}, with SQL: #{sql}"
253
253
  ensure
254
- statement.close unless statement.nil?
254
+ statement&.close
255
255
  end
256
256
  end
257
257
  end
@@ -1,10 +1,11 @@
1
- require File.join(File.dirname(__FILE__), "service")
1
+ # frozen_string_literal: true
2
+
3
+ require File.join(File.dirname(__FILE__), 'service')
2
4
 
3
5
  module Charrington
6
+ # This service starts the process of attempting to insert a row.
7
+ # It handles retries where applicable.
4
8
  class Process
5
- # This service starts the process of attempting to insert a row.
6
- # It handles retries where applicable.
7
-
8
9
  include Service
9
10
  include LogStash::Util::Loggable
10
11
  attr_reader :event, :connection, :opts, :max_retries, :schema, :retry_max_interval, :driver, :transformer
@@ -14,8 +15,9 @@ module Charrington
14
15
  ProcessFailed = Class.new(Error)
15
16
  EventNil = Class.new(Error)
16
17
 
17
- def initialize(connection, event, opts={})
18
- raise EventNil, "Event is nil" if event.nil?
18
+ def initialize(connection, event, opts = {})
19
+ raise EventNil, 'Event is nil' if event.nil?
20
+
19
21
  @connection = connection
20
22
  @event = event.to_hash
21
23
  @opts = opts
@@ -31,18 +33,18 @@ module Charrington
31
33
  end
32
34
 
33
35
  def call
34
- while should_retry do
35
- transformed = case transformer
36
- when "redshift"
37
- self.logger.info "Found transformer of #{transformer} for driver of #{driver} with event of: #{event}"
38
- Charrington::TransformRedshift.call(event)
39
- else
40
- self.logger.info "Found transformer of #{transformer} for driver of #{driver} with event of: #{event}"
41
- Charrington::TransformPostgres.call(event)
42
- end
43
- self.logger.info "Transformed event into: #{transformed}"
36
+ while should_retry
37
+ logger.info "Found transformer of #{transformer} for driver of #{driver} with event of: #{event}"
38
+ transformed =
39
+ case transformer
40
+ when 'redshift'
41
+ Charrington::TransformRedshift.call(event)
42
+ else
43
+ Charrington::TransformPostgres.call(event)
44
+ end
45
+ logger.info "Transformed event into: #{transformed}"
44
46
  should_retry = Charrington::Insert.call(connection, transformed, opts)
45
- break if !should_retry
47
+ break unless should_retry
46
48
 
47
49
  @attempts += 1
48
50
  break if @attempts > max_retries
@@ -51,10 +53,10 @@ module Charrington
51
53
  # Double the interval for the next time through to achieve exponential backoff
52
54
  sleep_interval
53
55
  end
54
- rescue => e
56
+ rescue StandardError => e
55
57
  raise ProcessFailed, e.message
56
58
  ensure
57
- connection.close unless connection.nil?
59
+ connection&.close
58
60
  @event.clear if clearable(@event)
59
61
  end
60
62
 
@@ -63,7 +65,9 @@ module Charrington
63
65
  def sleep_interval
64
66
  sleep(retry_interval)
65
67
  doubled = retry_interval * 2
68
+ # rubocop:disable Lint/UselessAssignment
66
69
  retry_interval = doubled > retry_max_interval ? retry_max_interval : doubled
70
+ # rubocop:enable Lint/UselessAssignment
67
71
  end
68
72
 
69
73
  def clearable(obj)
@@ -1,9 +1,13 @@
1
1
  # frozen_string_literal: true
2
+
3
+ # Service mix in that provides a `call` helper method
2
4
  module Service
3
5
  def self.included(base)
4
6
  base.extend ClassMethods
5
7
  end
6
8
 
9
+ # Adds a `call` method that creates a new instance
10
+ # and delegates to the child's call method
7
11
  module ClassMethods
8
12
  def call(*args)
9
13
  new(*args).call
@@ -1,6 +1,9 @@
1
- require File.join(File.dirname(__FILE__), "service")
1
+ # frozen_string_literal: true
2
+
3
+ require File.join(File.dirname(__FILE__), 'service')
2
4
 
3
5
  module Charrington
6
+ # Inserts and modifies a Postgres database
4
7
  class TransformPostgres
5
8
  include Service
6
9
  attr_accessor :event
@@ -11,11 +14,12 @@ module Charrington
11
14
  TableNameNil = Class.new(Error)
12
15
  ColumnBlacklist = Class.new(Error)
13
16
 
14
- KEY_FILTER_BLACKLIST = ['host','path','jwt','sequence']
15
- KEY_RAISE_BLACKLIST = ['id', 'inserted_at']
17
+ KEY_FILTER_BLACKLIST = %w[host path jwt sequence].freeze
18
+ KEY_RAISE_BLACKLIST = %w[id inserted_at].freeze
16
19
 
17
20
  def initialize(event)
18
- raise EventNil, "Event is nil" if event.nil?
21
+ raise EventNil, 'Event is nil' if event.nil?
22
+
19
23
  event = event.to_hash
20
24
  @event = drop_keys(event)
21
25
  @top_level_keys = @event.keys
@@ -34,11 +38,11 @@ module Charrington
34
38
  def check_blacklist
35
39
  arr = []
36
40
  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?
41
+ raise ColumnBlacklist, "Event contains these blacklisted keys: #{arr.join(',')}" unless arr.empty?
38
42
  end
39
43
 
40
44
  def drop_keys(event)
41
- event.delete_if {|k, _v| k.start_with?("@") || KEY_FILTER_BLACKLIST.include?(k) }
45
+ event.delete_if { |k, _v| k.start_with?('@') || KEY_FILTER_BLACKLIST.include?(k) }
42
46
  end
43
47
 
44
48
  def flatten_hash(hash)
@@ -1,7 +1,10 @@
1
- require File.join(File.dirname(__FILE__), "service")
1
+ # frozen_string_literal: true
2
+
3
+ require File.join(File.dirname(__FILE__), 'service')
2
4
  require 'securerandom'
3
5
 
4
6
  module Charrington
7
+ # Inserts and modifies a Postgres/Redshift database
5
8
  class TransformRedshift
6
9
  include Service
7
10
  attr_accessor :event
@@ -12,11 +15,12 @@ module Charrington
12
15
  TableNameNil = Class.new(Error)
13
16
  ColumnBlacklist = Class.new(Error)
14
17
 
15
- KEY_FILTER_BLACKLIST = ['host','path','jwt','sequence']
16
- KEY_RAISE_BLACKLIST = ['inserted_at']
18
+ KEY_FILTER_BLACKLIST = %w[host path jwt sequence].freeze
19
+ KEY_RAISE_BLACKLIST = ['inserted_at'].freeze
17
20
 
18
21
  def initialize(event)
19
- raise EventNil, "Event is nil" if event.nil?
22
+ raise EventNil, 'Event is nil' if event.nil?
23
+
20
24
  event = event.to_hash
21
25
  @event = drop_keys(event)
22
26
  @top_level_keys = @event.keys
@@ -27,17 +31,17 @@ module Charrington
27
31
  handle_event_key(event)
28
32
  add_id_to_event(event)
29
33
 
30
- handle_key_transform(event, "anonymous_id", "anonymous_user")
31
- handle_key_transform(event, "sent_at", "published_at")
32
- handle_key_transform(event, "original_timestamp", "sent_at")
33
- handle_key_transform(event, "received_at", "sent_at")
34
- handle_key_transform(event, "timestamp", "sent_at")
34
+ handle_key_transform(event, 'anonymous_id', 'anonymous_user')
35
+ handle_key_transform(event, 'sent_at', 'published_at')
36
+ handle_key_transform(event, 'original_timestamp', 'sent_at')
37
+ handle_key_transform(event, 'received_at', 'sent_at')
38
+ handle_key_transform(event, 'timestamp', 'sent_at')
35
39
 
36
40
  handle_meta_section(event)
37
41
 
38
42
  transform_session_stuff(event)
39
43
 
40
- event.delete_if {|k, _v| ['session', 'meta', 'published_at', 'anonymous_user'].include?(k) }
44
+ event.delete_if { |k, _v| %w[session meta published_at anonymous_user].include?(k) }
41
45
 
42
46
  event
43
47
  end
@@ -45,65 +49,65 @@ module Charrington
45
49
  private
46
50
 
47
51
  def handle_key_transform(hash, key_that_should_be_there, key_to_take_value_from)
48
- unless hash.has_key?(key_that_should_be_there)
49
- hash[key_that_should_be_there] = hash[key_to_take_value_from] || ""
50
- else
52
+ if hash.key?(key_that_should_be_there)
51
53
  hash
54
+ else
55
+ hash[key_that_should_be_there] = hash[key_to_take_value_from] || ''
52
56
  end
53
57
  end
54
58
 
55
59
  def add_id_to_event(hash)
56
- hash["id"] = SecureRandom.hex(10)
60
+ hash['id'] = SecureRandom.hex(10)
57
61
  end
58
62
 
59
63
  def handle_event_key(hash)
60
- event_name = hash["event"] || ""
64
+ event_name = hash['event'] || ''
61
65
 
62
- hash["event_text"] = event_name
66
+ hash['event_text'] = event_name
63
67
 
64
- hash["event"] = underscore_event_name(event_name)
68
+ hash['event'] = underscore_event_name(event_name)
65
69
  end
66
70
 
67
71
  def underscore_event_name(event_name)
68
- event_name.
69
- gsub(/::/, '/').
70
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
71
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
72
- downcase.
73
- gsub(/[^a-z0-9]+/, "_").
74
- gsub(/\A_+/, "").
75
- gsub(/_+\z/, "")
72
+ event_name
73
+ .gsub(/::/, '/')
74
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
75
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
76
+ .downcase
77
+ .gsub(/[^a-z0-9]+/, '_')
78
+ .gsub(/\A_+/, '')
79
+ .gsub(/_+\z/, '')
76
80
  end
77
81
 
78
82
  def transform_session_stuff(hash)
79
- session_stuff = hash["session"] || {}
83
+ session_stuff = hash['session'] || {}
80
84
 
81
- session_stuff.each {|k, v|
82
- next unless k.kind_of?(String)
85
+ session_stuff.each do |k, v|
86
+ next unless k.is_a?(String)
83
87
 
84
88
  hash["context_#{k}"] = v
85
- }
89
+ end
86
90
  end
87
91
 
88
92
  def handle_meta_section(hash)
89
- meta_section = hash["meta"] || {}
93
+ meta_section = hash['meta'] || {}
90
94
 
91
- meta_section.each {|k, v|
92
- next unless k.kind_of?(String)
93
- next if [Array, Hash].map { |type| v.kind_of?(type) }.any?
95
+ meta_section.each do |k, v|
96
+ next unless k.is_a?(String)
97
+ next if [Array, Hash].map { |type| v.is_a?(type) }.any?
94
98
 
95
99
  hash[k] = v
96
- }
100
+ end
97
101
  end
98
102
 
99
103
  def check_blacklist
100
104
  arr = []
101
105
  KEY_RAISE_BLACKLIST.each { |k| arr << k if event.keys.include?(k) }
102
- raise ColumnBlacklist, "Event contains these blacklisted keys: #{arr.join(",")}" unless arr.empty?
106
+ raise ColumnBlacklist, "Event contains these blacklisted keys: #{arr.join(',')}" unless arr.empty?
103
107
  end
104
108
 
105
109
  def drop_keys(event)
106
- event.delete_if {|k, _v| k.start_with?("@") || KEY_FILTER_BLACKLIST.include?(k) }
110
+ event.delete_if { |k, _v| k.start_with?('@') || KEY_FILTER_BLACKLIST.include?(k) }
107
111
  end
108
112
 
109
113
  def flatten_hash(hash)