logstash-core 7.2.1-java → 7.3.0-java

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: '049f2a5cf05f1811e4393f09bbf0dfd07b63fcfc27e760fefafdb7d78c340659'
4
- data.tar.gz: a22c780783a2d190f4e97877e5e41191921a49568184b59c1d12ce276f55e567
3
+ metadata.gz: 4d89cdfc9aa7abd577325a9452457eabce0c675f0e279c83e1d412717597113c
4
+ data.tar.gz: 8bbe82e61e6a0f8066b47869eacae5e70d3d9f9d5c982509b550ef0476cae934
5
5
  SHA512:
6
- metadata.gz: ce56af4e9f40c706cd08f7ef6fb00dcab449e64b72968312feff85aa0c8460a28b48b41fa5b059eb75b610a679ccfef38653cf5774160eb3878eb5fded78ec1d
7
- data.tar.gz: 6d480b9c63e22f25b2b51521e6da69013bac56f875b803c94e173a8153ab2618bae4d366d90904286ecde7bdb4f0584030aad05fab1bb2103d251835058691ee
6
+ metadata.gz: e8804c92c588d2acd081318b94af4c92d1cdb310c578ff3e2915a1b4d40754450d9b6a62e550a101e33b88b61dfea7f9b4605fcaa0dc77a269e72f76dac7343e
7
+ data.tar.gz: ffcdf7710fece27cddc70601bd6650c6b6efba007fa75486e93e884754ac84828429cc7b8bdb3c5658599072c6544a720b02f7a1ee1d27931125f5af07d605ec
@@ -15,6 +15,11 @@ module LogStash
15
15
  :ephemeral_id => service.agent.ephemeral_id,
16
16
  :status => "green", # This is hard-coded to mirror x-pack behavior
17
17
  :snapshot => ::BUILD_INFO["build_snapshot"],
18
+ :pipeline => {
19
+ :workers => LogStash::SETTINGS.get("pipeline.workers"),
20
+ :batch_size => LogStash::SETTINGS.get("pipeline.batch.size"),
21
+ :batch_delay => LogStash::SETTINGS.get("pipeline.batch.delay"),
22
+ }
18
23
  }
19
24
  end
20
25
 
@@ -36,10 +36,12 @@ module LogStash
36
36
  :config_reload_interval,
37
37
  :dead_letter_queue_enabled,
38
38
  :dead_letter_queue_path,
39
- :cluster_uuids
40
39
  ).reject{|_, v|v.nil?}
41
40
  if options.fetch(:graph, false)
42
- metrics.merge!(extract_metrics([:stats, :pipelines, pipeline_id.to_sym, :config], :graph))
41
+ extended_stats = extract_metrics([:stats, :pipelines, pipeline_id.to_sym, :config], :graph)
42
+ decorated_vertices = extended_stats[:graph]["graph"]["vertices"].map { |vertex| decorate_with_cluster_uuids(vertex) }
43
+ extended_stats[:graph]["graph"]["vertices"] = decorated_vertices
44
+ metrics.merge!(extended_stats)
43
45
  end
44
46
  metrics
45
47
  rescue
@@ -78,6 +80,24 @@ module LogStash
78
80
  def hot_threads(options={})
79
81
  HotThreadsReport.new(self, options)
80
82
  end
83
+
84
+ private
85
+ ##
86
+ # Returns a vertex, decorated with the cluster UUID metadata retrieved from ES
87
+ # Does not mutate the passed `vertex` object.
88
+ # @api private
89
+ # @param vertex [Hash{String=>Object}]
90
+ # @return [Hash{String=>Object}]
91
+ def decorate_with_cluster_uuids(vertex)
92
+ plugin_id = vertex["id"]&.to_s
93
+ return vertex unless plugin_id && LogStash::PluginMetadata.exists?(plugin_id)
94
+
95
+ plugin_metadata = LogStash::PluginMetadata.for_plugin(plugin_id)
96
+ cluster_uuid = plugin_metadata&.get(:cluster_uuid)
97
+ vertex = vertex.merge("cluster_uuid" => cluster_uuid) unless cluster_uuid.nil?
98
+
99
+ vertex
100
+ end
81
101
  end
