fluent-plugin-bin 0.1
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/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +65 -0
- data/fluent-plugin-bin.gemspec +15 -0
- data/lib/fluent/plugin/in_bin.rb +164 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cb3e6c6f8011ebabd99c18bce4c692265daae3af
|
4
|
+
data.tar.gz: ef3f2083ef9c77f90935ed411221f0cc9b70a6d7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 80d047db3a9ff73548444db5be839e85153a53d7cecc5e959583164ce5979b012700cb12445dfb691b5c4e805fea611d0934ba5ff52c2a78b56934fc1195943c
|
7
|
+
data.tar.gz: 5ab88e6341f9249f7cd026a64bc1ddd24425c0456ad9ada238d791335fcdb0a6c230422a584e08acb7c3c4fb557fb68bc2e7c00bb0de4838d7c0bc96a27f2997
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (C) 2015 Nexedi SA and Contributors
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
fluent-plugin-bin
|
2
|
+
====================
|
3
|
+
|
4
|
+
[Fluentd][] input plugin for binary files based on in_tail.
|
5
|
+
|
6
|
+
Usage Example
|
7
|
+
=============
|
8
|
+
|
9
|
+
This exmaple shows how to install and configure fluent-plugin-bin together
|
10
|
+
with fluent-plugin wendelin output plugin to ingest binary files into
|
11
|
+
[Wendelin][] on Ubuntu 14.04.4 LTS.
|
12
|
+
|
13
|
+
sudo apt-get install supervisor
|
14
|
+
sudo service supervisor restart
|
15
|
+
sudo apt-get install python-software-properties
|
16
|
+
sudo apt-add-repository ppa:brightbox/ruby-ng
|
17
|
+
sudo apt-get update
|
18
|
+
sudo apt-get install ruby2.0 ruby2.0-dev make
|
19
|
+
sudo gem install fluentd --no-ri --no-rdoc
|
20
|
+
sudo mkdir -p /etc/fluent/plugin
|
21
|
+
cd /etc/fluent/plugin
|
22
|
+
sudo wget https://lab.nexedi.com/nexedi/fluent-plugin-bin/raw/master/lib/fluent/plugin/in_bin.rb
|
23
|
+
sudo wget https://lab.nexedi.cn/nexedi/fluent-plugin-wendelin/raw/master/lib/fluent/plugin/out_wendelin.rb
|
24
|
+
sudo wget https://lab.nexedi.cn/nexedi/fluent-plugin-wendelin/raw/master/lib/fluent/plugin/wendelin_client.rb
|
25
|
+
|
26
|
+
Create /etc/fluent/fluentd.conf:
|
27
|
+
|
28
|
+
<source>
|
29
|
+
@type bin
|
30
|
+
format none
|
31
|
+
path /path/to/files/*.ext
|
32
|
+
pos_file /mic/upload.pos
|
33
|
+
enable_watch_timer false
|
34
|
+
read_from_head true
|
35
|
+
tag my_prefix.*
|
36
|
+
</source>
|
37
|
+
|
38
|
+
<match my_prefix.path.to.files.*.ext>
|
39
|
+
@type wendelin
|
40
|
+
@id wendelin_out
|
41
|
+
|
42
|
+
streamtool_uri https://wendelin_url/portal_ingestion_policies/my_policy
|
43
|
+
user my_user_name
|
44
|
+
password my_password
|
45
|
+
|
46
|
+
buffer_type memory
|
47
|
+
flush_interval 1s
|
48
|
+
disable_retry_limit true
|
49
|
+
</match>
|
50
|
+
|
51
|
+
Create /etc/supervisor/conf.d/fluentd.conf:
|
52
|
+
|
53
|
+
[program:fluentd]
|
54
|
+
command=/usr/local/bin/fluentd
|
55
|
+
autostart=true
|
56
|
+
autorestart=true
|
57
|
+
stderr_logfile=/var/log/fluentd.log
|
58
|
+
stdout_logfile=/var/log/fluentd.log
|
59
|
+
|
60
|
+
Start fluentd:
|
61
|
+
|
62
|
+
sudo supervisorctl start fluentd
|
63
|
+
|
64
|
+
[Fluentd]: http://fluentd.org
|
65
|
+
[Wendelin]: http://www.wendelin.io
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Gem::Specification.new do |gem|
|
2
|
+
gem.name = "fluent-plugin-bin"
|
3
|
+
gem.version = "0.1"
|
4
|
+
gem.authors = ["Klaus Wölfel"]
|
5
|
+
gem.email = ["klaus@nexedi.com"]
|
6
|
+
gem.summary = %q{Fluentd input plugin for binary files}
|
7
|
+
gem.description = %q{Fluentd input plugin to read binary files based on in_tail}
|
8
|
+
gem.homepage = "https://lab.nexedi.com/klaus/fluent-plugin-bin"
|
9
|
+
gem.license = "APLv2"
|
10
|
+
|
11
|
+
gem.files = `git ls-files -z`.split("\x0")
|
12
|
+
gem.require_paths = ["lib"]
|
13
|
+
|
14
|
+
gem.add_runtime_dependency "fluentd", "~> 0.12"
|
15
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# Fluentd input plugin for general hardware monitoring
|
2
|
+
# Copyright (C) 2016 Nexedi SA and Contributors.
|
3
|
+
# Klaus Wölfel <klaus@nexedi.com>
|
4
|
+
#
|
5
|
+
# This program is free software: you can Use, Study, Modify and Redistribute
|
6
|
+
# it under the terms of the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require 'fluent/input'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
|
22
|
+
class BinInput < NewTailInput
|
23
|
+
Plugin.register_input('bin', self)
|
24
|
+
|
25
|
+
def convert_line_to_event(line, es, tail_watcher)
|
26
|
+
begin
|
27
|
+
es.add(nil, line)
|
28
|
+
rescue => e
|
29
|
+
log.warn line.dump, error: e.to_s
|
30
|
+
log.debug_backtrace(e.backtrace)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def setup_watcher(path, pe)
|
35
|
+
line_buffer_timer_flusher = (@multiline_mode && @multiline_flush_interval) ? TailWatcher::LineBufferTimerFlusher.new(log, @multiline_flush_interval, &method(:flush_buffer)) : nil
|
36
|
+
tw = TailWatcher.new(path, @rotate_wait, pe, log, @read_from_head, @enable_watch_timer, @read_lines_limit, method(:update_watcher), line_buffer_timer_flusher, &method(:receive_lines))
|
37
|
+
tw.attach(@loop)
|
38
|
+
tw
|
39
|
+
end
|
40
|
+
|
41
|
+
class TailWatcher < NewTailInput::TailWatcher
|
42
|
+
def on_rotate(io)
|
43
|
+
if @io_handler == nil
|
44
|
+
if io
|
45
|
+
# first time
|
46
|
+
stat = io.stat
|
47
|
+
fsize = stat.size
|
48
|
+
inode = stat.ino
|
49
|
+
|
50
|
+
last_inode = @pe.read_inode
|
51
|
+
if inode == last_inode
|
52
|
+
# rotated file has the same inode number with the last file.
|
53
|
+
# assuming following situation:
|
54
|
+
# a) file was once renamed and backed, or
|
55
|
+
# b) symlink or hardlink to the same file is recreated
|
56
|
+
# in either case, seek to the saved position
|
57
|
+
pos = @pe.read_pos
|
58
|
+
elsif last_inode != 0
|
59
|
+
# this is FilePositionEntry and fluentd once started.
|
60
|
+
# read data from the head of the rotated file.
|
61
|
+
# logs never duplicate because this file is a rotated new file.
|
62
|
+
pos = 0
|
63
|
+
@pe.update(inode, pos)
|
64
|
+
else
|
65
|
+
# this is MemoryPositionEntry or this is the first time fluentd started.
|
66
|
+
# seek to the end of the any files.
|
67
|
+
# logs may duplicate without this seek because it's not sure the file is
|
68
|
+
# existent file or rotated new file.
|
69
|
+
pos = @read_from_head ? 0 : fsize
|
70
|
+
@pe.update(inode, pos)
|
71
|
+
end
|
72
|
+
io.seek(pos)
|
73
|
+
|
74
|
+
@io_handler = IOHandler.new(io, @pe, @log, @read_lines_limit, &method(:wrap_receive_lines))
|
75
|
+
else
|
76
|
+
@io_handler = NullIOHandler.new
|
77
|
+
end
|
78
|
+
else
|
79
|
+
log_msg = "detected rotation of #{@path}"
|
80
|
+
log_msg << "; waiting #{@rotate_wait} seconds" if @io_handler.io # wait rotate_time if previous file is exist
|
81
|
+
@log.info log_msg
|
82
|
+
|
83
|
+
if io
|
84
|
+
stat = io.stat
|
85
|
+
inode = stat.ino
|
86
|
+
if inode == @pe.read_inode # truncated
|
87
|
+
@pe.update_pos(stat.size)
|
88
|
+
io_handler = IOHandler.new(io, @pe, @log, @read_lines_limit, &method(:wrap_receive_lines))
|
89
|
+
@io_handler.close
|
90
|
+
@io_handler = io_handler
|
91
|
+
elsif @io_handler.io.nil? # There is no previous file. Reuse TailWatcher
|
92
|
+
@pe.update(inode, io.pos)
|
93
|
+
io_handler = IOHandler.new(io, @pe, @log, @read_lines_limit, &method(:wrap_receive_lines))
|
94
|
+
@io_handler = io_handler
|
95
|
+
else # file is rotated and new file found
|
96
|
+
@update_watcher.call(@path, swap_state(@pe))
|
97
|
+
end
|
98
|
+
else # file is rotated and new file not found
|
99
|
+
# Clear RotateHandler to avoid duplicated file watch in same path.
|
100
|
+
@rotate_handler = nil
|
101
|
+
@update_watcher.call(@path, swap_state(@pe))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def swap_state(pe)
|
106
|
+
# Use MemoryPositionEntry for rotated file temporary
|
107
|
+
mpe = MemoryPositionEntry.new
|
108
|
+
mpe.update(pe.read_inode, pe.read_pos)
|
109
|
+
@pe = mpe
|
110
|
+
@io_handler.pe = mpe # Don't re-create IOHandler because IOHandler has an internal buffer.
|
111
|
+
|
112
|
+
pe # This pe will be updated in on_rotate after TailWatcher is initialized
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class IOHandler < NewTailInput::TailWatcher::IOHandler
|
117
|
+
def initialize(io, pe, log, read_lines_limit, first = true, &receive_lines)
|
118
|
+
@log = log
|
119
|
+
@log.info "following #{io.path}" if first
|
120
|
+
@io = io
|
121
|
+
@pe = pe
|
122
|
+
@read_lines_limit = read_lines_limit
|
123
|
+
@receive_lines = receive_lines
|
124
|
+
@lines = []
|
125
|
+
@io.binmode
|
126
|
+
end
|
127
|
+
|
128
|
+
def on_notify
|
129
|
+
begin
|
130
|
+
read_more = false
|
131
|
+
|
132
|
+
if @lines.empty?
|
133
|
+
begin
|
134
|
+
while true
|
135
|
+
@lines << @io.readpartial(2048)
|
136
|
+
if @lines.size >= @read_lines_limit
|
137
|
+
# not to use too much memory in case the file is very large
|
138
|
+
read_more = true
|
139
|
+
break
|
140
|
+
end
|
141
|
+
end
|
142
|
+
rescue EOFError
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
unless @lines.empty?
|
147
|
+
if @receive_lines.call(@lines)
|
148
|
+
@pe.update_pos(@io.pos)
|
149
|
+
@lines.clear
|
150
|
+
else
|
151
|
+
read_more = false
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end while read_more
|
155
|
+
|
156
|
+
rescue
|
157
|
+
@log.error $!.to_s
|
158
|
+
@log.error_backtrace
|
159
|
+
close
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-bin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Klaus Wölfel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fluentd
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.12'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.12'
|
27
|
+
description: Fluentd input plugin to read binary files based on in_tail
|
28
|
+
email:
|
29
|
+
- klaus@nexedi.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- Gemfile
|
35
|
+
- LICENSE.txt
|
36
|
+
- README.md
|
37
|
+
- fluent-plugin-bin.gemspec
|
38
|
+
- lib/fluent/plugin/in_bin.rb
|
39
|
+
homepage: https://lab.nexedi.com/klaus/fluent-plugin-bin
|
40
|
+
licenses:
|
41
|
+
- APLv2
|
42
|
+
metadata: {}
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 2.0.14.1
|
60
|
+
signing_key:
|
61
|
+
specification_version: 4
|
62
|
+
summary: Fluentd input plugin for binary files
|
63
|
+
test_files: []
|