logstash-output-picsv 1.0.5
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 +7 -0
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/README.md +2 -0
- data/Rakefile +1 -0
- data/lib/logstash/outputs/picsv.rb +365 -0
- data/logstash-output-picsv.gemspec +25 -0
- data/spec/outputs/picsv_spec.rb +21 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8fe57ac88a14e3ed8becf6f750c9f9708c3aeb38
|
4
|
+
data.tar.gz: bb239e83f2e5c3dd4915ab668fb4299b19d26a54
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1a0259c8796a3180d6c9c757c19ae7abbd9eeeb27bf75f038f167d245197d6ef72698a3ad2ca6891344156a07aebcb824252a9546e1bf1aa83d11a580feaf5fc
|
7
|
+
data.tar.gz: bdcc0729fed0edd80b5f825a910d49a50b79b91e29c3a53f5985644c1542eb056f903cd7f1041db5a2b93104c4eec5dc2f69a8cb14ad942650196e681893b825
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "logstash/devutils/rake"
|
@@ -0,0 +1,365 @@
|
|
1
|
+
############################################
|
2
|
+
#
|
3
|
+
# picsv
|
4
|
+
#
|
5
|
+
# Logstash mediation output for IOA PI
|
6
|
+
#
|
7
|
+
# Version 030815.1 Robert Mckeown
|
8
|
+
# Version 030815.2 Jim Ray
|
9
|
+
#
|
10
|
+
############################################
|
11
|
+
|
12
|
+
require "csv"
|
13
|
+
require "logstash/namespace"
|
14
|
+
require "logstash/outputs/file"
|
15
|
+
require 'java' # for the java data format stuff
|
16
|
+
|
17
|
+
# SCACSV - based upon original Logstash CSV output.
|
18
|
+
#
|
19
|
+
# Write events to disk in CSV format
|
20
|
+
# Write a PI header as the first line in the file
|
21
|
+
# Name file per PI convention, based upon first and last timestamps encountered
|
22
|
+
|
23
|
+
class LogStash::Outputs::SCACSV < LogStash::Outputs::File
|
24
|
+
|
25
|
+
config_name "scacsv"
|
26
|
+
milestone 1
|
27
|
+
|
28
|
+
# The field names from the event that should be written to the CSV file.
|
29
|
+
# Fields are written to the CSV in the same order as the array.
|
30
|
+
# If a field does not exist on the event, an empty string will be written.
|
31
|
+
config :fields, :validate => :array, :required => true
|
32
|
+
|
33
|
+
|
34
|
+
# If present, the values here will over-ride the default header
|
35
|
+
# names. Useful if you simply want to provide other names
|
36
|
+
config :header, :validate => :array, :required => false
|
37
|
+
|
38
|
+
# Options for CSV output. This is passed directly to the Ruby stdlib to\_csv function.
|
39
|
+
# Full documentation is available here: [http://ruby-doc.org/stdlib-2.0.0/libdoc/csv/rdoc/index.html].
|
40
|
+
# A typical use case would be to use alternative column or row seperators eg: `csv_options => {"col_sep" => "\t" "row_sep" => "\r\n"}` gives tab seperated data with windows line endings
|
41
|
+
config :csv_options, :validate => :hash, :required => false, :default => Hash.new
|
42
|
+
|
43
|
+
# Name of the output group - used as a prefix in the renamed file
|
44
|
+
config :group, :validate => :string, :required => true
|
45
|
+
config :max_size, :validate => :number, :default => 0
|
46
|
+
config :file_interval_width, :validate => :string, :default => "" # Allow "" or "hour","day" or "minute"
|
47
|
+
config :flush_interval, :validate => :number, :default => 60
|
48
|
+
config :time_field, :validate => :string, :default => "timestamp"
|
49
|
+
# config :time_format, :validate => :string, :default => "%Y%m%d%H%M%S"
|
50
|
+
config :time_field_format, :validate => :string, :required => true
|
51
|
+
config :timestamp_output_format, :validate => :string, :default => "" # "yyyyMMddHHmmss" # java format
|
52
|
+
config :force_GMT_filenames, :validate => :boolean, :default => false
|
53
|
+
|
54
|
+
config :tz_offset, :validate => :number, :default => 0
|
55
|
+
config :increment_time, :validate => :boolean, :default => false
|
56
|
+
|
57
|
+
public
|
58
|
+
def register
|
59
|
+
super
|
60
|
+
@csv_options = Hash[@csv_options.map{|(k,v)|[k.to_sym, v]}]
|
61
|
+
|
62
|
+
# variables to hold the start and end times which we'll use to rename the files to
|
63
|
+
@startTime = "missingStartTime"
|
64
|
+
@endTime = "missingEndTime"
|
65
|
+
@recordCount = 0
|
66
|
+
|
67
|
+
@lastOutputTime = 0 #data time
|
68
|
+
@flushInterval = @flush_interval.to_i
|
69
|
+
|
70
|
+
@timerThread = Thread.new { flushWatchdog(@flush_interval) }
|
71
|
+
|
72
|
+
@currentOutputIntervalStartTime = 0
|
73
|
+
@fileIntervalWidthSeconds = 0
|
74
|
+
@closeOnIntervalBoundaries = false
|
75
|
+
case @file_interval_width.upcase
|
76
|
+
when "MINUTE"
|
77
|
+
@fileIntervalWidthSeconds = 60
|
78
|
+
@closeOnIntervalBoundaries = true
|
79
|
+
when "FIVE"
|
80
|
+
@fileIntervalWidthSeconds = 300
|
81
|
+
@closeOnIntervalBoundaries = true
|
82
|
+
when "FIFTEEN"
|
83
|
+
@fileIntervalWidthSeconds = 900
|
84
|
+
@closeOnIntervalBoundaries = true
|
85
|
+
when "HOUR"
|
86
|
+
@fileIntervalWidthSeconds = 3600
|
87
|
+
@closeOnIntervalBoundaries = true
|
88
|
+
when "DAY"
|
89
|
+
@fileIntervalWidthSeconds = 86400
|
90
|
+
@closeOnIntervalBoundaries = true
|
91
|
+
else
|
92
|
+
@fileIntervalWidthSeconds = 0 #not used
|
93
|
+
@closeOnIntervalBoundaries = false
|
94
|
+
end
|
95
|
+
|
96
|
+
@df = nil
|
97
|
+
if (@time_field_format != "epoch")
|
98
|
+
@df = java.text.SimpleDateFormat.new(@time_field_format)
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
# This thread ensures that we output (close and rename) a file every so often
|
105
|
+
private
|
106
|
+
def flushWatchdog(delay)
|
107
|
+
begin
|
108
|
+
@logger.debug("SCACSVFlushWatchdog - Last output time = " + @lastOutputTime.to_s)
|
109
|
+
while true do
|
110
|
+
@logger.debug("SCACSVFlushWatchdog - Time.now = " + Time.now.to_s + " $lastOutputTime=" + @lastOutputTime.to_s + " delay=" + delay.to_s)
|
111
|
+
|
112
|
+
if ( (Time.now.to_i >= (@lastOutputTime.to_i + delay.to_i)) and (@recordCount > 0)) then
|
113
|
+
@logger.debug("SCACSVFlushWatchdog - closeAndRenameCurrentFile")
|
114
|
+
closeAndRenameCurrentFile
|
115
|
+
end
|
116
|
+
@logger.debug("SCACSVFlushWatchdog - Sleeping")
|
117
|
+
sleep 1
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
public
|
123
|
+
def receive(event)
|
124
|
+
return unless output?(event)
|
125
|
+
|
126
|
+
@logger.debug("in SCACSV receive")
|
127
|
+
|
128
|
+
if (event['SCAWindowMarker'])
|
129
|
+
# just eat the marker - don't output it
|
130
|
+
# if we had at least one record output, then close the file and move on
|
131
|
+
if @recordCount >= 1
|
132
|
+
closeAndRenameCurrentFile
|
133
|
+
end
|
134
|
+
else
|
135
|
+
|
136
|
+
# Now see if we need to close file because of a new boundary
|
137
|
+
if @closeOnIntervalBoundaries and @recordCount >= 1 and (@currentOutputIntervalStartTime != snapTimestampToInterval(timestampFromEventAsEpochSeconds(event),@fileIntervalWidthSeconds))
|
138
|
+
closeAndRenameCurrentFile
|
139
|
+
end
|
140
|
+
|
141
|
+
@formattedPath = event.sprintf(@path)
|
142
|
+
fd = open(@formattedPath)
|
143
|
+
@logger.debug("SCACSVreceive - after opening fd=" + fd.to_s)
|
144
|
+
|
145
|
+
if @recordCount == 0
|
146
|
+
# output header on first line - note, need a minimum of one record for sensible output
|
147
|
+
if @header then
|
148
|
+
# csv_header = @fields.map { |name| name }
|
149
|
+
fd.write(@header.to_csv(@csv_options))
|
150
|
+
else
|
151
|
+
fd.write(@fields.to_csv(@csv_options))
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
csv_values = @fields.map {|name| get_value(name, event)}
|
156
|
+
fd.write(csv_values.to_csv(@csv_options))
|
157
|
+
|
158
|
+
flush(fd)
|
159
|
+
close_stale_files
|
160
|
+
|
161
|
+
# remember state
|
162
|
+
@recordCount = @recordCount + 1
|
163
|
+
@lastOutputTime = Time.now
|
164
|
+
|
165
|
+
# capture the earliest - assumption is that records are in order
|
166
|
+
if (@recordCount) == 1
|
167
|
+
if !@closeOnIntervalBoundaries
|
168
|
+
@startTime = timestampFromEventAsEpochSeconds(event)
|
169
|
+
else
|
170
|
+
@startTime = snapTimestampToInterval(timestampFromEventAsEpochSeconds(event),@fileIntervalWidthSeconds)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# for every record, update endTime - again, assumption is that records are in order
|
175
|
+
if !@closeOnIntervalBoundaries
|
176
|
+
@endTime = timestampFromEventAsEpochSeconds(event)
|
177
|
+
else
|
178
|
+
@endTime = @startTime + @fileIntervalWidthSeconds - 1 # end of interval
|
179
|
+
end
|
180
|
+
|
181
|
+
# remember start of boundary for next time
|
182
|
+
if @closeOnIntervalBoundaries
|
183
|
+
@currentOutputIntervalStartTime = @startTime
|
184
|
+
end
|
185
|
+
|
186
|
+
if ((@max_size > 0) and (@recordCount >= max_size))
|
187
|
+
# Have enough records, close it out
|
188
|
+
closeAndRenameCurrentFile
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
end #def receive
|
193
|
+
|
194
|
+
private
|
195
|
+
def timestampAsEpochSeconds(timestamp, dateFormat)
|
196
|
+
if !dateFormat.nil?
|
197
|
+
return dateFormat.parse(timestamp.to_s).getTime/1000 # convert milliSeconds to seconds
|
198
|
+
else
|
199
|
+
#when df not set, we assume epoch SECONDS
|
200
|
+
return timestamp.to_i
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
private
|
205
|
+
def timestampFromEventAsEpochSeconds(event)
|
206
|
+
timestampAsEpochSeconds(event[@time_field],@df)
|
207
|
+
end
|
208
|
+
|
209
|
+
private
|
210
|
+
def snapTimestampToInterval(timestamp,interval)
|
211
|
+
# timestamp & interval are in seconds
|
212
|
+
intervalStart = (timestamp/ interval) * interval
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
def get_value(name, event)
|
217
|
+
val = event[name]
|
218
|
+
case val
|
219
|
+
when Hash
|
220
|
+
return val.to_json
|
221
|
+
else
|
222
|
+
return val
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
private
|
227
|
+
def epochAsJavaDate( epochTimestamp )
|
228
|
+
|
229
|
+
x = 0
|
230
|
+
if epochTimestamp.to_s.length == 13
|
231
|
+
x = java.util.Date.new(epochTimestamp.to_i)
|
232
|
+
else
|
233
|
+
# should be 10
|
234
|
+
x = java.util.Date.new(epochTimestamp.to_i * 1000)
|
235
|
+
end
|
236
|
+
x
|
237
|
+
end
|
238
|
+
|
239
|
+
def formatOutputTime( timestamp, time_field_format, timestamp_output_format, missingString )
|
240
|
+
|
241
|
+
outputString = ""
|
242
|
+
|
243
|
+
begin
|
244
|
+
|
245
|
+
if timestamp.nil? then
|
246
|
+
@logger.debug("SCACSV " + missingString + " for #{group}")
|
247
|
+
elsif timestamp_output_format == "epoch" then
|
248
|
+
outputString = timestamp.to_s
|
249
|
+
elsif timestamp_output_format == "" then
|
250
|
+
# use time_field format
|
251
|
+
if time_field_format == "epoch" then
|
252
|
+
outputString = timestamp.to_s
|
253
|
+
else
|
254
|
+
df = java.text.SimpleDateFormat.new(time_field_format)
|
255
|
+
if (@force_GMT_filenames) then
|
256
|
+
df.setTimeZone(java.util.TimeZone.getTimeZone("GMT"))
|
257
|
+
end
|
258
|
+
outputString = df.format(epochAsJavaDate(timestamp))
|
259
|
+
end
|
260
|
+
else # explicit java timeformat supplied
|
261
|
+
df = java.text.SimpleDateFormat.new(timestamp_output_format)
|
262
|
+
if (@force_GMT_filenames) then
|
263
|
+
df.setTimeZone(java.util.TimeZone.getTimeZone("GMT"))
|
264
|
+
end
|
265
|
+
outputString = df.format(epochAsJavaDate(timestamp))
|
266
|
+
end
|
267
|
+
|
268
|
+
rescue Exception => e
|
269
|
+
@logger.error("Exception determining output file timestamp. " + missingString, :exception => e)
|
270
|
+
outputString = missingString
|
271
|
+
end
|
272
|
+
|
273
|
+
outputString
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
def closeAndRenameCurrentFile
|
278
|
+
|
279
|
+
# cloned and changed from the 'file.rb' operator
|
280
|
+
# even though this is in a loop - assumption is that we have one file here for the SCA CSV use
|
281
|
+
@files.each do |path, fd|
|
282
|
+
begin
|
283
|
+
fd.close
|
284
|
+
@files.delete(path) # so it will be forgotten and we can open it up again if needed
|
285
|
+
@logger.debug("closeAndRenameCurrentFile #{path}", :fd => fd)
|
286
|
+
|
287
|
+
# Now the various time adjustments
|
288
|
+
|
289
|
+
begin # determine start&end times
|
290
|
+
|
291
|
+
if (@time_field_format != "epoch")
|
292
|
+
# if not epoch, then we expect java timestamp format
|
293
|
+
# so must convert start/end times
|
294
|
+
# nStartTime = @df.parse(@startTime)
|
295
|
+
# nEndTime = @df.parse(@endTime)
|
296
|
+
|
297
|
+
# @startTime = @df.parse(@startTime).getTime
|
298
|
+
# @endTime = @df.parse(@endTime).getTime
|
299
|
+
|
300
|
+
# All timestamps are in epoch time now
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
# Ensure epoch time from here on out
|
305
|
+
|
306
|
+
if (!@startTime.nil?)
|
307
|
+
@startTime = @startTime.to_i + @tz_offset
|
308
|
+
end
|
309
|
+
|
310
|
+
if (!@endTime.nil?)
|
311
|
+
@endTime = @endTime.to_i + @tz_offset
|
312
|
+
if (@increment_time)
|
313
|
+
# increment is used to ensure that the end-time on the filename is after the last data value
|
314
|
+
@endTime = @endTime.to_i # times are in seconds + 1000 # 1000ms = 1sec
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# then do conversion for output
|
319
|
+
|
320
|
+
@fileStartTime = formatOutputTime( @startTime, @time_field_format, @timestamp_output_format, "noStartTime" )
|
321
|
+
@fileEndTime = formatOutputTime( @endTime, @time_field_format, @timestamp_output_format, "noEndTime" )
|
322
|
+
|
323
|
+
rescue Exception => e
|
324
|
+
@logger.error("Exception while flushing and closing files - preparing start/end time", :exception => e)
|
325
|
+
raise
|
326
|
+
end
|
327
|
+
|
328
|
+
# timestamps are strings here
|
329
|
+
|
330
|
+
newFilename = "#{group}" + "__" + @fileStartTime + "__" + @fileEndTime + ".csv"
|
331
|
+
|
332
|
+
if newFilename.include? '/'
|
333
|
+
@logger.error("New filename " + newFilename + " cannot contain / characters. Check the timestamp format. / characters stripped from filename")
|
334
|
+
newFilename = newFilename.delete! '/'
|
335
|
+
end
|
336
|
+
|
337
|
+
realdirpath = File.dirname(File.realdirpath("#{path}"))
|
338
|
+
realdirpath = File.dirname(File.realdirpath(path))
|
339
|
+
oldFilename = File.basename(path)
|
340
|
+
|
341
|
+
File.rename(realdirpath + "/" + oldFilename, realdirpath + "/" + newFilename)
|
342
|
+
|
343
|
+
# reset record count so we'll pick up new start time, and put a header on next file
|
344
|
+
# when a new record comes in
|
345
|
+
@recordCount = 0
|
346
|
+
@lastOutputTime = Time.now
|
347
|
+
|
348
|
+
rescue Exception => e
|
349
|
+
@logger.error("Exception while flushing and closing files.", :exception => e)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
end
|
354
|
+
|
355
|
+
def teardown
|
356
|
+
@logger.debug("SCACSV - Teardown: closing files")
|
357
|
+
|
358
|
+
Thread.kill(@timerThread)
|
359
|
+
closeAndRenameCurrentFile
|
360
|
+
|
361
|
+
finished
|
362
|
+
end
|
363
|
+
|
364
|
+
end # class LogStash::Outputs::SCACSV
|
365
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'logstash-output-picsv'
|
3
|
+
s.version = "1.0.5"
|
4
|
+
s.licenses = ["Apache-2.0"]
|
5
|
+
s.summary = "Receives a stream of events and outputs files meeting the csv format for IBM Operation Analytics Predictive Insights"
|
6
|
+
# Need to validate 1.5 standalone gemfile compatibility; gemfile exists!
|
7
|
+
s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
|
8
|
+
s.authors = ["ORIG:Robert Mckeown, Update:Jim Ray"]
|
9
|
+
s.email = "raygj@us.ibm.com"
|
10
|
+
s.homepage = "https://github.com/raygj/logstash-output-picsv/README.md"
|
11
|
+
s.require_paths = ["lib"]
|
12
|
+
|
13
|
+
# Files
|
14
|
+
s.files = `git ls-files`.split($\)
|
15
|
+
# Tests
|
16
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
17
|
+
|
18
|
+
# Special flag to let us know this is actually a logstash plugin
|
19
|
+
s.metadata = { "logstash_plugin" => "true", "logstash_group" => "output" }
|
20
|
+
|
21
|
+
# Gem dependencies
|
22
|
+
s.add_runtime_dependency "logstash-core", ">= 1.5.0", "< 3.0.0"
|
23
|
+
s.add_runtime_dependency "logstash-codec-plain", "~> 0"
|
24
|
+
s.add_development_dependency "logstash-devutils", "~> 0"
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "logstash/devutils/rspec/spec_helper"
|
2
|
+
require "logstash/outputs/base" # changed from /example to /base
|
3
|
+
require "logstash/codecs/plain"
|
4
|
+
require "logstash/event"
|
5
|
+
|
6
|
+
describe LogStash::Outputs::Example do
|
7
|
+
let(:sample_event) { LogStash::Event.new }
|
8
|
+
let(:output) { LogStash::Outputs::Example.new }
|
9
|
+
|
10
|
+
before do
|
11
|
+
output.register
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "receive message" do
|
15
|
+
subject { output.receive(sample_event) }
|
16
|
+
|
17
|
+
it "returns a string" do
|
18
|
+
expect(subject).to eq("Event received")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logstash-output-picsv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ORIG:Robert Mckeown, Update:Jim Ray
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 1.5.0
|
19
|
+
- - "<"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.0
|
22
|
+
name: logstash-core
|
23
|
+
prerelease: false
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.5.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - "~>"
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
name: logstash-codec-plain
|
40
|
+
prerelease: false
|
41
|
+
type: :runtime
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - "~>"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
name: logstash-devutils
|
54
|
+
prerelease: false
|
55
|
+
type: :development
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
|
62
|
+
email: raygj@us.ibm.com
|
63
|
+
executables: []
|
64
|
+
extensions: []
|
65
|
+
extra_rdoc_files: []
|
66
|
+
files:
|
67
|
+
- ".gitignore"
|
68
|
+
- Gemfile
|
69
|
+
- README.md
|
70
|
+
- Rakefile
|
71
|
+
- lib/logstash/outputs/picsv.rb
|
72
|
+
- logstash-output-picsv.gemspec
|
73
|
+
- spec/outputs/picsv_spec.rb
|
74
|
+
homepage: https://github.com/raygj/logstash-output-picsv/README.md
|
75
|
+
licenses:
|
76
|
+
- Apache-2.0
|
77
|
+
metadata:
|
78
|
+
logstash_plugin: 'true'
|
79
|
+
logstash_group: output
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.4.8
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: Receives a stream of events and outputs files meeting the csv format for IBM Operation Analytics Predictive Insights
|
100
|
+
test_files:
|
101
|
+
- spec/outputs/picsv_spec.rb
|