82
102
  end
83
103
  end
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require "logstash/api/commands/base"
3
3
  require 'logstash/util/thread_dump'
4
+ require 'logstash/config/pipelines_info'
4
5
  require_relative "hot_threads_reporter"
5
6
 
6
7
  java_import java.nio.file.Files
@@ -10,6 +11,20 @@ module LogStash
10
11
  module Api
11
12
  module Commands
12
13
  class Stats < Commands::Base
14
+ def queue
15
+ pipeline_ids = service.get_shallow(:stats, :pipelines).keys
16
+ total_queued_events = 0
17
+ pipeline_ids.each do |pipeline_id|
18
+ p_stats = service.get_shallow(:stats, :pipelines, pipeline_id.to_sym)
19
+ type = p_stats[:queue] && p_stats[:queue][:type].value
20
+ pipeline = service.agent.get_pipeline(pipeline_id)
21
+ next if pipeline.nil? || pipeline.system? || type != 'persisted'
22
+ total_queued_events += p_stats[:queue][:events].value
23
+ end
24
+
25
+ {:events_count => total_queued_events}
26
+ end
27
+
13
28
  def jvm
14
29
  {
15
30
  :threads => extract_metrics(
@@ -45,14 +60,24 @@ module LogStash
45
60
  )
46
61
  end
47
62
 
48
- def pipeline(pipeline_id = nil)
63
+ def pipeline(pipeline_id = nil, opts={})
64
+ extended_stats = LogStash::Config::PipelinesInfo.format_pipelines_info(
65
+ service.agent,
66
+ service.snapshot.metric_store,
67
+ true).each_with_object({}) do |pipeline_stats, memo|
68
+ pipeline_id = pipeline_stats["id"].to_s
69
+ memo[pipeline_id] = pipeline_stats
70
+ end
71
+
49
72
  if pipeline_id.nil?
50
73
  pipeline_ids = service.get_shallow(:stats, :pipelines).keys
51
74
  pipeline_ids.each_with_object({}) do |pipeline_id, result|
52
- result[pipeline_id] = plugins_stats_report(pipeline_id)
75
+ extended_pipeline = extended_stats[pipeline_id.to_s]
76
+ result[pipeline_id] = plugins_stats_report(pipeline_id, extended_pipeline, opts)
53
77
  end
54
78
  else
55
- { pipeline_id => plugins_stats_report(pipeline_id) }
79
+ extended_pipeline = extended_stats[pipeline_id.to_s]
80
+ { pipeline_id => plugins_stats_report(pipeline_id, extended_pipeline, opts) }
56
81
  end
57
82
  rescue # failed to find pipeline
58
83
  {}
@@ -92,9 +117,9 @@ module LogStash
92
117
  end
93
118
 
94
119
  private
95
- def plugins_stats_report(pipeline_id)
120
+ def plugins_stats_report(pipeline_id, extended_pipeline, opts={})
96
121
  stats = service.get_shallow(:stats, :pipelines, pipeline_id.to_sym)
97
- PluginsStats.report(stats)
122
+ PluginsStats.report(stats, extended_pipeline, opts)
98
123
  end
99
124
 
100
125
  module PluginsStats
@@ -110,8 +135,8 @@ module LogStash
110
135
  end
111
136
  end
112
137
 
113
- def report(stats)
114
- {
138
+ def report(stats, extended_stats=nil, opts={})
139
+ ret = {
115
140
  :events => stats[:events],
116
141
  :plugins => {
117
142
  :inputs => plugin_stats(stats, :inputs),
@@ -121,8 +146,38 @@ module LogStash
121
146
  },
122
147
  :reloads => stats[:reloads],
123
148
  :queue => stats[:queue]
124
- }.merge(stats[:dlq] ? {:dead_letter_queue => stats[:dlq]} : {})
149
+ }
150
+ ret[:dead_letter_queue] = stats[:dlq] if stats.include?(:dlq)
151
+
152
+ # if extended_stats were provided, enrich the return value
153
+ if extended_stats
154
+ ret[:queue] = extended_stats["queue"] if extended_stats.include?("queue")
155
+ ret[:hash] = extended_stats["hash"]
156
+ ret[:ephemeral_id] = extended_stats["ephemeral_id"]
157
+ if opts[:vertices] && extended_stats.include?("vertices")
158
+ ret[:vertices] = extended_stats["vertices"].map { |vertex| decorate_vertex(vertex) }
159
+ end
125
160
  end
161
+
162
+ ret
163
+ end
164
+
165
+ ##
166
+ # Returns a vertex, decorated with additional metadata if available.
167
+ # Does not mutate the passed `vertex` object.
168
+ # @api private
169
+ # @param vertex [Hash{String=>Object}]
170
+ # @return [Hash{String=>Object}]
171
+ def decorate_vertex(vertex)
172
+ plugin_id = vertex["id"]&.to_s
173
+ return vertex unless plugin_id && LogStash::PluginMetadata.exists?(plugin_id)
174
+
175
+ plugin_metadata = LogStash::PluginMetadata.for_plugin(plugin_id)
176
+ cluster_uuid = plugin_metadata&.get(:cluster_uuid)
177
+ vertex = vertex.merge("cluster_uuid" => cluster_uuid) unless cluster_uuid.nil?
178
+
179
+ vertex
180
+ end
126
181
  end # module PluginsStats
127
182
  end
128
183
  end
@@ -29,14 +29,16 @@ module LogStash
29
29
 
30
30
  get "/pipelines/:id" do
31
31
  pipeline_id = params["id"]
32
- opts = {:graph => as_boolean(params.fetch("graph", false))}
32
+ opts = {:graph => as_boolean(params.fetch("graph", false)),
33
+ :vertices => as_boolean(params.fetch("vertices", false))}
33
34
  payload = node.pipeline(pipeline_id, opts)
34
35
  halt(404) if payload.empty?
35
36
  respond_with(:pipelines => { pipeline_id => payload } )
36
37
  end
37
38
 
38
39
  get "/pipelines" do
39
- opts = {:graph => as_boolean(params.fetch("graph", false))}
40
+ opts = {:graph => as_boolean(params.fetch("graph", false)),
41
+ :vertices => as_boolean(params.fetch("vertices", false))}
40
42
  payload = node.pipelines(opts)
41
43
  halt(404) if payload.empty?
42
44
  respond_with(:pipelines => payload )
@@ -21,11 +21,17 @@ module LogStash
21
21
  :events => events_payload,
22
22
  :pipelines => pipeline_payload,
23
23
  :reloads => reloads_payload,
24
- :os => os_payload
24
+ :os => os_payload,
25
+ :queue => queue
25
26
  }
