logstash-integration-jdbc 5.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +8 -0
  3. data/CONTRIBUTORS +22 -0
  4. data/Gemfile +11 -0
  5. data/LICENSE +13 -0
  6. data/NOTICE.TXT +5 -0
  7. data/README.md +105 -0
  8. data/docs/filter-jdbc_static.asciidoc +606 -0
  9. data/docs/filter-jdbc_streaming.asciidoc +317 -0
  10. data/docs/index.asciidoc +32 -0
  11. data/docs/input-jdbc.asciidoc +573 -0
  12. data/lib/logstash/filters/jdbc/basic_database.rb +125 -0
  13. data/lib/logstash/filters/jdbc/column.rb +39 -0
  14. data/lib/logstash/filters/jdbc/db_object.rb +101 -0
  15. data/lib/logstash/filters/jdbc/loader.rb +119 -0
  16. data/lib/logstash/filters/jdbc/loader_schedule.rb +64 -0
  17. data/lib/logstash/filters/jdbc/lookup.rb +253 -0
  18. data/lib/logstash/filters/jdbc/lookup_processor.rb +100 -0
  19. data/lib/logstash/filters/jdbc/lookup_result.rb +40 -0
  20. data/lib/logstash/filters/jdbc/read_only_database.rb +57 -0
  21. data/lib/logstash/filters/jdbc/read_write_database.rb +108 -0
  22. data/lib/logstash/filters/jdbc/repeating_load_runner.rb +13 -0
  23. data/lib/logstash/filters/jdbc/single_load_runner.rb +46 -0
  24. data/lib/logstash/filters/jdbc/validatable.rb +46 -0
  25. data/lib/logstash/filters/jdbc_static.rb +240 -0
  26. data/lib/logstash/filters/jdbc_streaming.rb +196 -0
  27. data/lib/logstash/inputs/jdbc.rb +341 -0
  28. data/lib/logstash/inputs/tzinfo_jruby_patch.rb +57 -0
  29. data/lib/logstash/plugin_mixins/jdbc/checked_count_logger.rb +43 -0
  30. data/lib/logstash/plugin_mixins/jdbc/jdbc.rb +298 -0
  31. data/lib/logstash/plugin_mixins/jdbc/statement_handler.rb +129 -0
  32. data/lib/logstash/plugin_mixins/jdbc/value_tracking.rb +140 -0
  33. data/lib/logstash/plugin_mixins/jdbc_streaming/cache_payload.rb +28 -0
  34. data/lib/logstash/plugin_mixins/jdbc_streaming/parameter_handler.rb +64 -0
  35. data/lib/logstash/plugin_mixins/jdbc_streaming/statement_handler.rb +143 -0
  36. data/lib/logstash/plugin_mixins/jdbc_streaming.rb +100 -0
  37. data/lib/logstash/plugin_mixins/statement_handler.rb +0 -0
  38. data/lib/logstash-integration-jdbc_jars.rb +5 -0
  39. data/logstash-integration-jdbc.gemspec +44 -0
  40. data/spec/filters/env_helper.rb +10 -0
  41. data/spec/filters/integration/jdbc_static_spec.rb +154 -0
  42. data/spec/filters/integration/jdbcstreaming_spec.rb +173 -0
  43. data/spec/filters/jdbc/column_spec.rb +70 -0
  44. data/spec/filters/jdbc/db_object_spec.rb +81 -0
  45. data/spec/filters/jdbc/loader_spec.rb +77 -0
  46. data/spec/filters/jdbc/lookup_processor_spec.rb +132 -0
  47. data/spec/filters/jdbc/lookup_spec.rb +253 -0
  48. data/spec/filters/jdbc/read_only_database_spec.rb +67 -0
  49. data/spec/filters/jdbc/read_write_database_spec.rb +90 -0
  50. data/spec/filters/jdbc/repeating_load_runner_spec.rb +24 -0
  51. data/spec/filters/jdbc/single_load_runner_spec.rb +16 -0
  52. data/spec/filters/jdbc_static_file_local_spec.rb +83 -0
  53. data/spec/filters/jdbc_static_spec.rb +162 -0
  54. data/spec/filters/jdbc_streaming_spec.rb +350 -0
  55. data/spec/filters/remote_server_helper.rb +24 -0
  56. data/spec/filters/shared_helpers.rb +34 -0
  57. data/spec/helpers/WHY-THIS-JAR.txt +4 -0
  58. data/spec/helpers/derbyrun.jar +0 -0
  59. data/spec/inputs/integration/integ_spec.rb +78 -0
  60. data/spec/inputs/jdbc_spec.rb +1431 -0
  61. data/vendor/jar-dependencies/org/apache/derby/derby/10.14.1.0/derby-10.14.1.0.jar +0 -0
  62. data/vendor/jar-dependencies/org/apache/derby/derbyclient/10.14.1.0/derbyclient-10.14.1.0.jar +0 -0
  63. metadata +319 -0
