logstash-input-log4j2 3.3

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a661a6d6ca3ab8b8119af6dc0ede5d3977d4343e
4
+ data.tar.gz: c578297e13d1ae750263659bbd2142be3ecf4219
5
+ SHA512:
6
+ metadata.gz: f822314505321950760711fd20d195fe7cbc5d8c0fffaede6f544237fb22a864ec7beaa50b726f93ea0c84c46a0e0134caba5b8262f952216ce6213bde56e092
7
+ data.tar.gz: dbccd7ff2fa7aadc4d9456e5fe9bc188e447ebb05b3591372b097e4f94ade4a3a68ae34121e9773f5f3634db156ec3a307a9a18237a185e579592c8c1f7a211b
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem "logstash", :github => "elasticsearch/logstash", :branch => "1.5"
@@ -0,0 +1,53 @@
1
+ logstash-log4j2
2
+ ===============
3
+
4
+ Log4j2 plugin for logstash.
5
+
6
+ Supported Log4J2 versions:
7
+ -----
8
+ Version: 2.0 (And probably newer 2.x releases)
9
+
10
+ Get the plugin
11
+ ----
12
+ Download the latest release at: https://github.com/jurmous/logstash-log4j2/releases and unzip it.
13
+
14
+ Setup log4j2
15
+ ------------
16
+
17
+ Set log4j2.xml in your project
18
+ ```xml
19
+ <?xml version="1.0" encoding="UTF-8"?>
20
+ <Configuration>
21
+ <Appenders>
22
+ <Socket name="A1" host="localHost" port="7000">
23
+ <SerializedLayout />
24
+ </Socket>
25
+ </Appenders>
26
+ <Loggers>
27
+ <Root level="debug">
28
+ <AppenderRef ref="A1"/>
29
+ </Root>
30
+ </Loggers>
31
+ </Configuration>
32
+ ```
33
+
34
+ Setup logstash
35
+ -----
36
+
37
+ ```
38
+ input {
39
+ log4j2 {
40
+ port => 7000
41
+ mode => "server"
42
+ }
43
+ }
44
+
45
+ output {
46
+ stdout { codec => rubydebug }
47
+ }
48
+ ```
49
+
50
+ Run logstash with the plugin
51
+ -------------
52
+
53
+ Run from your logstash install directory `./bin/logstash --pluginpath PATH_TO_PLUGIN -f YOUR_CONF.conf`
@@ -0,0 +1,8 @@
1
+ @files=[
2
+ ]
3
+
4
+ task :default do
5
+ system("rake -T")
6
+ end
7
+
8
+ require "logstash/devutils/rake"
@@ -0,0 +1,167 @@
1
+ # encoding: utf-8
2
+ require "logstash/inputs/base"
3
+ require "logstash/errors"
4
+ require "logstash/environment"
5
+ require "logstash/namespace"
6
+ require "logstash/util/socket_peer"
7
+ require "socket"
8
+ require "timeout"
9
+
10
+ # Read events over a TCP socket from a Log4j2 SocketAppender.
11
+ #
12
+ # Can either accept connections from clients or connect to a server,
13
+ # depending on `mode`. Depending on which `mode` is configured,
14
+ # you need a matching SocketAppender or a SocketHubAppender
15
+ # on the remote side.
16
+ class LogStash::Inputs::Log4j2 < LogStash::Inputs::Base
17
+
18
+ config_name "log4j2"
19
+ milestone 1
20
+
21
+ # When mode is `server`, the address to listen on.
22
+ # When mode is `client`, the address to connect to.
23
+ config :host, :validate => :string, :default => "0.0.0.0"
24
+
25
+ # When mode is `server`, the port to listen on.
26
+ # When mode is `client`, the port to connect to.
27
+ config :port, :validate => :number, :default => 4560
28
+
29
+ # Read timeout in seconds. If a particular TCP connection is
30
+ # idle for more than this timeout period, we will assume
31
+ # it is dead and close it.
32
+ # If you never want to timeout, use -1.
33
+ config :data_timeout, :validate => :number, :default => 5
34
+
35
+ # Mode to operate in. `server` listens for client connections,
36
+ # `client` connects to a server.
37
+ config :mode, :validate => ["server", "client"], :default => "server"
38
+
39
+ def initialize(*args)
40
+ super(*args)
41
+ end # def initialize
42
+
43
+ public
44
+ def register
45
+ require "java"
46
+ require "jruby/serialization"
47
+
48
+ begin
49
+ if __FILE__ !~ /^(jar:)?file:\/\//
50
+ if File.exists?(File.dirname(__FILE__)+"/log4j-api-2.0.jar")
51
+ require File.dirname(__FILE__)+"/log4j-api-2.0.jar"
52
+ end
53
+ if File.exists?(File.dirname(__FILE__)+"/log4j-core-2.0.jar")
54
+ require File.dirname(__FILE__)+"/log4j-core-2.0.jar"
55
+ end
56
+ end
57
+ Java::OrgApacheLoggingLog4jCoreImpl.const_get("Log4jLogEvent")
58
+ rescue
59
+ raise(LogStash::PluginLoadingError, "Log4j2 java library not loaded")
60
+ end
61
+
62
+ if server?
63
+ @logger.info("Starting Log4j2 input listener", :address => "#{@host}:#{@port}")
64
+ @server_socket = TCPServer.new(@host, @port)
65
+ end
66
+ @logger.info("Log4j input")
67
+ end # def register
68
+
69
+ private
70
+ def pretty_print_stack_trace(proxy)
71
+ indentation = "\n\t"
72
+ result = "#{proxy.getName}: #{proxy.getMessage.to_s}#{indentation}#{proxy.getExtendedStackTrace.to_a.join(indentation)}"
73
+ cause = proxy.getCauseProxy
74
+ while cause
75
+ result += "\nCaused by: #{cause.getName}: #{cause.getMessage.to_s}#{indentation}#{cause.getExtendedStackTrace.to_a.join(indentation)}"
76
+ cause = cause.getCauseProxy
77
+ end
78
+ result
79
+ end
80
+
81
+ private
82
+ def handle_socket(socket, output_queue)
83
+ begin
84
+ # JRubyObjectInputStream uses JRuby class path to find the class to de-serialize to
85
+ ois = JRubyObjectInputStream.new(java.io.BufferedInputStream.new(socket.to_inputstream))
86
+ loop do
87
+ # NOTE: log4j_obj is org.apache.logging.log4j.core.impl.Log4jLogEvent
88
+ log4j_obj = ois.readObject
89
+ event = LogStash::Event.new("message" => log4j_obj.getMessage.getFormattedMessage, LogStash::Event::TIMESTAMP => Time.at(log4j_obj.getTimeMillis/1000,log4j_obj.getTimeMillis%1000*1000).gmtime)
90
+ decorate(event)
91
+ event["host"] = socket.peer
92
+ event["marker"] = log4j_obj.getMarker.getName if log4j_obj.getMarker
93
+ event["path"] = log4j_obj.getLoggerName
94
+ event["priority"] = log4j_obj.getLevel.toString
95
+ event["logger_name"] = log4j_obj.getLoggerName
96
+ event["thread"] = log4j_obj.getThreadName
97
+ if log4j_obj.getSource()
98
+ event["class"] = log4j_obj.getSource().getClassName
99
+ event["file"] = log4j_obj.getSource().getFileName + ":" + log4j_obj.getSource().getLineNumber.to_s
100
+ event["method"] = log4j_obj.getSource().getMethodName
101
+ end
102
+ # Add the context properties to '@fields'
103
+ if log4j_obj.contextMap
104
+ log4j_obj.contextMap.keySet.each do |key|
105
+ event["cmap_"+key] = log4j_obj.contextMap.get(key)
106
+ end
107
+ end
108
+
109
+ proxy = log4j_obj.getThrownProxy
110
+ if proxy
111
+ event["stack_trace"] = pretty_print_stack_trace(proxy)
112
+ end
113
+
114
+ event["cstack"] = log4j_obj.getContextStack.to_a if log4j_obj.getContextStack
115
+ output_queue << event
116
+ end # loop do
117
+ rescue => e
118
+ @logger.debug(e)
119
+ @logger.debug("Closing connection", :client => socket.peer,
120
+ :exception => e)
121
+ rescue Timeout::Error
122
+ @logger.debug("Closing connection after read timeout",
123
+ :client => socket.peer)
124
+ end # begin
125
+ ensure
126
+ begin
127
+ socket.close
128
+ rescue IOError
129
+ pass
130
+ end # begin
131
+ end
132
+
133
+ private
134
+ def server?
135
+ @mode == "server"
136
+ end # def server?
137
+
138
+ private
139
+ def readline(socket)
140
+ line = socket.readline
141
+ end # def readline
142
+
143
+ public
144
+ def run(output_queue)
145
+ if server?
146
+ loop do
147
+ # Start a new thread for each connection.
148
+ Thread.start(@server_socket.accept) do |s|
149
+ # TODO(sissel): put this block in its own method.
150
+
151
+ # monkeypatch a 'peer' method onto the socket.
152
+ s.instance_eval { class << self; include ::LogStash::Util::SocketPeer end }
153
+ @logger.debug("Accepted connection", :client => s.peer,
154
+ :server => "#{@host}:#{@port}")
155
+ handle_socket(s, output_queue)
156
+ end # Thread.start
157
+ end # loop
158
+ else
159
+ loop do
160
+ client_socket = TCPSocket.new(@host, @port)
161
+ client_socket.instance_eval { class << self; include ::LogStash::Util::SocketPeer end }
162
+ @logger.debug("Opened connection", :client => "#{client_socket.peer}")
163
+ handle_socket(client_socket, output_queue)
164
+ end # loop
165
+ end
166
+ end # def run
167
+ end # class LogStash::Inputs::Log4j2
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |s|
2
+
3
+ s.name = 'logstash-input-log4j2'
4
+ s.version = '3.3'
5
+ s.licenses = ['Apache License (2.0)']
6
+ s.summary = "$summary"
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 = ["Jurriaan Mous"]
9
+ s.email = 'jurmous@jurmo.us'
10
+ s.homepage = "https://github.com/jurmous/logstash-log4j2"
11
+ s.require_paths = ["lib"]
12
+
13
+ # Files
14
+ s.files = `git ls-files`.split($\)+::Dir.glob('vendor/*')
15
+
16
+ # Tests
17
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
+
19
+ # Special flag to let us know this is actually a logstash plugin
20
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "input" }
21
+
22
+ # Gem dependencies
23
+ s.add_runtime_dependency 'logstash', '>= 1.4.0', '< 2.0.0'
24
+
25
+ s.add_development_dependency 'logstash-devutils'
26
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-input-log4j2
3
+ version: !ruby/object:Gem::Version
4
+ version: '3.3'
5
+ platform: ruby
6
+ authors:
7
+ - Jurriaan Mous
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logstash
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.0
20
+ - - <
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.4.0
30
+ - - <
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: logstash-devutils
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ description: This gem is a logstash plugin required to be installed on top of the
48
+ Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not
49
+ a stand-alone program
50
+ email: jurmous@jurmo.us
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - Gemfile
56
+ - README.md
57
+ - Rakefile
58
+ - lib/logstash/inputs/log4j-api-2.0.jar
59
+ - lib/logstash/inputs/log4j-core-2.0.jar
60
+ - lib/logstash/inputs/log4j2.rb
61
+ - logstash-input-log4j2.gemspec
62
+ homepage: https://github.com/jurmous/logstash-log4j2
63
+ licenses:
64
+ - Apache License (2.0)
65
+ metadata:
66
+ logstash_plugin: 'true'
67
+ logstash_group: input
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.0.14
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: $summary
88
+ test_files: []