26
27
  respond_with(payload, {:filter => params["filter"]})
27
28
  end
28
29
 
30
+ private
31
+ def queue
32
+ @stats.queue
33
+ end
34
+
29
35
  private
30
36
  def os_payload
31
37
  @stats.os
@@ -52,7 +58,8 @@ module LogStash
52
58
  end
53
59
 
54
60
  def pipeline_payload(val = nil)
55
- @stats.pipeline(val)
61
+ opts = {:vertices => as_boolean(params.fetch("vertices", false))}
62
+ @stats.pipeline(val, opts)
56
63
  end
57
64
  end
58
65
  end
@@ -124,3 +124,4 @@ module LogStash;
124
124
  end
125
125
  end
126
126
  end
127
+
@@ -0,0 +1,152 @@
1
+ # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2
+ # or more contributor license agreements. Licensed under the Elastic License;
3
+ # you may not use this file except in compliance with the Elastic License.
4
+ #
5
+ module LogStash; module Config;
6
+ class PipelinesInfo
7
+ def self.format_pipelines_info(agent, metric_store, extended_performance_collection)
8
+ # It is important that we iterate via the agent's pipelines vs. the
9
+ # metrics pipelines. This prevents race conditions as pipeline stats may be
10
+ # populated before the agent has it in its own pipelines state
11
+ stats = metric_store.get_with_path("/stats/pipelines")[:stats][:pipelines]
12
+ agent.running_pipelines.map do |pipeline_id, pipeline|
13
+ p_stats = stats[pipeline_id]
14
+ # Don't record stats for system pipelines
15
+ next nil if pipeline.system?
16
+ res = {
17
+ "id" => pipeline_id.to_s,
18
+ "hash" => pipeline.lir.unique_hash,
19
+ "ephemeral_id" => pipeline.ephemeral_id,
20
+ "events" => format_pipeline_events(p_stats[:events]),
21
+ "queue" => format_queue_stats(pipeline_id, metric_store),
22
+ "reloads" => {
23
+ "successes" => p_stats[:reloads][:successes].value,
24
+ "failures" => p_stats[:reloads][:failures].value
25
+ }
26
+ }
27
+ if extended_performance_collection
28
+ res["vertices"] = format_pipeline_vertex_stats(p_stats[:plugins], pipeline)
29
+ end
30
+ res
31
+ end.compact
32
+ end
33
+
34
+ def self.format_pipeline_events(stats)
35
+ result = {}
36
+ (stats || {}).each { |stage, counter| result[stage.to_s] = counter.value }
37
+ result
38
+ end
39
+
40
+ def self.format_pipeline_vertex_stats(stats, pipeline)
41
+ return nil unless stats
42
+
43
+ [:inputs, :filters, :outputs].flat_map do |section|
44
+ format_pipeline_vertex_section_stats(stats[section], pipeline)
45
+ end.select {|stats| !stats.nil?} # Ignore empty sections
46
+ end
47
+
48
+ ROOT_METRIC_MAPPINGS = {
49
+ 'events.in' => 'events_in',
50
+ 'events.out' => 'events_out',
51
+ 'events.queue_push_duration_in_millis' => 'queue_push_duration_in_millis',
52
+ 'events.duration_in_millis' => 'duration_in_millis',
53
+ 'name' => :discard # we don't need this, pipeline_state has this already
54
+ }
55
+
56
+ def self.format_pipeline_vertex_section_stats(stats, pipeline)
57
+ return nil unless stats
58
+
59
+ (stats || {}).reduce([]) do |acc,kv|
60
+ plugin_id, plugin_stats = kv
61
+
62
+ props = Hash.new {|h,k| h[k] = []}
63
+ next unless plugin_stats
64
+
65
+ flattened = flatten_metrics(plugin_stats)
66
+
67
+ segmented = flattened.reduce(Hash.new {|h,k| h[k] = []}) do |acc,kv|
68
+ k,v = kv
69
+ metric_value = v.value
70
+ root_metric_field = ROOT_METRIC_MAPPINGS[k]
71
+
72
+ if root_metric_field
73
+ if root_metric_field != :discard
74
+ acc[root_metric_field] = metric_value
75
+ end
76
+ else
77
+ type_sym = v.type.to_sym
78
+
79
+ nested_type = if type_sym == :"counter/long"
80
+ :long_counters
81
+ elsif type_sym == :"gauge/numeric"
82
+ :double_gauges
83
+ else
84
+ nil
85
+ end
86
+
87
+ if nested_type
88
+ acc[nested_type] << { :name => k, :value => metric_value }
89
+ end
90
+ end
91
+
92
+ acc
93
+ end
94
+ segment = {
95
+ :id => plugin_id,
96
+ :pipeline_ephemeral_id => pipeline.ephemeral_id
97
+ }
98
+
99
+ if LogStash::PluginMetadata.exists?(plugin_id.to_s)
100
+ plugin_metadata = LogStash::PluginMetadata.for_plugin(plugin_id.to_s)
101
+ cluster_uuid = plugin_metadata&.get(:cluster_uuid)
102
+ segment[:cluster_uuid] = cluster_uuid unless cluster_uuid.nil?
103
+ end
104
+
105
+ acc << segment.merge(segmented)
106
+ acc
107
+ end
108
+ end
109
+
110
+ def self.flatten_metrics(hash_or_value, namespaces = [])
111
+ if hash_or_value.is_a?(Hash)
112
+ return hash_or_value.reduce({}) do |acc,kv|
113
+ k,v = kv
114
+ # We must concat the arrays, creating a copy instead of mutation
115
+ # to handle the case where there are multiple sibling metrics in a namespace
116
+ new_namespaces = namespaces.clone
117
+ new_namespaces << k
118
+ acc.merge(flatten_metrics(v, new_namespaces))
119
+ end
120
+ else
121
+ { namespaces.join('.') => hash_or_value }
122
+ end
123
+ end
124
+
125
+ def self.format_queue_stats(pipeline_id, metric_store)
126
+ path = [:stats, :pipelines, pipeline_id, :queue, :type]
127
+ if metric_store.has_metric?(*path)
128
+ queue_type = metric_store.get_shallow(*path).value
129
+ else
130
+ queue_type = 'memory'
131
+ end
132
+
133
+ events = 0
134
+ queue_size_in_bytes = 0
135
+ max_queue_size_in_bytes = 0
136
+
137
+ if queue_type == "persisted"
138
+ queue_path = [:stats, :pipelines, pipeline_id, :queue]
139
+ events = metric_store.get_shallow(*queue_path, :events).value
140
+ queue_size_in_bytes = metric_store.get_shallow(*queue_path, :capacity, :queue_size_in_bytes).value
141
+ max_queue_size_in_bytes = metric_store.get_shallow(*queue_path, :capacity, :max_queue_size_in_bytes).value
142
+ end
143
+
144
+ {
145
+ :type => queue_type,
146
+ :events_count => events,
147
+ :queue_size_in_bytes => queue_size_in_bytes,
148
+ :max_queue_size_in_bytes => max_queue_size_in_bytes,
149
+ }
150
+ end
151
+ end
152
+ end; end;
@@ -72,5 +72,4 @@ Gem::Specification.new do |gem|
72
72
 
