fluent_0.12-plugin-syslog-tls 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,129 @@
1
+ # Configuration
2
+
3
+ This plugin allows to configure all syslog message attributes.
4
+
5
+ ## Static configuration
6
+
7
+ Static configuration allow to define connection details, facility and hostname that will
8
+ apply to all messages.
9
+
10
+ ### host
11
+
12
+ Host represents DNS name of endpoint where should be data sent. Example: `syslog.collection.us1.sumologic.com` or `logs1.papertrailapp.com`
13
+
14
+ ### port
15
+
16
+ Example: `6514`
17
+
18
+ ### ca_cert
19
+
20
+ Whether and how to verify the server's TLS certificate. Examples:
21
+ * ca_cert system - Default; use the system CA certificate store (which must then be configured correctly)
22
+ * ca_cert false - Disable verification; not recommended
23
+ * ca_cert /path/to/file - A path+filename to a single CA file
24
+ * ca_cert /path/to/dir/ - A directory of CA files (in format that OpenSSL can parse); must end with /
25
+
26
+ ### token
27
+
28
+ Some services require a token to identify the account. Example: `ABABABABABABA@99999`. Not required for Papertrail.
29
+
30
+ ### cert
31
+
32
+ Optionally path to client certificate for TLS connection. Example: `/path/to/crt/file.crt`
33
+
34
+ ### key
35
+
36
+ Optionally path to client private key for TLS connection. Example: `/path/to/key/file.key`
37
+
38
+ ### hostname
39
+
40
+ Default hostname that is going to be sent in syslog message. Example: `ip-10-0-0-10`
41
+
42
+ ### facility
43
+
44
+ Default syslog facility for all records. Example: `LOCAL0`
45
+
46
+ ## Per message configuration
47
+
48
+ Its possible to configure the plugin to extract various parts of syslog message header
49
+ from processed record itself. That allows to dynamically set app_name, procid, msgid from
50
+ records if single match is being used to log messages from multiple sources.
51
+
52
+ ### severity_key
53
+
54
+ Optionally record key where to get severity from the record. If not provided default `INFO` will be used.
55
+
56
+ ### facility_key
57
+
58
+ Optionally record key where to get syslog facility from the record. If not provided default `LOCAL0` will be used.
59
+
60
+ ### hostname_key
61
+
62
+ Optionally record key where to get hostname from the record. If not provided hostname is determined by system hostname.
63
+
64
+ ### app_name_key
65
+
66
+ Optionally record key where to get app_name from the record. If not provided nil value will be sent.
67
+
68
+ ### procid_key
69
+
70
+ Optionally record key where to get procid from the record. If not provided nil value will be sent.
71
+
72
+ ### msgid_key
73
+
74
+ Optionally record key where to get msgid from the record. If not provided nil value will be sent.
75
+
76
+ ## Example
77
+
78
+ ```
79
+ <match>
80
+ @type syslog_tls
81
+ host logs1.papertrailapp.com
82
+ port 12345
83
+
84
+ hostname static-hostname
85
+ facility SYSLOG
86
+
87
+ # You can configure syslog headers to be picked from actual message
88
+ # processed by plugin. If key is not provided '-' value will be sent
89
+ # which is NIL by syslog specification.
90
+ severity_key RECORD_SEVERITY_KEY
91
+ facility_key RECORD_FACILITY_KEY
92
+ hostname_key ...
93
+ app_name_key ...
94
+ procid_key ...
95
+ msgid_key ...
96
+
97
+ # Fluent's standard formatting options are supported. Default is 'json'.
98
+ # Example: For Docker logs sent to Papertrail, sending only the log text:
99
+ format single_value
100
+ message_key log
101
+ </match>
102
+ ```
103
+
104
+ ```
105
+ <match>
106
+ @type syslog_tls
107
+ host syslog.collection.us1.sumologic.com
108
+ port 6514
109
+ token [token]@[iana-id]
110
+ cert /path/to/cert/file.crt
111
+ key /path/to/key/file.key
112
+
113
+ hostname static-hostname
114
+ facility SYSLOG
115
+
116
+ # You can configure syslog headers to be picked from actual message
117
+ # processed by plugin. If key is not provided '-' value will be sent
118
+ # which is NIL by syslog specification.
119
+ severity_key RECORD_SEVERITY_KEY
120
+ facility_key RECORD_FACILITY_KEY
121
+ hostname_key ...
122
+ app_name_key ...
123
+ procid_key ...
124
+ msgid_key ...
125
+
126
+ # Fluent's standard formatting options are supported. Default is 'json'.
127
+ format json
128
+ </match>
129
+ ```
@@ -0,0 +1,44 @@
1
+ # Copyright 2016 Acquia, Inc.
2
+ # Copyright 2016 t.e.morgan.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ lib = File.expand_path('../lib', __FILE__)
17
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
18
+ require 'syslog_tls/version'
19
+
20
+ Gem::Specification.new do |s|
21
+ s.name = 'fluent_0.12-plugin-syslog-tls'
22
+ s.version = SyslogTls::VERSION
23
+ s.authors = ['thomas morgan']
24
+ s.email = ['tm@iprog.com']
25
+ s.summary = %q{Fluent Syslog TLS output plugin}
26
+ s.description = %q{Syslog TLS output plugin with formatting support, for Fluentd}
27
+ s.homepage = 'https://github.com/zarqman/fluent-plugin-syslog-tls'
28
+ s.license = 'Apache v2'
29
+ s.files = `git ls-files`.split($/)
30
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
31
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
32
+ s.require_paths = ['lib']
33
+ s.required_ruby_version = '>= 2.0.0'
34
+
35
+ s.add_runtime_dependency 'fluentd', '~> 0.12.0'
36
+ s.add_runtime_dependency 'fluent-mixin-config-placeholders', '~> 0.3'
37
+
38
+ s.add_development_dependency 'minitest', '~> 5.8'
39
+ s.add_development_dependency 'minitest-stub_any_instance', '~> 1.0.0'
40
+ s.add_development_dependency 'rake', '~> 10.5'
41
+ s.add_development_dependency 'test-unit', '~> 3.1'
42
+ s.add_development_dependency 'webmock', '~> 2.0'
43
+ s.add_development_dependency 'simplecov', '~> 0.11'
44
+ end
@@ -0,0 +1,134 @@
1
+ # Copyright 2016 Acquia, Inc.
2
+ # Copyright 2016 t.e.morgan.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'fluent/mixin/config_placeholders'
17
+ require 'socket'
18
+
19
+ module Fluent
20
+ class SyslogTlsOutput < Fluent::Output
21
+ Fluent::Plugin.register_output('syslog_tls', self)
22
+
23
+ include Fluent::Mixin::ConfigPlaceholders
24
+ include Fluent::HandleTagNameMixin
25
+
26
+ DEFAULT_FORMAT_TYPE = 'json'
27
+
28
+ config_param :host, :string
29
+ config_param :port, :integer
30
+ config_param :ca_cert, :string, default: 'system'
31
+ config_param :token, :string, :default => nil
32
+ config_param :cert, :string, :default => nil
33
+ config_param :key, :string, :default => nil
34
+ config_param :hostname, :string, :default => nil
35
+ config_param :facility, :string, :default => 'LOCAL0'
36
+
37
+ # Allow to map keys from record to syslog message headers
38
+ SYSLOG_HEADERS = [
39
+ :severity, :facility, :hostname, :app_name, :procid, :msgid
40
+ ]
41
+
42
+ SYSLOG_HEADERS.each do |key_name|
43
+ config_param "#{key_name}_key".to_sym, :string, :default => nil
44
+ end
45
+
46
+ config_param :format, :string, default: DEFAULT_FORMAT_TYPE
47
+
48
+
49
+ def initialize
50
+ super
51
+ require 'syslog_tls/logger'
52
+ @loggers = {}
53
+ end
54
+
55
+ def shutdown
56
+ super
57
+ @loggers.values.each(&:close)
58
+ end
59
+
60
+ # This method is called before starting.
61
+ def configure(conf)
62
+ super
63
+ @host = conf['host']
64
+ @port = conf['port']
65
+ @token = conf['token']
66
+ @hostname = conf['hostname'] || Socket.gethostname.split('.').first
67
+
68
+ # Determine mapping of record keys to syslog keys
69
+ @mappings = {}
70
+ SYSLOG_HEADERS.each do |key_name|
71
+ conf_key = "#{key_name}_key"
72
+ @mappings[key_name] = conf[conf_key] if conf.key?(conf_key)
73
+ end
74
+
75
+ @formatter = Plugin.new_formatter(@format)
76
+ @formatter.configure(conf)
77
+ end
78
+
79
+ # Get logger for given tag
80
+ def logger(tag)
81
+ # Try to reuse existing logger
82
+ @loggers[tag] ||= new_logger(tag)
83
+
84
+ # Create new logger if old one is closed
85
+ if @loggers[tag].closed?
86
+ @loggers[tag] = new_logger(tag)
87
+ end
88
+
89
+ @loggers[tag]
90
+ end
91
+
92
+ def new_logger(tag)
93
+ transport = ::SyslogTls::SSLTransport.new(host, port, ca_cert: ca_cert, cert: cert, key: key, max_retries: 3)
94
+ logger = ::SyslogTls::Logger.new(transport, token)
95
+ logger.facility(facility)
96
+ logger.hostname(hostname)
97
+ logger.app_name(tag)
98
+ logger
99
+ end
100
+
101
+ def format(tag, time, record)
102
+ @formatter.format(tag, time, record)
103
+ end
104
+
105
+ def emit(tag, es, chain)
106
+ chain.next
107
+ es.each do |time, record|
108
+ record.each_pair do |_, v|
109
+ v.force_encoding('utf-8') if v.is_a?(String)
110
+ end
111
+
112
+ # Check if severity has been provided in record otherwise use INFO
113
+ # by default.
114
+ severity = if @mappings.key?(:severity)
115
+ record[@mappings[:severity]] || 'INFO'
116
+ else
117
+ 'INFO'
118
+ end
119
+
120
+ # Send message to Syslog
121
+ begin
122
+ logger(tag).log(severity, format(tag, time, record), time: Time.at(time)) do |header|
123
+ # Map syslog headers from record
124
+ @mappings.each do |name, record_key|
125
+ header.send("#{name}=", record[record_key]) unless record[record_key].nil?
126
+ end
127
+ end
128
+ rescue => e
129
+ log.error e.to_s
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,46 @@
1
+ # Copyright 2016 Acquia, Inc.
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.
14
+
15
+ require_relative 'lookup_from_const'
16
+
17
+ module SyslogTls
18
+ module Facility
19
+ extend LookupFromConst
20
+ KERN = 0
21
+ USER = 1
22
+ MAIL = 2
23
+ DAEMON = 3
24
+ AUTH = 4
25
+ SYSLOG = 5
26
+ LPR = 6
27
+ NEWS = 7
28
+ UUCP = 8
29
+ CRON = 9
30
+ AUTHPRIV = 10
31
+ FTP = 11
32
+ NTP = 12
33
+ SECURITY = 13
34
+ CONSOLE = 14
35
+ RAS = 15
36
+ LOCAL0 = 16
37
+ LOCAL1 = 17
38
+ LOCAL2 = 18
39
+ LOCAL3 = 19
40
+ LOCAL4 = 20
41
+ LOCAL5 = 21
42
+ LOCAL6 = 22
43
+ LOCAL7 = 23
44
+ NONE = SYSLOG
45
+ end
46
+ end
@@ -0,0 +1,82 @@
1
+ # Copyright 2016 Acquia, Inc.
2
+ # Copyright 2016 t.e.morgan.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require_relative 'protocol'
17
+ require_relative 'ssl_transport'
18
+
19
+ module SyslogTls
20
+ class Logger
21
+ attr_reader :token
22
+ attr_accessor :transport
23
+
24
+ # Logger accepts transport which should implement IO methods
25
+ # close, closed? and write
26
+ def initialize(transport, token=nil)
27
+ @transport = transport
28
+ @default_header = SyslogTls::Header.new
29
+ @default_structured_data = SyslogTls::StructuredData.new(token)
30
+ end
31
+
32
+ # Sets default facility for each message
33
+ def facility(val)
34
+ @default_header.facility = val
35
+ end
36
+
37
+ # Sets default hostname for each message
38
+ def hostname(val)
39
+ @default_header.hostname = val
40
+ end
41
+
42
+ # Sets default app_name for each message
43
+ def app_name(val)
44
+ @default_header.app_name = val
45
+ end
46
+
47
+ # Sets default procid for message
48
+ def procid(val)
49
+ @default_header.procid = val
50
+ end
51
+
52
+ # Check if IO is closed
53
+ def closed?
54
+ transport && transport.closed?
55
+ end
56
+
57
+ def close
58
+ transport.close
59
+ end
60
+
61
+ # Send log message with severity to syslog
62
+ def log(severity, message, time: nil)
63
+ time ||= Time.now
64
+
65
+ m = SyslogTls::Message.new
66
+
67
+ # Include authentication header
68
+ m.structured_data << @default_structured_data
69
+
70
+ # Adjust header with current timestamp and severity
71
+ m.header = @default_header.dup
72
+ m.header.severity = severity
73
+ m.header.timestamp = time
74
+
75
+ yield m.header if block_given?
76
+
77
+ m.msg = message
78
+
79
+ transport.write(m.to_s)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,36 @@
1
+ # Copyright 2016 Acquia, Inc.
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.
14
+
15
+ module SyslogTls
16
+ module LookupFromConst
17
+ def setup_constants(dst)
18
+ constants.each do |pri|
19
+ cval = const_get pri
20
+
21
+ dst[pri] = cval
22
+ dst[pri.downcase] = cval
23
+
24
+ dst[:"LOG_#{pri.to_s}"] = cval
25
+ dst[:"LOG_#{pri.downcase.to_s}"] = cval
26
+ const_set :"LOG_#{pri.to_s}", cval
27
+
28
+ dst[pri.to_s] = cval
29
+ dst[pri.downcase.to_s] = cval
30
+
31
+ dst[cval] = cval
32
+ dst[cval.to_s] = cval
33
+ end
34
+ end
35
+ end
36
+ end