logstash-input-twitter 4.0.3 → 4.1.0

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: 90a556dabd75cd5e9260c327a7bdffa6bfe5e7fe4f80457901505953d7dc31f2
4
- data.tar.gz: c83225608136218ea6b950f158fcd1983b3455c533f37a4f01d768b1e6dc03e2
3
+ metadata.gz: 35aa088d3d7f0ebcecf9ea2e00ea9009dacf682b99ca57f544ca25201cf70744
4
+ data.tar.gz: 5e740cbcabb04ba97a218324d8d5c56aa20f992382347e3aaae29bf4ff6260b8
5
5
  SHA512:
6
- metadata.gz: cced602c79e40db401fb8a2547fc2a4756a9680b62ce31852f953bcc7a17942076378e04e403505403152f8d751b9a61f90d643ff406aa3cbc90e23438291fbe
7
- data.tar.gz: 7e2cef7a66efcd33566dab11d6e293b07a6a3458d22c66372b28f63dcec676dcba2fff6e63c5aec7f41836109afda8d4233f1a4c7e76625c4bbbd8fff71c8900
6
+ metadata.gz: 61c1343445e3dca087247221044d41feb05c660d17682cb47bf0499f31f19a5206f636128f67c4d1c34295db29bd45c305344d63cef09ed10b7a5cf9dbc9514d
7
+ data.tar.gz: 2dbb9da7f8097ec766bf2ad0a2ae3745e7e811b31f5e8dded9b8fac413edffd014eaadc247895373d1260ee0a690a6b961fe17a50ec3a01d882d02c859643f97
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 4.1.0
2
+ - Feat: optional target + ecs_compatibility [#72](https://github.com/logstash-plugins/logstash-input-twitter/pull/72)
3
+
1
4
  ## 4.0.3
2
5
  - Fix: broken proxy configuration [#69](https://github.com/logstash-plugins/logstash-input-twitter/pull/69)
3
6
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Logstash Plugin
2
2
 
3
- [![Travis Build Status](https://travis-ci.org/logstash-plugins/logstash-input-twitter.svg)](https://travis-ci.org/logstash-plugins/logstash-input-twitter)
3
+ [![Travis Build Status](https://travis-ci.com/logstash-plugins/logstash-input-twitter.svg)](https://travis-ci.com/logstash-plugins/logstash-input-twitter)
4
4
 
5
5
  This is a plugin for [Logstash](https://github.com/elastic/logstash).
6
6
 
data/docs/index.asciidoc CHANGED
@@ -23,6 +23,46 @@ include::{include_path}/plugin_header.asciidoc[]
23
23
 
24
24
  Ingest events from the Twitter Streaming API.
25
25
 
26
+ Example:
27
+ [source,ruby]
28
+ input {
29
+ twitter {
30
+ consumer_key => '...'
31
+ consumer_secret => '...'
32
+ oauth_token => '...'
33
+ oauth_token_secret => '...'
34
+ keywords => [ 'logstash' ]
35
+ }
36
+ }
37
+
38
+ Sample event fields generated:
39
+
40
+ [source,ruby]
41
+ -----
42
+ {
43
+ "@timestamp" => 2019-09-23T16:41:53.000Z,
44
+ "message" => "I forgot how fun it is to write @logstash configs !!! Thank you @jordansissel and @elastic !!!"
45
+ "user" => "missnebun",
46
+ "in-reply-to" => nil,
47
+ "retweeted" => false,
48
+ "source" => "http://twitter.com/missnebun/status/1176174859833004037",
49
+ "user_mentions" => [
50
+ { "screen_name"=>"logstash", "name"=>"logstash", "id"=>217155915 },
51
+ { "screen_name"=>"jordansissel", "name"=>"@jordansissel", "id"=>15782607 },
52
+ { "screen_name"=>"elastic", "name"=>"Elastic", "id"=>84512601 }],
53
+ "symbols" => [],
54
+ "hashtags" => [],
55
+ "client" => "<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone</a>"
56
+ }
57
+ -----
58
+
59
+ [id="plugins-{type}s-{plugin}-ecs"]
60
+ ==== Compatibility with the Elastic Common Schema (ECS)
61
+
62
+ Twitter streams are very specific and do not map easily to the {ecs-ref}[Elastic Common Schema (ECS)].
63
+ We recommend setting a <<plugins-{type}s-{plugin}-target>> when <<plugins-{type}s-{plugin}-ecs_compatibility,ECS compatibility mode>> is enabled.
64
+ The plugin issues a warning in the log when a `target` isn't set.
65
+
26
66
  [id="plugins-{type}s-{plugin}-options"]
27
67
  ==== Twitter Input Configuration Options
28
68
 
@@ -33,6 +73,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
33
73
  |Setting |Input type|Required
34
74
  | <<plugins-{type}s-{plugin}-consumer_key>> |<<string,string>>|Yes
35
75
  | <<plugins-{type}s-{plugin}-consumer_secret>> |<<password,password>>|Yes
76
+ | <<plugins-{type}s-{plugin}-ecs_compatibility>> |<<string,string>>|No
36
77
  | <<plugins-{type}s-{plugin}-follows>> |<<array,array>>|No
37
78
  | <<plugins-{type}s-{plugin}-full_tweet>> |<<boolean,boolean>>|No
38
79
  | <<plugins-{type}s-{plugin}-ignore_retweets>> |<<boolean,boolean>>|No
@@ -46,6 +87,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
46
87
  | <<plugins-{type}s-{plugin}-rate_limit_reset_in>> |<<number,number>>|No
47
88
  | <<plugins-{type}s-{plugin}-use_proxy>> |<<boolean,boolean>>|No
48
89
  | <<plugins-{type}s-{plugin}-use_samples>> |<<boolean,boolean>>|No
90
+ | <<plugins-{type}s-{plugin}-target>> |<<string,string>>|No
49
91
  |=======================================================================
50
92
 
51
93
  Also see <<plugins-{type}s-{plugin}-common-options>> for a list of options supported by all
@@ -78,6 +120,19 @@ If you don't have one of these, you can create one by
78
120
  registering a new application with Twitter:
79
121
  <https://dev.twitter.com/apps/new>
80
122
 
123
+ [id="plugins-{type}s-{plugin}-ecs_compatibility"]
124
+ ===== `ecs_compatibility`
125
+
126
+ * Value type is <<string,string>>
127
+ * Supported values are:
128
+ ** `disabled`: does not use ECS-compatible field names (fields might be set at the root of the event)
129
+ ** `v1`, `v8`: avoids field names that might conflict with Elastic Common Schema (for example, Twitter specific properties)
130
+ * Default value depends on which version of Logstash is running:
131
+ ** When Logstash provides a `pipeline.ecs_compatibility` setting, its value is used as the default
132
+ ** Otherwise, the default value is `disabled`.
133
+
134
+ Controls this plugin's compatibility with the {ecs-ref}[Elastic Common Schema (ECS)].
135
+
81
136
  [id="plugins-{type}s-{plugin}-follows"]
82
137
  ===== `follows`
83
138
 
@@ -221,6 +276,17 @@ by the default access level are the same, so if two different clients connect
221
276
  to this endpoint, they will see the same tweets. If set to true, the keywords,
222
277
  follows, locations, and languages options will be ignored. Default => false
223
278
 
279
+ [id="plugins-{type}s-{plugin}-target"]
280
+ ===== `target`
281
+
282
+ * Value type is <<string,string>>
283
+ * There is no default value for this setting.
284
+
285
+ Without a `target`, events are created from tweets at the root level.
286
+ When the `target` is set to a field reference, the tweet data is placed in the target field instead.
287
+
288
+ This option can be useful to avoid populating unknown fields when a downstream schema such as ECS is enforced.
289
+
224
290
 
225
291
 
226
292
  [id="plugins-{type}s-{plugin}-common-options"]
@@ -7,10 +7,20 @@ require "logstash/json"
7
7
  require "stud/interval"
8
8
  require "twitter"
9
9
  require "logstash/inputs/twitter/patches"
10
+ require 'logstash/plugin_mixins/ecs_compatibility_support'
11
+ require 'logstash/plugin_mixins/ecs_compatibility_support/target_check'
12
+ require 'logstash/plugin_mixins/event_support/event_factory_adapter'
13
+ require 'logstash/plugin_mixins/validator_support/field_reference_validation_adapter'
10
14
 
11
15
  # Ingest events from the Twitter Streaming API.
12
16
  class LogStash::Inputs::Twitter < LogStash::Inputs::Base
13
17
 
18
+ include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled, :v1, :v8 => :v1)
19
+ include LogStash::PluginMixins::ECSCompatibilitySupport::TargetCheck
20
+ include LogStash::PluginMixins::EventSupport::EventFactoryAdapter
21
+
22
+ extend LogStash::PluginMixins::ValidatorSupport::FieldReferenceValidationAdapter
23
+
14
24
  attr_reader :filter_options, :event_generation_error_count
15
25
 
16
26
  config_name "twitter"
@@ -104,6 +114,11 @@ class LogStash::Inputs::Twitter < LogStash::Inputs::Base
104
114
  # is nil. If this occurs then we use the integer specified here. The default is 5 minutes.
105
115
  config :rate_limit_reset_in, :validate => :number, :default => 300
106
116
 
117
+ # Defines a target field for placing fields.
118
+ # If this setting is omitted, data gets stored at the root (top level) of the event.
119
+ # The target is only relevant while decoding data into a new event.
120
+ config :target, :validate => :field_reference
121
+
107
122
  def register
108
123
  if !@use_samples && ( @keywords.nil? && @follows.nil? && @locations.nil? )
109
124
  raise LogStash::ConfigurationError.new("At least one parameter (follows, locations or keywords) must be specified.")
@@ -189,35 +204,34 @@ class LogStash::Inputs::Twitter < LogStash::Inputs::Base
189
204
 
190
205
  def from_tweet(tweet)
191
206
  @logger.debug? && @logger.debug("Got tweet", :user => tweet.user.screen_name, :text => tweet.text)
207
+
192
208
  if @full_tweet
193
- event = LogStash::Event.new(LogStash::Util.stringify_symbols(tweet.to_hash))
194
- event.timestamp = LogStash::Timestamp.new(tweet.created_at)
209
+ attributes = LogStash::Util.stringify_symbols(tweet.to_hash)
195
210
  else
196
-
197
211
  attributes = {
198
- LogStash::Event::TIMESTAMP => LogStash::Timestamp.new(tweet.created_at),
199
212
  "message" => tweet.full_text,
200
213
  "user" => tweet.user.screen_name,
201
214
  "client" => tweet.source,
202
215
  "retweeted" => tweet.retweeted?,
203
- "source" => "http://twitter.com/#{tweet.user.screen_name}/status/#{tweet.id}"
216
+ "source" => "http://twitter.com/#{tweet.user.screen_name}/status/#{tweet.id}",
217
+ "hashtags" => tweet.hashtags.map(&:attrs),
218
+ "symbols" => tweet.symbols.map(&:attrs),
219
+ "user_mentions" => tweet.user_mentions.map(&:attrs),
204
220
  }
205
221
 
206
- attributes["hashtags"] = tweet.hashtags.map{|ht| ht.attrs}
207
- attributes["symbols"] = tweet.symbols.map{|sym| sym.attrs}
208
- attributes["user_mentions"] = tweet.user_mentions.map{|um| um.attrs}
209
- event = LogStash::Event.new(attributes)
210
222
  if tweet.reply? && !tweet.in_reply_to_status_id.nil?
211
- event.set("in-reply-to", tweet.in_reply_to_status_id)
223
+ attributes["in-reply-to"] = tweet.in_reply_to_status_id
212
224
  end
213
225
  unless tweet.urls.empty?
214
- event.set("urls", tweet.urls.map(&:expanded_url).map(&:to_s))
226
+ attributes["urls"] = tweet.urls.map(&:expanded_url).map(&:to_s)
215
227
  end
216
228
  end
217
229
 
218
230
  # Work around bugs in JrJackson. The standard serializer won't work till we upgrade
219
231
  # event.set("in-reply-to", nil) if event.get("in-reply-to").is_a?(Twitter::NullObject)
220
232
 
233
+ event = targeted_event_factory.new_event(attributes)
234
+ event.timestamp = LogStash::Timestamp.new(tweet.created_at)
221
235
  event
222
236
  end
223
237
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-input-twitter'
3
- s.version = '4.0.3'
3
+ s.version = '4.1.0'
4
4
  s.licenses = ['Apache License (2.0)']
5
5
  s.summary = "Reads events from the Twitter Streaming API"
6
6
  s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
@@ -24,6 +24,9 @@ Gem::Specification.new do |s|
24
24
 
25
25
  # Gem dependencies
26
26
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
27
+ s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~> 1.3'
28
+ s.add_runtime_dependency "logstash-mixin-event_support", '~> 1.0'
29
+ s.add_runtime_dependency 'logstash-mixin-validator_support', '~> 1.0'
27
30
  s.add_runtime_dependency 'twitter', '6.2.0'
28
31
  s.add_runtime_dependency 'http-form_data', '~> 2'
29
32
  s.add_runtime_dependency 'public_suffix', '~> 3'
@@ -97,6 +97,58 @@ describe LogStash::Inputs::Twitter do
97
97
 
98
98
  end
99
99
 
100
+ let(:tweet) do
101
+ Twitter::Tweet.new(id: 1234567890123456789,
102
+ id_str: '1234567890123456789',
103
+ created_at: 'Thu Nov 11 10:00:00 +0000 2021',
104
+ text: 'Hello World! 🥰',
105
+ source: "<a href=\"http://twitter.com/download/android\" rel=\"nofollow\">Twitter for Android</a>",
106
+ truncated: false,
107
+ user: {
108
+ id: 1182909005012345600,
109
+ name: "Foo Bar",
110
+ screen_name: "foo001",
111
+ location: nil,
112
+ })
113
+ end
114
+
115
+ describe "from tweet" do
116
+
117
+ before(:each) do
118
+ plugin.register
119
+ @event = plugin.send :from_tweet, tweet
120
+ end
121
+
122
+ it "generated an event" do
123
+ expect(@event.get('message')).to eql "Hello World! 🥰"
124
+ expect(@event.get('user')).to eql "foo001"
125
+ expect(@event.timestamp.to_s).to match /2021-11-11T10:00:00(.000)?Z/
126
+ end
127
+
128
+ context 'with full_tweet' do
129
+ let(:config) { super().merge 'full_tweet' => true }
130
+
131
+ it "generated an event" do
132
+ expect(@event.get('text')).to eql "Hello World! 🥰"
133
+ expect(@event.get('user')['screen_name']).to eql "foo001"
134
+ expect(@event.timestamp.to_s).to match /2021-11-11T10:00:00(.000)?Z/
135
+ end
136
+ end
137
+
138
+ context 'with target' do
139
+ let(:config) { super().merge 'target' => '[twitter]' }
140
+
141
+ it "generated an event" do
142
+ expect(@event.include?('message')).to be false
143
+ expect(@event.include?('user')).to be false
144
+
145
+ expect(@event.get('[twitter][message]')).to eql "Hello World! 🥰"
146
+ expect(@event.get('[twitter][user]')).to eql "foo001"
147
+ expect(@event.timestamp.to_s).to match /2021-11-11T10:00:00(.000)?Z/
148
+ end
149
+ end
150
+ end
151
+
100
152
  describe "stream filter" do
101
153
 
102
154
  describe "options parsing" do
@@ -161,8 +213,6 @@ describe LogStash::Inputs::Twitter do
161
213
 
162
214
  context "when not filtering retweets" do
163
215
 
164
- let(:tweet) { Twitter::Tweet.new(id: 1) }
165
-
166
216
  let(:config) do
167
217
  {
168
218
  'consumer_key' => 'foo',
@@ -187,8 +237,6 @@ describe LogStash::Inputs::Twitter do
187
237
 
188
238
  context "when filtering retweets" do
189
239
 
190
- let(:tweet) { Twitter::Tweet.new(id: 1) }
191
-
192
240
  let(:config) do
193
241
  {
194
242
  'consumer_key' => 'foo',
@@ -219,7 +267,7 @@ describe LogStash::Inputs::Twitter do
219
267
  end
220
268
 
221
269
  let(:config) do
222
- super.merge( 'use_proxy' => true, 'proxy_address' => '127.0.0.1', 'proxy_port' => 12345 )
270
+ super().merge( 'use_proxy' => true, 'proxy_address' => '127.0.0.1', 'proxy_port' => 12345 )
223
271
  end
224
272
 
225
273
  let(:proxy_socket) { double('proxy-socket') }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-twitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.3
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-06 00:00:00.000000000 Z
11
+ date: 2021-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -30,6 +30,48 @@ dependencies:
30
30
  - - "<="
31
31
  - !ruby/object:Gem::Version
32
32
  version: '2.99'
33
+ - !ruby/object:Gem::Dependency
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - "~>"
37
+ - !ruby/object:Gem::Version
38
+ version: '1.3'
39
+ name: logstash-mixin-ecs_compatibility_support
40
+ prerelease: false
41
+ type: :runtime
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.3'
47
+ - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '1.0'
53
+ name: logstash-mixin-event_support
54
+ prerelease: false
55
+ type: :runtime
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.0'
61
+ - !ruby/object:Gem::Dependency
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.0'
67
+ name: logstash-mixin-validator_support
68
+ prerelease: false
69
+ type: :runtime
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.0'
33
75
  - !ruby/object:Gem::Dependency
34
76
  requirement: !ruby/object:Gem::Requirement
35
77
  requirements:
@@ -179,8 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
221
  - !ruby/object:Gem::Version
180
222
  version: '0'
181
223
  requirements: []
182
- rubyforge_project:
183
- rubygems_version: 2.6.13
224
+ rubygems_version: 3.1.6
184
225
  signing_key:
185
226
  specification_version: 4
186
227
  summary: Reads events from the Twitter Streaming API