73
73
  gem.add_runtime_dependency "elasticsearch", "~> 5"
74
74
  gem.add_runtime_dependency "manticore", '~> 0.6'
75
- gem.add_runtime_dependency "faraday", '~> 0.9.0'
76
75
  end
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  # alpha and beta qualifiers are now added via VERSION_QUALIFIER environment var
3
- logstash: 7.2.1
4
- logstash-core: 7.2.1
3
+ logstash: 7.3.0
4
+ logstash-core: 7.3.0
5
5
  logstash-core-plugin-api: 2.1.16
6
6
 
7
7
  # jruby must reference a *released* version of jruby which can be downloaded from the official download url
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.1
4
+ version: 7.3.0
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
@@ -288,20 +288,6 @@ dependencies:
288
288
  - - "~>"
289
289
  - !ruby/object:Gem::Version
290
290
  version: '0.6'
291
- - !ruby/object:Gem::Dependency
292
- requirement: !ruby/object:Gem::Requirement
293
- requirements:
294
- - - "~>"
295
- - !ruby/object:Gem::Version
296
- version: 0.9.0
297
- name: faraday
298
- prerelease: false
299
- type: :runtime
300
- version_requirements: !ruby/object:Gem::Requirement
301
- requirements:
302
- - - "~>"
303
- - !ruby/object:Gem::Version
304
- version: 0.9.0
305
291
  description: The core components of logstash, the scalable log and event management
306
292
  tool
307
293
  email:
@@ -352,6 +338,7 @@ files:
352
338
  - lib/logstash/config/mixin.rb
353
339
  - lib/logstash/config/modules_common.rb
354
340
  - lib/logstash/config/pipeline_config.rb
341
+ - lib/logstash/config/pipelines_info.rb
355
342
  - lib/logstash/config/source/base.rb
356
343
  - lib/logstash/config/source/local.rb
357
344
  - lib/logstash/config/source/modules.rb