logstash-output-file 2.0.2 → 2.1.0
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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +3 -0
- data/lib/logstash/outputs/file.rb +33 -7
- data/logstash-output-file.gemspec +1 -1
- data/spec/outputs/file_spec.rb +53 -0
- metadata +17 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34e5dcb5b4862273a9cc92f1c4ab73235db7df4a
|
4
|
+
data.tar.gz: 802613ca119351bcb1970d3ec96efa52c18b6a38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab71908733217054a01c5688cd3a31a6257350440440ba4885d7ac15a8404207b7fd2b19b067790541fd6db40d5e99e3b7cfd9173fc82f3b38c16daa4d4b4f76
|
7
|
+
data.tar.gz: 798c54d4b133f2aed3dba737254dc2807ad3d6f0253a2ae6e06e8b51bee5e7b691415532cab396868b60959a6c92c84ba1eb4424786fccf7a4b978914c338a36
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 2.1.0
|
2
|
+
- Add create_if_deleted option to create a destination file in case it
|
3
|
+
was deleted by another agent in the machine. In case of being false
|
4
|
+
the system will add the incomming messages to the failure file.
|
5
|
+
|
1
6
|
## 2.0.0
|
2
7
|
- Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
|
3
8
|
instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Logstash Plugin
|
2
2
|
|
3
|
+
[](http://build-eu-00.elastic.co/view/LS%20Plugins/view/LS%20Outputs/job/logstash-plugin-output-file-unit/)
|
5
|
+
|
3
6
|
This is a plugin for [Logstash](https://github.com/elastic/logstash).
|
4
7
|
|
5
8
|
It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
|
@@ -11,6 +11,8 @@ class LogStash::Outputs::File < LogStash::Outputs::Base
|
|
11
11
|
|
12
12
|
config_name "file"
|
13
13
|
|
14
|
+
attr_reader :failure_path
|
15
|
+
|
14
16
|
# The path to the file to write. Event fields can be used here,
|
15
17
|
# like `/var/log/logstash/%{host}/%{application}`
|
16
18
|
# One may also utilize the path option for date-based log
|
@@ -42,6 +44,11 @@ class LogStash::Outputs::File < LogStash::Outputs::Base
|
|
42
44
|
# into this file and inside the defined path.
|
43
45
|
config :filename_failure, :validate => :string, :default => '_filepath_failures'
|
44
46
|
|
47
|
+
# If the a file is deleted, but an event is comming with the need to be stored
|
48
|
+
# in such a file, the plugin will created a gain this file. Default => true
|
49
|
+
config :create_if_deleted, :validate => :boolean, :default => true
|
50
|
+
|
51
|
+
|
45
52
|
public
|
46
53
|
def register
|
47
54
|
require "fileutils" # For mkdir_p
|
@@ -56,8 +63,10 @@ class LogStash::Outputs::File < LogStash::Outputs::Base
|
|
56
63
|
|
57
64
|
if path_with_field_ref?
|
58
65
|
@file_root = extract_file_root
|
59
|
-
|
66
|
+
else
|
67
|
+
@file_root = File.dirname(path)
|
60
68
|
end
|
69
|
+
@failure_path = File.join(@file_root, @filename_failure)
|
61
70
|
|
62
71
|
now = Time.now
|
63
72
|
@last_flush_cycle = now
|
@@ -87,13 +96,14 @@ class LogStash::Outputs::File < LogStash::Outputs::Base
|
|
87
96
|
|
88
97
|
public
|
89
98
|
def receive(event)
|
90
|
-
|
91
99
|
|
92
100
|
file_output_path = generate_filepath(event)
|
93
101
|
|
94
102
|
if path_with_field_ref? && !inside_file_root?(file_output_path)
|
95
103
|
@logger.warn("File: the event tried to write outside the files root, writing the event to the failure file", :event => event, :filename => @failure_path)
|
96
104
|
file_output_path = @failure_path
|
105
|
+
elsif !@create_if_deleted && deleted?(file_output_path)
|
106
|
+
file_output_path = @failure_path
|
97
107
|
end
|
98
108
|
|
99
109
|
output = format_message(event)
|
@@ -123,7 +133,6 @@ class LogStash::Outputs::File < LogStash::Outputs::Base
|
|
123
133
|
def write_event(log_path, event)
|
124
134
|
@logger.debug("File, writing event to file.", :filename => log_path)
|
125
135
|
fd = open(log_path)
|
126
|
-
|
127
136
|
# TODO(sissel): Check if we should rotate the file.
|
128
137
|
|
129
138
|
fd.write(event)
|
@@ -198,9 +207,27 @@ class LogStash::Outputs::File < LogStash::Outputs::Base
|
|
198
207
|
end
|
199
208
|
|
200
209
|
private
|
201
|
-
def
|
202
|
-
|
210
|
+
def cached?(path)
|
211
|
+
@files.include?(path) && !@files[path].nil?
|
212
|
+
end
|
203
213
|
|
214
|
+
private
|
215
|
+
def deleted?(path)
|
216
|
+
!File.exist?(path)
|
217
|
+
end
|
218
|
+
|
219
|
+
private
|
220
|
+
def open(path)
|
221
|
+
if !deleted?(path) && cached?(path)
|
222
|
+
return @files[path]
|
223
|
+
elsif deleted?(path)
|
224
|
+
if @create_if_deleted
|
225
|
+
@logger.debug("Required path was deleted, creating the file again", :path => path)
|
226
|
+
@files.delete(path)
|
227
|
+
else
|
228
|
+
return @files[path] if cached?(path)
|
229
|
+
end
|
230
|
+
end
|
204
231
|
@logger.info("Opening file", :path => path)
|
205
232
|
|
206
233
|
dir = File.dirname(path)
|
@@ -208,13 +235,12 @@ class LogStash::Outputs::File < LogStash::Outputs::Base
|
|
208
235
|
@logger.info("Creating directory", :directory => dir)
|
209
236
|
FileUtils.mkdir_p(dir)
|
210
237
|
end
|
211
|
-
|
212
238
|
# work around a bug opening fifos (bug JRUBY-6280)
|
213
239
|
stat = File.stat(path) rescue nil
|
214
240
|
if stat && stat.ftype == "fifo" && LogStash::Environment.jruby?
|
215
241
|
fd = java.io.FileWriter.new(java.io.File.new(path))
|
216
242
|
else
|
217
|
-
fd = File.new(path, "a")
|
243
|
+
fd = File.new(path, "a+")
|
218
244
|
end
|
219
245
|
if gzip
|
220
246
|
fd = Zlib::GzipWriter.new(fd)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-output-file'
|
4
|
-
s.version = '2.0
|
4
|
+
s.version = '2.1.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "This output will write events to files on disk"
|
7
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"
|
data/spec/outputs/file_spec.rb
CHANGED
@@ -6,6 +6,7 @@ require "logstash/json"
|
|
6
6
|
require "stud/temporary"
|
7
7
|
require "tempfile"
|
8
8
|
require "uri"
|
9
|
+
require "fileutils"
|
9
10
|
|
10
11
|
describe LogStash::Outputs::File do
|
11
12
|
describe "ship lots of events to a file" do
|
@@ -106,6 +107,58 @@ describe LogStash::Outputs::File do
|
|
106
107
|
end
|
107
108
|
|
108
109
|
describe "receiving events" do
|
110
|
+
|
111
|
+
context "when the output file is deleted" do
|
112
|
+
|
113
|
+
let(:temp_file) { Tempfile.new('logstash-spec-output-file_deleted') }
|
114
|
+
|
115
|
+
let(:config) do
|
116
|
+
{ "path" => temp_file.path, "flush_interval" => 0 }
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should recreate the required file if deleted" do
|
120
|
+
output = LogStash::Outputs::File.new(config)
|
121
|
+
output.register
|
122
|
+
|
123
|
+
10.times do |i|
|
124
|
+
event = LogStash::Event.new("event_id" => i)
|
125
|
+
output.receive(event)
|
126
|
+
end
|
127
|
+
FileUtils.rm(temp_file)
|
128
|
+
10.times do |i|
|
129
|
+
event = LogStash::Event.new("event_id" => i+10)
|
130
|
+
output.receive(event)
|
131
|
+
end
|
132
|
+
expect(FileTest.size(temp_file.path)).to be > 0
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when appending to the error log" do
|
136
|
+
|
137
|
+
let(:config) do
|
138
|
+
{ "path" => temp_file.path, "flush_interval" => 0, "create_if_deleted" => false }
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should append the events to the filename_failure location" do
|
142
|
+
output = LogStash::Outputs::File.new(config)
|
143
|
+
output.register
|
144
|
+
|
145
|
+
10.times do |i|
|
146
|
+
event = LogStash::Event.new("event_id" => i)
|
147
|
+
output.receive(event)
|
148
|
+
end
|
149
|
+
FileUtils.rm(temp_file)
|
150
|
+
10.times do |i|
|
151
|
+
event = LogStash::Event.new("event_id" => i+10)
|
152
|
+
output.receive(event)
|
153
|
+
end
|
154
|
+
expect(FileTest.exist?(temp_file.path)).to be_falsey
|
155
|
+
expect(FileTest.size(output.failure_path)).to be > 0
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
109
162
|
context "when using an interpolated path" do
|
110
163
|
context "when trying to write outside the files root directory" do
|
111
164
|
let(:bad_event) do
|
metadata
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-output-file
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.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: 2015-
|
11
|
+
date: 2015-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
|
14
|
+
name: logstash-core
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
15
16
|
requirements:
|
16
17
|
- - '>='
|
17
18
|
- !ruby/object:Gem::Version
|
@@ -19,10 +20,7 @@ dependencies:
|
|
19
20
|
- - <
|
20
21
|
- !ruby/object:Gem::Version
|
21
22
|
version: 3.0.0
|
22
|
-
|
23
|
-
prerelease: false
|
24
|
-
type: :runtime
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirement: !ruby/object:Gem::Requirement
|
26
24
|
requirements:
|
27
25
|
- - '>='
|
28
26
|
- !ruby/object:Gem::Version
|
@@ -30,34 +28,36 @@ dependencies:
|
|
30
28
|
- - <
|
31
29
|
- !ruby/object:Gem::Version
|
32
30
|
version: 3.0.0
|
31
|
+
prerelease: false
|
32
|
+
type: :runtime
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
+
name: logstash-input-generator
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
34
40
|
requirement: !ruby/object:Gem::Requirement
|
35
41
|
requirements:
|
36
42
|
- - '>='
|
37
43
|
- !ruby/object:Gem::Version
|
38
44
|
version: '0'
|
39
|
-
name: logstash-input-generator
|
40
45
|
prerelease: false
|
41
46
|
type: :runtime
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: logstash-devutils
|
42
49
|
version_requirements: !ruby/object:Gem::Requirement
|
43
50
|
requirements:
|
44
51
|
- - '>='
|
45
52
|
- !ruby/object:Gem::Version
|
46
53
|
version: '0'
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
54
|
requirement: !ruby/object:Gem::Requirement
|
49
55
|
requirements:
|
50
56
|
- - '>='
|
51
57
|
- !ruby/object:Gem::Version
|
52
58
|
version: '0'
|
53
|
-
name: logstash-devutils
|
54
59
|
prerelease: false
|
55
60
|
type: :development
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - '>='
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: '0'
|
61
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
62
|
email: info@elastic.co
|
63
63
|
executables: []
|
@@ -95,9 +95,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
95
|
version: '0'
|
96
96
|
requirements: []
|
97
97
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.4.
|
98
|
+
rubygems_version: 2.4.6
|
99
99
|
signing_key:
|
100
100
|
specification_version: 4
|
101
101
|
summary: This output will write events to files on disk
|
102
102
|
test_files:
|
103
103
|
- spec/outputs/file_spec.rb
|
104
|
+
has_rdoc:
|