@@ -0,0 +1,606 @@
1
+ :plugin: jdbc_static
2
+ :type: filter
3
+
4
+ ///////////////////////////////////////////
5
+ START - GENERATED VARIABLES, DO NOT EDIT!
6
+ ///////////////////////////////////////////
7
+ :version: %VERSION%
8
+ :release_date: %RELEASE_DATE%
9
+ :changelog_url: %CHANGELOG_URL%
10
+ :include_path: ../../../../logstash/docs/include
11
+ ///////////////////////////////////////////
12
+ END - GENERATED VARIABLES, DO NOT EDIT!
13
+ ///////////////////////////////////////////
14
+
15
+ [id="plugins-{type}s-{plugin}"]
16
+
17
+ === Jdbc_static filter plugin
18
+
19
+ include::{include_path}/plugin_header.asciidoc[]
20
+
21
+ ==== Description
22
+
23
+ This filter enriches events with data pre-loaded from a remote database.
24
+
25
+ This filter is best suited for enriching events with reference data that is
26
+ static or does not change very often, such as environments, users, and products.
27
+
28
+ This filter works by fetching data from a remote database, caching it in a
29
+ local, in-memory https://db.apache.org/derby/manuals/#docs_10.14[Apache Derby]
30
+ database, and using lookups to enrich events with data cached in the local
31
+ database. You can set up the filter to load the remote data once (for static
32
+ data), or you can schedule remote loading to run periodically (for data that
33
+ needs to be refreshed).
34
+
35
+ To define the filter, you specify three main sections: local_db_objects, loaders,
36
+ and lookups.
37
+
38
+ *local_db_objects*::
39
+
40
+ Define the columns, types, and indexes used to build the local database
41
+ structure. The column names and types should match the external database.
42
+ Define as many of these objects as needed to build the local database
43
+ structure.
44
+
45
+ *loaders*::
46
+
47
+ Query the external database to fetch the dataset that will be cached locally.
48
+ Define as many loaders as needed to fetch the remote data. Each
49
+ loader should fill a table defined by `local_db_objects`. Make sure
50
+ the column names and datatypes in the loader SQL statement match the
51
+ columns defined under `local_db_objects`. Each loader has an independent remote
52
+ database connection.
53
+
54
+ *lookups*::
55
+
56
+ Perform lookup queries on the local database to enrich the events.
57
+ Define as many lookups as needed to enrich the event from all
58
+ lookup tables in one pass. Ideally the SQL statement should only
59
+ return one row. Any rows are converted to Hash objects and are
60
+ stored in a target field that is an Array.
61
+ +
62
+ The following example config fetches data from a remote database, caches it in a
63
+ local database, and uses lookups to enrich events with data cached in the local
64
+ database.
65
+ +
66
+ ["source","json",subs="callouts"]
67
+ -----
68
+ filter {
69
+ jdbc_static {
70
+ loaders => [ <1>
71
+ {
72
+ id => "remote-servers"
73
+ query => "select ip, descr from ref.local_ips order by ip"
74
+ local_table => "servers"
75
+ },
76
+ {
77
+ id => "remote-users"
78
+ query => "select firstname, lastname, userid from ref.local_users order by userid"
79
+ local_table => "users"
80
+ }
81
+ ]
82
+ local_db_objects => [ <2>
83
+ {
84
+ name => "servers"
85
+ index_columns => ["ip"]
86
+ columns => [
87
+ ["ip", "varchar(15)"],
88
+ ["descr", "varchar(255)"]
89
+ ]
90
+ },
91
+ {
92
+ name => "users"
93
+ index_columns => ["userid"]
94
+ columns => [
95
+ ["firstname", "varchar(255)"],
96
+ ["lastname", "varchar(255)"],
97
+ ["userid", "int"]
98
+ ]
99
+ }
100
+ ]
101
+ local_lookups => [ <3>
102
+ {
103
+ id => "local-servers"
104
+ query => "SELECT descr as description FROM servers WHERE ip = :ip"
105
+ parameters => {ip => "[from_ip]"}
106
+ target => "server"
107
+ },
108
+ {
109
+ id => "local-users"
110
+ query => "SELECT firstname, lastname FROM users WHERE userid = ? AND country = ?"
111
+ prepared_parameters => ["[loggedin_userid]", "[user_nation]"] <4>
112
+ target => "user" <5>
113
+ }
114
+ ]
115
+ # using add_field here to add & rename values to the event root
116
+ add_field => { server_name => "%{[server][0][description]}" } <6>
117
+ add_field => { user_firstname => "%{[user][0][firstname]}" }
118
+ add_field => { user_lastname => "%{[user][0][lastname]}" }
119
+ remove_field => ["server", "user"]
120
+ staging_directory => "/tmp/logstash/jdbc_static/import_data"
121
+ loader_schedule => "* */2 * * *" # run loaders every 2 hours
122
+ jdbc_user => "logstash"
123
+ jdbc_password => "example"
124
+ jdbc_driver_class => "org.postgresql.Driver"
125
+ jdbc_driver_library => "/tmp/logstash/vendor/postgresql-42.1.4.jar"
126
+ jdbc_connection_string => "jdbc:postgresql://remotedb:5432/ls_test_2"
127
+ }
128
+ }
129
+ -----
130
+ <1> Queries an external database to fetch the dataset that will be cached
131
+ locally.
132
+ <2> Defines the columns, types, and indexes used to build the local database
133
+ structure. The column names and types should match the external database.
134
+ The order of table definitions is significant and should match that of the loader queries.
135
+ See <<plugins-{type}s-{plugin}-object_order>>.
136
+ <3> Performs lookup queries on the local database to enrich the events.
137
+ <4> Local lookup queries can also use prepared statements where the parameters
138
+ follow the positional ordering.
139
+ <5> Specifies the event field that will store the looked-up data. If the lookup
140
+ returns multiple columns, the data is stored as a JSON object within the field.
141
+ <6> Takes data from the JSON object and stores it in top-level event fields for
142
+ easier analysis in Kibana.
143
+
144
+ Here's a full example:
145
+
146
+ [source,json]
147
+ -----
148
+ input {
149
+ generator {
150
+ lines => [
151
+ '{"from_ip": "10.2.3.20", "app": "foobar", "amount": 32.95}',
152
+ '{"from_ip": "10.2.3.30", "app": "barfoo", "amount": 82.95}',
153
+ '{"from_ip": "10.2.3.40", "app": "bazfoo", "amount": 22.95}'
154
+ ]
155
+ count => 200
156
+ }
157
+ }
158
+
159
+ filter {
160
+ json {
161
+ source => "message"
162
+ }
163
+
164
+ jdbc_static {
165
+ loaders => [
166
+ {
167
+ id => "servers"
168
+ query => "select ip, descr from ref.local_ips order by ip"
169
+ local_table => "servers"
170
+ }
171
+ ]
172
+ local_db_objects => [
173
+ {
174
+ name => "servers"
175
+ index_columns => ["ip"]
176
+ columns => [
177
+ ["ip", "varchar(15)"],
178
+ ["descr", "varchar(255)"]
179
+ ]
180
+ }
181
+ ]
182
+ local_lookups => [
183
+ {
184
+ query => "select descr as description from servers WHERE ip = :ip"
185
+ parameters => {ip => "[from_ip]"}
186
+ target => "server"
187
+ }
188
+ ]
189
+ staging_directory => "/tmp/logstash/jdbc_static/import_data"
190
+ loader_schedule => "*/30 * * * *"
191
+ jdbc_user => "logstash"
192
+ jdbc_password => "logstash??"
193
+ jdbc_driver_class => "org.postgresql.Driver"
194
+ jdbc_driver_library => "/Users/guy/tmp/logstash-6.0.0/vendor/postgresql-42.1.4.jar"
195
+ jdbc_connection_string => "jdbc:postgresql://localhost:5432/ls_test_2"
196
+ }
197
+ }
198
+
199
+ output {
200
+ stdout {
201
+ codec => rubydebug {metadata => true}
202
+ }
203
+ }
204
+ -----
205
+
206
+ Assuming the loader fetches the following data from a Postgres database:
207
+
208
+ [source,shell]
209
+ select * from ref.local_ips order by ip;
210
+ ip | descr
211
+ -----------+-----------------------
212
+ 10.2.3.10 | Authentication Server
213
+ 10.2.3.20 | Payments Server
214
+ 10.2.3.30 | Events Server
215
+ 10.2.3.40 | Payroll Server
216
+ 10.2.3.50 | Uploads Server
217
+
218
+
219
+ The events are enriched with a description of the server based on the value of
220
+ the IP:
221
+
222
+ [source,shell]
223
+ {
224
+ "app" => "bazfoo",
225
+ "sequence" => 0,
226
+ "server" => [
227
+ [0] {
228
+ "description" => "Payroll Server"
229
+ }
230
+ ],
231
+ "amount" => 22.95,
232
+ "@timestamp" => 2017-11-30T18:08:15.694Z,
233
+ "@version" => "1",
234
+ "host" => "Elastics-MacBook-Pro.local",
235
+ "message" => "{\"from_ip\": \"10.2.3.40\", \"app\": \"bazfoo\", \"amount\": 22.95}",
236
+ "from_ip" => "10.2.3.40"
237
+ }
238
+
239
+
240
+ ==== Using this plugin with multiple pipelines
241
+
242
+ [IMPORTANT]
243
+ ===============================
244
+ Logstash uses a single, in-memory Apache Derby instance as the lookup database
245
+ engine for the entire JVM. Because each plugin instance uses a unique database
246
+ inside the shared Derby engine, there should be no conflicts with plugins
247
+ attempting to create and populate the same tables. This is true regardless of
248
+ whether the plugins are defined in a single pipeline, or multiple pipelines.
249
+ However, after setting up the filter, you should watch the lookup results and
250
+ view the logs to verify correct operation.
251
+ ===============================
252
+
253
+ [id="plugins-{type}s-{plugin}-object_order"]
254
+ ==== Loader column and local_db_object order dependency
255
+
256
+ [IMPORTANT]
257
+ ===============================
258
+ For loader performance reasons, the loading mechanism uses a CSV style file with an inbuilt
259
+ Derby file import procedure to add the remote data to the local db. The retrieved columns
260
+ are written to the CSV file as is and the file import procedure expects a 1 to 1 correspondence
261
+ to the order of the columns specified in the local_db_object settings. Please ensure that this
262
+ order is in place.
263
+ ===============================
264
+
265
+
266
+ [id="plugins-{type}s-{plugin}-options"]
267
+ ==== Jdbc_static Filter Configuration Options
268
+
269
+ This plugin supports the following configuration options plus the <<plugins-{type}s-{plugin}-common-options>> described later.
270
+
271
+ [cols="<,<,<",options="header",]
272
+ |=======================================================================
273
+ |Setting |Input type|Required
274
+ | <<plugins-{type}s-{plugin}-jdbc_connection_string>> |<<string,string>>|Yes
275
+ | <<plugins-{type}s-{plugin}-jdbc_driver_class>> |<<string,string>>|Yes
276
+ | <<plugins-{type}s-{plugin}-jdbc_driver_library>> |a valid filesystem path|No
277
+ | <<plugins-{type}s-{plugin}-jdbc_password>> |<<password,password>>|No
278
+ | <<plugins-{type}s-{plugin}-jdbc_user>> |<<string,string>>|No
279
+ | <<plugins-{type}s-{plugin}-tag_on_failure>> |<<array,array>>|No
280
+ | <<plugins-{type}s-{plugin}-tag_on_default_use>> |<<array,array>>|No
281
+ | <<plugins-{type}s-{plugin}-staging_directory>> |<<string,string>>|No
282
+ | <<plugins-{type}s-{plugin}-loader_schedule>>|<<string,string>>|No
283
+ | <<plugins-{type}s-{plugin}-loaders>>|<<array,array>>|No
284
+ | <<plugins-{type}s-{plugin}-local_db_objects>>|<<array,array>>|No
285
+ | <<plugins-{type}s-{plugin}-local_lookups>>|<<array,array>>|No
286
+ |=======================================================================
287
+
288
+ Also see <<plugins-{type}s-{plugin}-common-options>> for a list of options supported by all
289
+ filter plugins.
290
+
291
+ &nbsp;
292
+
293
+ [id="plugins-{type}s-{plugin}-jdbc_connection_string"]
294
+ ===== `jdbc_connection_string`
295
+
296
+ * This is a required setting.
297
+ * Value type is <<string,string>>
298
+ * There is no default value for this setting.
299
+
300
+ JDBC connection string.
301
+
302
+ [id="plugins-{type}s-{plugin}-jdbc_driver_class"]
303
+ ===== `jdbc_driver_class`
304
+
305
+ * This is a required setting.
306
+ * Value type is <<string,string>>
307
+ * There is no default value for this setting.
308
+
309
+ JDBC driver class to load, for example, "org.apache.derby.jdbc.ClientDriver".
310
+
311
+ NOTE: According to https://github.com/logstash-plugins/logstash-input-jdbc/issues/43[Issue 43],
312
+ if you are using the Oracle JDBC driver (ojdbc6.jar), the correct
313
+ `jdbc_driver_class` is `"Java::oracle.jdbc.driver.OracleDriver"`.
314
+
315
+ [id="plugins-{type}s-{plugin}-jdbc_driver_library"]
316
+ ===== `jdbc_driver_library`
317
+
318
+ * Value type is <<string,string>>
319
+ * There is no default value for this setting.
320
+
321
+ JDBC driver library path to third-party driver library. Use comma separated paths
322
+ in one string if you need multiple libraries.
323
+
324
+ If the driver class is not provided, the plugin looks for it in the Logstash
325
+ Java classpath.
326
+
327
+ [id="plugins-{type}s-{plugin}-jdbc_password"]
328
+ ===== `jdbc_password`
329
+
330
+ * Value type is <<password,password>>
331
+ * There is no default value for this setting.
332
+
333
+ JDBC password.
334
+
335
+ [id="plugins-{type}s-{plugin}-jdbc_user"]
336
+ ===== `jdbc_user`
337
+
338
+ * This is a required setting.
339
+ * Value type is <<string,string>>
340
+ * There is no default value for this setting.
341
+
342
+ JDBC user.
343
+
344
+ [id="plugins-{type}s-{plugin}-tag_on_default_use"]
345
+ ===== `tag_on_default_use`
346
+
347
+ * Value type is <<array,array>>
348
+ * Default value is `["_jdbcstaticdefaultsused"]`
349
+
350
+ Append values to the `tags` field if no record was found and default values were used.
351
+
352
+ [id="plugins-{type}s-{plugin}-tag_on_failure"]
353
+ ===== `tag_on_failure`
354
+
355
+ * Value type is <<array,array>>
356
+ * Default value is `["_jdbcstaticfailure"]`
357
+
358
+ Append values to the `tags` field if a SQL error occurred.
359
+
360
+ [id="plugins-{type}s-{plugin}-staging_directory"]
361
+ ===== `staging_directory`
362
+
363
+ * Value type is <<string,string>>
364
+ * Default value is derived from the Ruby temp directory + plugin_name + "import_data"
365
+ * e.g. `"/tmp/logstash/jdbc_static/import_data"`
366
+
367
+ The directory used stage the data for bulk loading, there should be sufficient
368
+ disk space to handle the data you wish to use to enrich events.
369
+ Previous versions of this plugin did not handle loading datasets of more than
370
+ several thousand rows well due to an open bug in Apache Derby. This setting
371
+ introduces an alternative way of loading large recordsets. As each row is
372
+ received it is spooled to file and then that file is imported using a
373
+ system 'import table' system call.
374
+
375
+ Append values to the `tags` field if a SQL error occurred.
376
+
377
+ [id="plugins-{type}s-{plugin}-loader_schedule"]
378
+ ===== `loader_schedule`
379
+
380
+ * Value type is <<string,string>>
381
+ * There is no default value for this setting.
382
+
383
+ You can schedule remote loading to run periodically according to a
384
+ specific schedule. This scheduling syntax is powered by
385
+ https://github.com/jmettraux/rufus-scheduler[rufus-scheduler]. The
386
+ syntax is cron-like with some extensions specific to Rufus
387
+ (for example, timezone support). For more about this syntax, see
388
+ https://github.com/jmettraux/rufus-scheduler#parsing-cronlines-and-time-strings[parsing cronlines and time strings].
389
+
390
+ Examples:
391
+
392
+ |==========================================================
393
+ | `*/30 * * * *` | will execute on the 0th and 30th minute of every hour every day.
394
+ | `* 5 * 1-3 *` | will execute every minute of 5am every day of January through March.
395
+ | `0 * * * *` | will execute on the 0th minute of every hour every day.
396
+ | `0 6 * * * America/Chicago` | will execute at 6:00am (UTC/GMT -5) every day.
397
+ |==========================================================
398
+
399
+ Debugging using the Logstash interactive shell:
400
+ [source,shell]
401
+ bin/logstash -i irb
402
+ irb(main):001:0> require 'rufus-scheduler'
403
+ => true
404
+ irb(main):002:0> Rufus::Scheduler.parse('*/10 * * * *')
405
+ => #<Rufus::Scheduler::CronLine:0x230f8709 @timezone=nil, @weekdays=nil, @days=nil, @seconds=[0], @minutes=[0, 10, 20, 30, 40, 50], @hours=nil, @months=nil, @monthdays=nil, @original="*/10 * * * *">
406
+ irb(main):003:0> exit
407
+
408
+
409
+ The object returned by the above call, an instance of `Rufus::Scheduler::CronLine` shows the seconds, minutes etc. of execution.
410
+
411
+ [id="plugins-{type}s-{plugin}-loaders"]
412
+ ===== `loaders`
413
+
414
+ * Value type is <<array,array>>
415
+ * Default value is `[]`
416
+
417
+ The array should contain one or more Hashes. Each Hash is validated
418
+ according to the table below.
419
+
420
+ [cols="<,<,<",options="header",]
421
+ |=======================================================================
422
+ |Setting |Input type|Required
423
+ | id|string|No
424
+ | table|string|Yes
425
+ | query|string|Yes
426
+ | max_rows|number|No
427
+ | jdbc_connection_string|string|No
428
+ | jdbc_driver_class|string|No
429
+ | jdbc_driver_library|a valid filesystem path|No
430
+ | jdbc_password|password|No
431
+ | jdbc_user|string|No
432
+ |=======================================================================
433
+
434
+ *Loader Field Descriptions:*
435
+
436
+ id::
437
+ An optional identifier. This is used to identify the loader that is
438
+ generating error messages and log lines.
439
+
440
+ table::
441
+ The destination table in the local lookup database that the loader will fill.
442
+
443
+ query::
444
+ The SQL statement that is executed to fetch the remote records. Use SQL
445
+ aliases and casts to ensure that the record's columns and datatype match the
446
+ table structure in the local database as defined in the `local_db_objects`.
447
+
448
+ max_rows::
449
+ The default for this setting is 1 million. Because the lookup database is
450
+ in-memory, it will take up JVM heap space. If the query returns many millions
451
+ of rows, you should increase the JVM memory given to Logstash or limit the
452
+ number of rows returned, perhaps to those most frequently found in the
453
+ event data.
454
+
455
+ jdbc_connection_string::
456
+ If not set in a loader, this setting defaults to the plugin-level
457
+ `jdbc_connection_string` setting.
458
+
459
+ jdbc_driver_class::
460
+ If not set in a loader, this setting defaults to the plugin-level
461
+ `jdbc_driver_class` setting.
462
+
463
+ jdbc_driver_library::
464
+ If not set in a loader, this setting defaults to the plugin-level
465
+ `jdbc_driver_library` setting.
466
+
467
+ jdbc_password::
468
+ If not set in a loader, this setting defaults to the plugin-level
469
+ `jdbc_password` setting.
470
+
471
+ jdbc_user::
472
+ If not set in a loader, this setting defaults to the plugin-level
473
+ `jdbc_user` setting.
474
+
475
+ [id="plugins-{type}s-{plugin}-local_db_objects"]
476
+ ===== `local_db_objects`
477
+
478
+ * Value type is <<array,array>>
479
+ * Default value is `[]`
480
+
481
+ The array should contain one or more Hashes. Each Hash represents a table
482
+ schema for the local lookups database. Each Hash is validated
483
+ according to the table below.
484
+
485
+ [cols="<,<,<",options="header",]
486
+ |=======================================================================
487
+ |Setting |Input type|Required
488
+ | name|string|Yes
489
+ | columns|array|Yes
490
+ | index_columns|number|No
491
+ | preserve_existing|boolean|No
492
+ |=======================================================================
493
+
494
+ *Local_db_objects Field Descriptions:*
495
+
496
+ name::
497
+ The name of the table to be created in the database.
498
+
499
+ columns::
500
+ An array of column specifications. Each column specification is an array
501
+ of exactly two elements, for example `["ip", "varchar(15)"]`. The first
502
+ element is the column name string. The second element is a string that
503
+ is an
504
+ https://db.apache.org/derby/docs/10.14/ref/crefsqlj31068.html[Apache Derby SQL type].
505
+ The string content is checked when the local lookup tables are built, not when
506
+ the settings are validated. Therefore, any misspelled SQL type strings result in
507
+ errors.
508
+
509
+ index_columns::
510
+ An array of strings. Each string must be defined in the `columns` setting. The
511
+ index name will be generated internally. Unique or sorted indexes are not
512
+ supported.
513
+
514
+ preserve_existing::
515
+ This setting, when `true`, checks whether the table already exists in the local
516
+ lookup database. If you have multiple pipelines running in the same
517
+ instance of Logstash, and more than one pipeline is using this plugin, then you
518
+ must read the important multiple pipeline notice at the top of the page.
519
+
520
+ [id="plugins-{type}s-{plugin}-local_lookups"]
521
+ ===== `local_lookups`
522
+
523
+ * Value type is <<array,array>>
524
+ * Default value is `[]`
525
+
526
+ The array should contain one or more Hashes. Each Hash represents a lookup
527
+ enrichment. Each Hash is validated according to the table below.
528
+
529
+ [cols="<,<,<",options="header",]
530
+ |=======================================================================
531
+ |Setting |Input type|Required
532
+ | id|string|No
533
+ | query|string|Yes
534
+ | parameters|hash|Yes
535
+ | target|string|No
536
+ | default_hash|hash|No
537
+ | tag_on_failure|string|No
538
+ | tag_on_default_use|string|No
539
+ |=======================================================================
540
+
541
+ *Local_lookups Field Descriptions:*
542
+
543
+ id::
544
+ An optional identifier. This is used to identify the lookup that is
545
+ generating error messages and log lines. If you omit this setting then a
546
+ default id is used instead.
547
+
548
+ query::
549
+ A SQL SELECT statement that is executed to achieve the lookup. To use
550
+ parameters, use named parameter syntax, for example
551
+ `"SELECT * FROM MYTABLE WHERE ID = :id"`. Alternatively, the `?` sign
552
+ can be used as a prepared statement parameter, in which case
553
+ the `prepared_parameters` array is used to populate the values
554
+
555
+ parameters::
556
+ A key/value Hash or dictionary. The key (LHS) is the text that is
557
+ substituted for in the SQL statement
558
+ `SELECT * FROM sensors WHERE reference = :p1`. The value (RHS)
559
+ is the field name in your event. The plugin reads the value from
560
+ this key out of the event and substitutes that value into the
561
+ statement, for example, `parameters => { "p1" => "ref" }`. Quoting is
562
+ automatic - you do not need to put quotes in the statement.
563
+ Only use the field interpolation syntax on the RHS if you need to
564
+ add a prefix/suffix or join two event field values together to build
565
+ the substitution value. For example, imagine an IOT message that has
566
+ an id and a location, and you have a table of sensors that have a
567
+ column of `id-loc_id`. In this case your parameter hash would look
568
+ like this: `parameters => { "p1" => "%{[id]}-%{[loc_id]}" }`.
569
+
570
+ prepared_parameters::
571
+ An Array, where the position is related to the position of the `?` in
572
+ the query syntax. The values of array follow the same semantic of `parameters`.
573
+ If `prepared_parameters` is valorized the filter is forced to use JDBC's
574
+ prepared statement to query the local database.
575
+ Prepared statements provides two benefits: one on the performance side, because
576
+ avoid the DBMS to parse and compile the SQL expression for every call;
577
+ the other benefit is on the security side, using prepared statements
578
+ avoid SQL-injection attacks based on query string concatenation.
579
+
580
+ target::
581
+ An optional name for the field that will receive the looked-up data.
582
+ If you omit this setting then the `id` setting (or the default id) is
583
+ used. The looked-up data, an array of results converted to Hashes, is
584
+ never added to the root of the event. If you want to do this, you
585
+ should use the `add_field` setting. This means that
586
+ you are in full control of how the fields/values are put in the root
587
+ of the event, for example,
588
+ `add_field => { user_firstname => "%{[user][0][firstname]}" }` -
589
+ where `[user]` is the target field, `[0]` is the first result in the
590
+ array, and `[firstname]` is the key in the result hash.
591
+
592
+ default_hash::
593
+ An optional hash that will be put in the target field array when the
594
+ lookup returns no results. Use this setting if you need to ensure that later
595
+ references in other parts of the config actually refer to something.
596
+
597
+ tag_on_failure::
598
+ An optional string that overrides the plugin-level setting. This is
599
+ useful when defining multiple lookups.
600
+
601
+ tag_on_default_use::
602
+ An optional string that overrides the plugin-level setting. This is
603
+ useful when defining multiple lookups.
604
+
605
+ [id="plugins-{type}s-{plugin}-common-options"]
606
+ include::{include_path}/{type}.asciidoc[]