@@ -75,6 +75,7 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
75
75
76
76
require 'logstash/inputs/elasticsearch/paginated_search'
77
77
require 'logstash/inputs/elasticsearch/aggregation'
78
+ require 'logstash/inputs/elasticsearch/cursor_tracker'
78
79
79
80
include LogStash ::PluginMixins ::ECSCompatibilitySupport ( :disabled , :v1 , :v8 => :v1 )
80
81
include LogStash ::PluginMixins ::ECSCompatibilitySupport ::TargetCheck
@@ -126,6 +127,22 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
126
127
# by this pipeline input.
127
128
config :slices , :validate => :number
128
129
130
+ # Enable tracking the value of a given field to be used as a cursor
131
+ # TODO: main concerns
132
+ # * schedule overlap needs to be disabled (hardcoded as enabled)
133
+ # * using anything other than _event.timestamp easily leads to data loss
134
+ # * the first "synchronization run can take a long time"
135
+ # * checkpointing is only safe to do after each run (not per document)
136
+ config :tracking_field , :validate => :string
137
+
138
+ # Define the initial seed value of the tracking_field
139
+ config :tracking_field_seed , :validate => :string
140
+
141
+ # The location of where the tracking field value will be stored
142
+ # The value is persisted after each scheduled run (and not per result)
143
+ # If it's not set it defaults to '${path.data}/plugins/inputs/elasticsearch/last_run_value'
144
+ config :last_run_metadata_path , :validate => :string
145
+
129
146
# If set, include Elasticsearch document information such as index, type, and
130
147
# the id in the event.
131
148
#
@@ -252,6 +269,10 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
252
269
# exactly once.
253
270
config :schedule , :validate => :string
254
271
272
+ # Allow scheduled runs to overlap (enabled by default). Setting to false will
273
+ # only start a new scheduled run after the previous one completes.
274
+ config :schedule_overlap , :validate => :string
275
+
255
276
# If set, the _source of each hit will be added nested under the target instead of at the top-level
256
277
config :target , :validate => :field_reference
257
278
@@ -330,25 +351,38 @@ def register
330
351
331
352
setup_query_executor
332
353
354
+ setup_cursor_tracker
355
+
333
356
@client
334
357
end
335
358
336
359
def run ( output_queue )
337
360
if @schedule
338
- scheduler . cron ( @schedule ) { @query_executor . do_run ( output_queue ) }
361
+ scheduler . cron ( @schedule , :overlap => @schedule_overlap ) do
362
+ @query_executor . do_run ( output_queue , get_query_object ( ) )
363
+ @cursor_tracker . checkpoint_cursor
364
+ end
339
365
scheduler . join
340
366
else
341
- @query_executor . do_run ( output_queue )
367
+ @query_executor . do_run ( output_queue , get_query_object ( ) )
368
+ @cursor_tracker . checkpoint_cursor
342
369
end
343
370
end
344
371
372
+ def get_query_object
373
+ injected_query = @cursor_tracker . inject_cursor ( @query )
374
+ @logger . debug ( "new query is #{ injected_query } " )
375
+ query_object = LogStash ::Json . load ( injected_query )
376
+ end
377
+
345
378
##
346
379
# This can be called externally from the query_executor
347
380
public
348
381
def push_hit ( hit , output_queue , root_field = '_source' )
349
382
event = event_from_hit ( hit , root_field )
350
383
decorate ( event )
351
384
output_queue << event
385
+ @cursor_tracker . record_last_value ( event )
352
386
end
353
387
354
388
def event_from_hit ( hit , root_field )
@@ -642,6 +676,17 @@ def setup_query_executor
642
676
end
643
677
end
644
678
679
+ def setup_cursor_tracker
680
+ if @tracking_field
681
+ @tracking_field_seed ||= Time . now . utc . iso8601
682
+ @cursor_tracker = CursorTracker . new ( last_run_metadata_path : @last_run_metadata_path ,
683
+ tracking_field : @tracking_field ,
684
+ tracking_field_seed : @tracking_field_seed )
685
+ else
686
+ @cursor_tracker = NoopCursorTracker . new
687
+ end
688
+ end
689
+
645
690
module URIOrEmptyValidator
646
691
##
647
692
# @override to provide :uri_or_empty validator
0 commit comments