tcp-server 1.2.1-java → 1.4.1-java
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/README.md +28 -28
- data/Rakefile +12 -2
- data/exe/tcp_server +3 -3
- data/lib/{server/argument_parser.rb → tcp_server/arguments_parser.rb} +9 -9
- data/lib/{server/channel_initializer.rb → tcp_server/channelizer.rb} +29 -25
- data/lib/{client.rb → tcp_server/client.rb} +53 -47
- data/lib/{server → tcp_server}/config.rb +8 -4
- data/lib/{server → tcp_server}/default_handler.rb +7 -6
- data/lib/{demo_listener.rb → tcp_server/demo_listener.rb} +5 -5
- data/lib/{server → tcp_server}/instance_methods.rb +70 -31
- data/lib/{server → tcp_server}/listenable.rb +4 -4
- data/lib/tcp_server/logging.rb +310 -0
- data/lib/{server → tcp_server}/message_handler.rb +8 -8
- data/lib/{server → tcp_server}/modular_handler.rb +33 -28
- data/lib/tcp_server/server.rb +58 -0
- data/lib/tcp_server/version.rb +16 -0
- data/lib/tcp_server.rb +3 -2
- metadata +38 -33
- data/lib/logging.rb +0 -253
- data/lib/server/server.rb +0 -38
- data/lib/server/shutdown_hook.rb +0 -35
- data/lib/server/version.rb +0 -16
- data/lib/server.rb +0 -36
- data/lib/tcp-server.rb +0 -13
|
@@ -6,61 +6,65 @@
|
|
|
6
6
|
|
|
7
7
|
# =begin
|
|
8
8
|
#
|
|
9
|
-
# Copyright Nels Nelson 2016-
|
|
9
|
+
# Copyright Nels Nelson 2016-2026 but freely usable (see license)
|
|
10
10
|
#
|
|
11
11
|
# =end
|
|
12
12
|
|
|
13
13
|
require 'java'
|
|
14
14
|
require 'netty'
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
java_import 'io.netty.channel.SimpleChannelInboundHandler'
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
module Server
|
|
20
|
-
java_import Java::io.netty.channel.SimpleChannelInboundHandler
|
|
18
|
+
require_relative 'listenable'
|
|
21
19
|
|
|
20
|
+
# The TcpServer module
|
|
21
|
+
module TcpServer
|
|
22
22
|
# The ModularHandler class notifies listeners about events.
|
|
23
23
|
class ModularHandler < SimpleChannelInboundHandler
|
|
24
|
-
include ::
|
|
24
|
+
include TcpServer::Listenable
|
|
25
25
|
|
|
26
26
|
def initialize(channel_group)
|
|
27
27
|
super()
|
|
28
28
|
@channel_group = channel_group
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# Overrides the Java::IoNettyChannel::SimpleChannelInboundHandler#isSharable
|
|
32
|
+
# method
|
|
33
|
+
# rubocop: disable Naming/PredicateMethod
|
|
31
34
|
def isSharable
|
|
32
35
|
true
|
|
33
36
|
end
|
|
37
|
+
# rubocop: enable Naming/PredicateMethod
|
|
34
38
|
|
|
35
39
|
def channelRegistered(ctx)
|
|
36
|
-
log.trace "
|
|
40
|
+
log.trace "#channelRegistered channel: #{ctx.channel}"
|
|
37
41
|
notify :channel_registered, ctx
|
|
38
|
-
super
|
|
42
|
+
super
|
|
39
43
|
end
|
|
40
44
|
|
|
41
45
|
def channelUnregistered(ctx)
|
|
42
|
-
log.trace "
|
|
46
|
+
log.trace "#channelUnregistered channel: #{ctx.channel}"
|
|
43
47
|
notify :channel_unregistered, ctx
|
|
44
|
-
super
|
|
48
|
+
super
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
def channelActive(ctx)
|
|
48
|
-
|
|
52
|
+
TcpServer.log.debug "#channelActive channel: #{ctx.channel}"
|
|
49
53
|
@channel_group.add(ctx.channel)
|
|
50
54
|
notify :channel_active, ctx
|
|
51
|
-
super
|
|
55
|
+
super
|
|
52
56
|
end
|
|
53
57
|
|
|
54
58
|
def channelInactive(ctx)
|
|
55
|
-
log.trace "
|
|
59
|
+
log.trace "#channelInactive channel: #{ctx.channel}"
|
|
56
60
|
notify :channel_inactive, ctx
|
|
57
|
-
super
|
|
61
|
+
super
|
|
58
62
|
end
|
|
59
63
|
|
|
60
64
|
def channelRead(ctx, msg)
|
|
61
|
-
log.trace "
|
|
65
|
+
log.trace "#channelRead channel: #{ctx.channel}, message: #{msg.inspect}"
|
|
62
66
|
notify :channel_read, ctx, msg
|
|
63
|
-
super
|
|
67
|
+
super
|
|
64
68
|
end
|
|
65
69
|
|
|
66
70
|
# Please keep in mind that this method will be renamed to
|
|
@@ -68,40 +72,41 @@ module Server
|
|
|
68
72
|
#
|
|
69
73
|
# java_signature 'protected abstract void channelRead0(ChannelHandlerContext ctx, I msg) throws Exception'
|
|
70
74
|
def channelRead0(ctx, msg)
|
|
71
|
-
log.trace "
|
|
75
|
+
log.trace "#channelRead0 channel: #{ctx.channel}, message: #{msg.inspect}"
|
|
72
76
|
messageReceived(ctx, msg)
|
|
73
77
|
# super(ctx, msg)
|
|
74
78
|
end
|
|
75
79
|
|
|
76
80
|
def messageReceived(ctx, msg)
|
|
77
|
-
log.trace "
|
|
81
|
+
log.trace "#messageReceived channel: #{ctx.channel}, message: #{msg.inspect}"
|
|
78
82
|
notify :message_received, ctx, msg
|
|
79
83
|
# super(ctx, msg)
|
|
80
84
|
end
|
|
81
85
|
|
|
82
86
|
def channelReadComplete(ctx)
|
|
83
|
-
log.trace "
|
|
87
|
+
log.trace "#channelReadComplete channel: #{ctx.channel}"
|
|
84
88
|
notify :channel_read_complete, ctx
|
|
85
|
-
super
|
|
89
|
+
super
|
|
86
90
|
end
|
|
87
91
|
|
|
88
92
|
def userEventTriggered(ctx, evt)
|
|
89
|
-
log.trace "
|
|
93
|
+
log.trace "#userEventTriggered channel: #{ctx.channel}, event: #{evt}"
|
|
90
94
|
notify :user_event_triggered, ctx, evt
|
|
91
|
-
super
|
|
95
|
+
super
|
|
92
96
|
end
|
|
93
97
|
|
|
94
98
|
def channelWritabilityChanged(ctx)
|
|
95
|
-
log.trace "
|
|
99
|
+
log.trace "#channelWritabilityChanged channel: #{ctx.channel}"
|
|
96
100
|
notify :channel_writability_changed, ctx
|
|
97
|
-
super
|
|
101
|
+
super
|
|
98
102
|
end
|
|
99
103
|
|
|
100
104
|
def exceptionCaught(ctx, cause)
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
TcpServer.log.warn "#exceptionCaught channel: #{ctx.channel}, " \
|
|
106
|
+
"cause: #{cause.message}"
|
|
107
|
+
cause.backtrace.each { |t| TcpServer.log.error t }
|
|
103
108
|
listeners = notify :exception_caught, ctx, cause
|
|
104
|
-
super
|
|
109
|
+
super if listeners.nil? || listeners.empty?
|
|
105
110
|
end
|
|
106
111
|
|
|
107
112
|
IdentifierTemplate = '#<%<class>s:0x%<id>s>'.freeze
|
|
@@ -113,4 +118,4 @@ module Server
|
|
|
113
118
|
end
|
|
114
119
|
# class ModularHandler
|
|
115
120
|
end
|
|
116
|
-
# module
|
|
121
|
+
# module TcpServer
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: false
|
|
3
|
+
|
|
4
|
+
# -*- mode: ruby -*-
|
|
5
|
+
# vi: set ft=ruby :
|
|
6
|
+
|
|
7
|
+
# =begin
|
|
8
|
+
#
|
|
9
|
+
# Copyright Nels Nelson 2016-2026 but freely usable (see license)
|
|
10
|
+
#
|
|
11
|
+
# =end
|
|
12
|
+
|
|
13
|
+
require 'java'
|
|
14
|
+
require 'netty'
|
|
15
|
+
|
|
16
|
+
require_relative 'arguments_parser'
|
|
17
|
+
require_relative 'demo_listener'
|
|
18
|
+
require_relative 'instance_methods'
|
|
19
|
+
require_relative 'listenable'
|
|
20
|
+
require_relative 'logging'
|
|
21
|
+
|
|
22
|
+
java_import 'io.netty.channel.socket.nio.NioServerSocketChannel'
|
|
23
|
+
|
|
24
|
+
# The Server module
|
|
25
|
+
module TcpServer
|
|
26
|
+
# The Server class sets up the netty server.
|
|
27
|
+
class Server
|
|
28
|
+
CHANNEL_TYPE = NioServerSocketChannel.java_class
|
|
29
|
+
include TcpServer::InstanceMethods
|
|
30
|
+
|
|
31
|
+
attr_reader :options
|
|
32
|
+
|
|
33
|
+
def initialize(options = {}, *handlers, &block)
|
|
34
|
+
raise ArgumentError, 'Parameter may not be nil: options' if options.nil?
|
|
35
|
+
@options = TcpServer.server_config.merge(options)
|
|
36
|
+
configure_handlers(*(handlers.empty? && block.nil? ? [self] : handlers), &block)
|
|
37
|
+
ensure
|
|
38
|
+
listeners = channelizer.default_handler.listeners
|
|
39
|
+
log.trace "##{__method__} listeners: #{listeners}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
# class Server
|
|
43
|
+
|
|
44
|
+
def main(args = parse_arguments)
|
|
45
|
+
Logging.log_level = args[:log_level]
|
|
46
|
+
demo_handler = TcpServer::Demo.new(args)
|
|
47
|
+
TcpServer::Server.new(args, demo_handler).run
|
|
48
|
+
rescue Interrupt => e
|
|
49
|
+
warn format("\r%<class>s", class: e.class)
|
|
50
|
+
exit
|
|
51
|
+
rescue StandardError => e
|
|
52
|
+
TcpServer::Server.log.fatal(e)
|
|
53
|
+
e.backtrace.each { |t| TcpServer.log.fatal t }
|
|
54
|
+
exit 1
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
Object.new.extend(TcpServer).main if $PROGRAM_NAME == __FILE__
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: false
|
|
3
|
+
|
|
4
|
+
# -*- mode: ruby -*-
|
|
5
|
+
# vi: set ft=ruby :
|
|
6
|
+
|
|
7
|
+
# =begin
|
|
8
|
+
#
|
|
9
|
+
# Copyright Nels Nelson 2016-2026 but freely usable (see license)
|
|
10
|
+
#
|
|
11
|
+
# =end
|
|
12
|
+
|
|
13
|
+
# The TcpServer module
|
|
14
|
+
module TcpServer
|
|
15
|
+
VERSION = '1.4.1'.freeze
|
|
16
|
+
end
|
data/lib/tcp_server.rb
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
# =begin
|
|
8
8
|
#
|
|
9
|
-
# Copyright Nels Nelson 2016-
|
|
9
|
+
# Copyright Nels Nelson 2016-2026 but freely usable (see license)
|
|
10
10
|
#
|
|
11
11
|
# =end
|
|
12
12
|
|
|
13
|
-
require_relative '
|
|
13
|
+
require_relative 'tcp_server/client'
|
|
14
|
+
require_relative 'tcp_server/server'
|
metadata
CHANGED
|
@@ -1,60 +1,70 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tcp-server
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.1
|
|
5
5
|
platform: java
|
|
6
6
|
authors:
|
|
7
7
|
- Nels Nelson
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: apache-log4j-2
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 2.
|
|
19
|
-
name: apache-log4j-2
|
|
18
|
+
version: 2.25.3
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 2.
|
|
27
|
-
force_ruby_platform: false
|
|
25
|
+
version: 2.25.3
|
|
28
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: bouncycastle
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - "~>"
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 1.
|
|
34
|
-
name: bouncycastle
|
|
32
|
+
version: '1.83'
|
|
35
33
|
type: :runtime
|
|
36
34
|
prerelease: false
|
|
37
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
38
36
|
requirements:
|
|
39
37
|
- - "~>"
|
|
40
38
|
- !ruby/object:Gem::Version
|
|
41
|
-
version: 1.
|
|
42
|
-
force_ruby_platform: false
|
|
39
|
+
version: '1.83'
|
|
43
40
|
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: logger
|
|
44
42
|
requirement: !ruby/object:Gem::Requirement
|
|
45
43
|
requirements:
|
|
46
44
|
- - "~>"
|
|
47
45
|
- !ruby/object:Gem::Version
|
|
48
|
-
version:
|
|
46
|
+
version: '1.7'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.7'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
49
55
|
name: netty-io
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 4.2.9
|
|
50
61
|
type: :runtime
|
|
51
62
|
prerelease: false
|
|
52
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
53
64
|
requirements:
|
|
54
65
|
- - "~>"
|
|
55
66
|
- !ruby/object:Gem::Version
|
|
56
|
-
version: 4.
|
|
57
|
-
force_ruby_platform: false
|
|
67
|
+
version: 4.2.9
|
|
58
68
|
description: TCP Server for JRuby is a tcp server which supports a demo echo server
|
|
59
69
|
application.
|
|
60
70
|
email: nels@nelsnelson.org
|
|
@@ -67,23 +77,20 @@ files:
|
|
|
67
77
|
- README.md
|
|
68
78
|
- Rakefile
|
|
69
79
|
- exe/tcp_server
|
|
70
|
-
- lib/client.rb
|
|
71
|
-
- lib/demo_listener.rb
|
|
72
|
-
- lib/logging.rb
|
|
73
|
-
- lib/server.rb
|
|
74
|
-
- lib/server/argument_parser.rb
|
|
75
|
-
- lib/server/channel_initializer.rb
|
|
76
|
-
- lib/server/config.rb
|
|
77
|
-
- lib/server/default_handler.rb
|
|
78
|
-
- lib/server/instance_methods.rb
|
|
79
|
-
- lib/server/listenable.rb
|
|
80
|
-
- lib/server/message_handler.rb
|
|
81
|
-
- lib/server/modular_handler.rb
|
|
82
|
-
- lib/server/server.rb
|
|
83
|
-
- lib/server/shutdown_hook.rb
|
|
84
|
-
- lib/server/version.rb
|
|
85
|
-
- lib/tcp-server.rb
|
|
86
80
|
- lib/tcp_server.rb
|
|
81
|
+
- lib/tcp_server/arguments_parser.rb
|
|
82
|
+
- lib/tcp_server/channelizer.rb
|
|
83
|
+
- lib/tcp_server/client.rb
|
|
84
|
+
- lib/tcp_server/config.rb
|
|
85
|
+
- lib/tcp_server/default_handler.rb
|
|
86
|
+
- lib/tcp_server/demo_listener.rb
|
|
87
|
+
- lib/tcp_server/instance_methods.rb
|
|
88
|
+
- lib/tcp_server/listenable.rb
|
|
89
|
+
- lib/tcp_server/logging.rb
|
|
90
|
+
- lib/tcp_server/message_handler.rb
|
|
91
|
+
- lib/tcp_server/modular_handler.rb
|
|
92
|
+
- lib/tcp_server/server.rb
|
|
93
|
+
- lib/tcp_server/version.rb
|
|
87
94
|
homepage: https://rubygems.org/gems/tcp-server-jruby
|
|
88
95
|
licenses:
|
|
89
96
|
- MIT
|
|
@@ -91,7 +98,6 @@ metadata:
|
|
|
91
98
|
source_code_uri: https://gitlab.com/nelsnelson/tcp-server-jruby
|
|
92
99
|
bug_tracker_uri: https://gitlab.com/nelsnelson/tcp-server-jruby/issues
|
|
93
100
|
rubygems_mfa_required: 'true'
|
|
94
|
-
post_install_message:
|
|
95
101
|
rdoc_options: []
|
|
96
102
|
require_paths:
|
|
97
103
|
- lib
|
|
@@ -106,8 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
106
112
|
- !ruby/object:Gem::Version
|
|
107
113
|
version: '0'
|
|
108
114
|
requirements: []
|
|
109
|
-
rubygems_version: 3.
|
|
110
|
-
signing_key:
|
|
115
|
+
rubygems_version: 3.6.9
|
|
111
116
|
specification_version: 4
|
|
112
117
|
summary: TCP Server for JRuby packaged as a gem.
|
|
113
118
|
test_files: []
|
data/lib/logging.rb
DELETED
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
# frozen_string_literal: false
|
|
3
|
-
|
|
4
|
-
# -*- mode: ruby -*-
|
|
5
|
-
# vi: set ft=ruby :
|
|
6
|
-
|
|
7
|
-
# =begin
|
|
8
|
-
|
|
9
|
-
# Copyright Nels Nelson 2016-2024 but freely usable (see license)
|
|
10
|
-
|
|
11
|
-
# =end
|
|
12
|
-
|
|
13
|
-
require 'java'
|
|
14
|
-
require 'fileutils'
|
|
15
|
-
require 'logger'
|
|
16
|
-
|
|
17
|
-
require 'apache-log4j-2'
|
|
18
|
-
|
|
19
|
-
# The Logging module
|
|
20
|
-
module Logging
|
|
21
|
-
# rubocop: disable Metrics/MethodLength
|
|
22
|
-
def config
|
|
23
|
-
@config ||= begin
|
|
24
|
-
lib_dir_path = File.expand_path(__dir__)
|
|
25
|
-
project_dir_path = File.expand_path(File.dirname(lib_dir_path))
|
|
26
|
-
logs_dir_path = File.expand_path(File.join(project_dir_path, 'logs'))
|
|
27
|
-
FileUtils.mkdir_p(logs_dir_path)
|
|
28
|
-
log_file_path = File.expand_path(File.join(logs_dir_path, 'server.log'))
|
|
29
|
-
FileUtils.touch(log_file_path)
|
|
30
|
-
{
|
|
31
|
-
level: Logger::INFO,
|
|
32
|
-
name: 'websocket',
|
|
33
|
-
lib_dir_path: lib_dir_path,
|
|
34
|
-
project_dir_path: project_dir_path,
|
|
35
|
-
logs_dir_path: logs_dir_path,
|
|
36
|
-
log_file_path: log_file_path,
|
|
37
|
-
rolling_log_file_name_template: File.expand_path(
|
|
38
|
-
File.join(logs_dir_path, 'server-%d{yyyy-MM-dd}.log.gz')),
|
|
39
|
-
logging_pattern_template: {
|
|
40
|
-
java: '%d{ABSOLUTE} %-5p [%c{1}] %m%n',
|
|
41
|
-
ruby: "%<timestamp>s %-5<severity>s [%<progname>s] %<msg>s\n"
|
|
42
|
-
},
|
|
43
|
-
schedule: '0 0 0 * * ?',
|
|
44
|
-
size: '100M'
|
|
45
|
-
}
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
module_function :config
|
|
49
|
-
# rubocop: enable Metrics/MethodLength
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# The Logging module
|
|
53
|
-
module Logging
|
|
54
|
-
if defined?(Java)
|
|
55
|
-
java_import Java::org.apache.logging.log4j.core.appender::ConsoleAppender
|
|
56
|
-
java_import Java::org.apache.logging.log4j.core.config::Configurator
|
|
57
|
-
java_import Java::org.apache.logging.log4j.core.config.builder.api::ConfigurationBuilderFactory
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# rubocop: disable Metrics/AbcSize
|
|
61
|
-
# rubocop: disable Metrics/MethodLength
|
|
62
|
-
def init_log4j(log_level = org.apache.logging.log4j.Level::INFO)
|
|
63
|
-
java.lang::System.setProperty('log4j.shutdownHookEnabled', java.lang::Boolean.toString(false))
|
|
64
|
-
config = ConfigurationBuilderFactory.newConfigurationBuilder()
|
|
65
|
-
|
|
66
|
-
log_level = org.apache.logging.log4j::Level.to_level(log_level.to_s.upcase) if log_level.is_a? Symbol
|
|
67
|
-
config.setStatusLevel(log_level)
|
|
68
|
-
config.setConfigurationName('websocket')
|
|
69
|
-
|
|
70
|
-
# create a console appender
|
|
71
|
-
target = ConsoleAppender::Target::SYSTEM_OUT
|
|
72
|
-
pattern = Logging.config[:logging_pattern_template][:java]
|
|
73
|
-
layout = config.newLayout('PatternLayout')
|
|
74
|
-
layout = layout.addAttribute('pattern', pattern)
|
|
75
|
-
appender = config.newAppender('stdout', 'CONSOLE')
|
|
76
|
-
appender = appender.addAttribute('target', target)
|
|
77
|
-
appender = appender.add(layout)
|
|
78
|
-
config.add(appender)
|
|
79
|
-
|
|
80
|
-
# create a root logger
|
|
81
|
-
root_logger = config.newRootLogger(log_level)
|
|
82
|
-
root_logger = root_logger.add(config.newAppenderRef('stdout'))
|
|
83
|
-
|
|
84
|
-
# create a rolling file appender
|
|
85
|
-
cron = config.newComponent('CronTriggeringPolicy')
|
|
86
|
-
cron = cron.addAttribute('schedule', '0 0 0 * * ?')
|
|
87
|
-
|
|
88
|
-
size = config.newComponent('SizeBasedTriggeringPolicy')
|
|
89
|
-
size = size.addAttribute('size', '100M')
|
|
90
|
-
|
|
91
|
-
policies = config.newComponent('Policies')
|
|
92
|
-
policies = policies.addComponent(cron)
|
|
93
|
-
policies = policies.addComponent(size)
|
|
94
|
-
|
|
95
|
-
appender = config.newAppender('rolling_file', 'RollingFile')
|
|
96
|
-
appender = appender.addAttribute('fileName', Logging.config[:log_file_path])
|
|
97
|
-
appender = appender.addAttribute('filePattern', Logging.config[:rolling_log_file_name_template])
|
|
98
|
-
appender = appender.add(layout)
|
|
99
|
-
appender = appender.addComponent(policies)
|
|
100
|
-
config.add(appender)
|
|
101
|
-
|
|
102
|
-
root_logger = root_logger.addAttribute('additivity', false)
|
|
103
|
-
root_logger = root_logger.add(config.newAppenderRef('rolling_file'))
|
|
104
|
-
config.add(root_logger)
|
|
105
|
-
|
|
106
|
-
logging_configuration = config.build()
|
|
107
|
-
ctx = Configurator.initialize(logging_configuration)
|
|
108
|
-
ctx.updateLoggers()
|
|
109
|
-
end
|
|
110
|
-
module_function :init_log4j
|
|
111
|
-
# rubocop: enable Metrics/AbcSize
|
|
112
|
-
# rubocop: enable Metrics/MethodLength
|
|
113
|
-
# def init_log4j
|
|
114
|
-
|
|
115
|
-
init_log4j if defined?(Java)
|
|
116
|
-
end
|
|
117
|
-
# module Logging
|
|
118
|
-
|
|
119
|
-
# Namespace for methods to help with implicit backtrace printing
|
|
120
|
-
module LoggerHelpers
|
|
121
|
-
def generate_message(error_or_message, error)
|
|
122
|
-
error_message = "#{error_or_message}: #{error.class.name}"
|
|
123
|
-
error_message << ": #{error.message}" if error.respond_to?(:message)
|
|
124
|
-
error_message
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def extract_backtrace(error, default_result = nil)
|
|
128
|
-
if error.respond_to?(:backtrace)
|
|
129
|
-
error.backtrace.each { |trace| original_error(trace) unless trace.nil? }
|
|
130
|
-
elsif error.respond_to?(:getStackTrace)
|
|
131
|
-
error.getStackTrace().each { |trace| original_error(trace) unless trace.nil? }
|
|
132
|
-
else
|
|
133
|
-
default_result
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# Monkey-patch the built-in Ruby Logger class to support
|
|
139
|
-
# implicit backtrace printing
|
|
140
|
-
# TODO: Figure out if this is actually useful.
|
|
141
|
-
class Logger
|
|
142
|
-
include LoggerHelpers
|
|
143
|
-
|
|
144
|
-
alias original_error error
|
|
145
|
-
def error(error_or_message, error = nil)
|
|
146
|
-
return extract_backtrace(error_or_message) if error.nil?
|
|
147
|
-
original_error(generate_message(error_or_message, error))
|
|
148
|
-
extract_backtrace(original_error(error))
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
# The Logging module
|
|
153
|
-
module Logging
|
|
154
|
-
if defined?(Java)
|
|
155
|
-
java_import Java::org.apache.logging.log4j.Level
|
|
156
|
-
java_import Java::org.apache.logging.log4j.LogManager
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
FORWARD_SLASH_PATTERN = %r{/} unless defined?(FORWARD_SLASH_PATTERN)
|
|
160
|
-
|
|
161
|
-
def init_logger(level = :info, logger_name = nil)
|
|
162
|
-
return init_java_logger(level, logger_name, caller[2]) if defined?(Java)
|
|
163
|
-
init_ruby_logger(level, logger_name, caller[2])
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
def ruby_log_formatter(severity_level, datetime, program_name, message)
|
|
167
|
-
format(
|
|
168
|
-
Logging.config[:logging_pattern_template][:ruby],
|
|
169
|
-
timestamp: datetime.strftime(Logging.config[:logging_timestamp_format]),
|
|
170
|
-
progname: program_name, severity: severity_level, msg: message)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
def init_ruby_logger(level = nil, logger_name = nil, source_location = nil)
|
|
174
|
-
logger_name = get_formatted_logger_name(logger_name)
|
|
175
|
-
logger_name = source_location.split(FORWARD_SLASH_PATTERN).last if logger_name.empty?
|
|
176
|
-
log = Logger.new($stdout, progname: logger_name)
|
|
177
|
-
log.level = level.to_s unless level.nil?
|
|
178
|
-
log.formatter = method(:ruby_log_formatter)
|
|
179
|
-
log
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def init_java_logger(level = nil, logger_name = nil, source_location = nil)
|
|
183
|
-
logger_name = get_formatted_logger_name(logger_name)
|
|
184
|
-
logger_name = source_location.split(FORWARD_SLASH_PATTERN).last if logger_name.empty?
|
|
185
|
-
log = LogManager.getLogger(logger_name)
|
|
186
|
-
log.level = Level.to_level(level.to_s.upcase) unless level.nil?
|
|
187
|
-
log
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
def get_formatted_logger_name(logger_name = nil)
|
|
191
|
-
return logger_name.to_s[/\w+$/] unless logger_name.nil?
|
|
192
|
-
return name[/\w+$/] if is_a?(Class) || is_a?(Module)
|
|
193
|
-
self.class.name[/\w+$/]
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
|
197
|
-
# OFF: 0
|
|
198
|
-
# FATAL: 100
|
|
199
|
-
# ERROR: 200
|
|
200
|
-
# WARN: 300
|
|
201
|
-
# INFO: 400
|
|
202
|
-
# DEBUG: 500
|
|
203
|
-
# TRACE: 600
|
|
204
|
-
# ALL: 2147483647
|
|
205
|
-
# See: https://logging.apache.org/log4j/2.x/log4j-api/apidocs/org/apache/logging/log4j/Level.html
|
|
206
|
-
def symbolize_numeric_log_level(level)
|
|
207
|
-
case level
|
|
208
|
-
when 5..Float::INFINITY then :off
|
|
209
|
-
when 4 then :fatal
|
|
210
|
-
when 3 then :error
|
|
211
|
-
when 2 then :warn
|
|
212
|
-
when 1 then :info
|
|
213
|
-
when 0 then :debug
|
|
214
|
-
when -1 then :trace
|
|
215
|
-
when -Float::INFINITY..-2 then :all
|
|
216
|
-
end
|
|
217
|
-
end
|
|
218
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
|
219
|
-
|
|
220
|
-
def log_level=(level)
|
|
221
|
-
Logging.config[:level] = symbolize_numeric_log_level(level)
|
|
222
|
-
end
|
|
223
|
-
module_function :log_level=
|
|
224
|
-
|
|
225
|
-
def log_level
|
|
226
|
-
Logging.config[:level]
|
|
227
|
-
end
|
|
228
|
-
module_function :log_level
|
|
229
|
-
|
|
230
|
-
def log(level = Logging.log_level, log_name = Logging.config[:app_name])
|
|
231
|
-
@log ||= init_logger(level, log_name)
|
|
232
|
-
end
|
|
233
|
-
alias logger log
|
|
234
|
-
end
|
|
235
|
-
# module Logging
|
|
236
|
-
|
|
237
|
-
# The Module class
|
|
238
|
-
class Module
|
|
239
|
-
# Universally include Logging
|
|
240
|
-
include ::Logging
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
# The Class class
|
|
244
|
-
class Class
|
|
245
|
-
# Universally include Logging
|
|
246
|
-
include ::Logging
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
# The Object class
|
|
250
|
-
class Object
|
|
251
|
-
# Universally include Logging
|
|
252
|
-
include ::Logging
|
|
253
|
-
end
|
data/lib/server/server.rb
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
# frozen_string_literal: false
|
|
3
|
-
|
|
4
|
-
# -*- mode: ruby -*-
|
|
5
|
-
# vi: set ft=ruby :
|
|
6
|
-
|
|
7
|
-
# =begin
|
|
8
|
-
#
|
|
9
|
-
# Copyright Nels Nelson 2016-2024 but freely usable (see license)
|
|
10
|
-
#
|
|
11
|
-
# =end
|
|
12
|
-
|
|
13
|
-
require 'java'
|
|
14
|
-
require 'netty'
|
|
15
|
-
|
|
16
|
-
require_relative 'instance_methods'
|
|
17
|
-
require_relative 'listenable'
|
|
18
|
-
|
|
19
|
-
# The Server module
|
|
20
|
-
module Server
|
|
21
|
-
# The Server class sets up the netty server.
|
|
22
|
-
class Server
|
|
23
|
-
CHANNEL_TYPE = Java::io.netty.channel.socket.nio.NioServerSocketChannel.java_class
|
|
24
|
-
include ::Server::InstanceMethods
|
|
25
|
-
attr_reader :options
|
|
26
|
-
|
|
27
|
-
def initialize(options = {}, *handlers, &block)
|
|
28
|
-
raise ArgumentError, 'Parameter may not be nil: options' if options.nil?
|
|
29
|
-
@options = ::Server.server_config.merge(options)
|
|
30
|
-
configure_handlers(*(handlers.empty? && block.nil? ? [self] : handlers), &block)
|
|
31
|
-
ensure
|
|
32
|
-
listeners = channel_initializer.default_handler.listeners
|
|
33
|
-
log.trace "##{__method__} listeners: #{listeners}"
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
# class Server
|
|
37
|
-
end
|
|
38
|
-
# module Server
|
data/lib/server/shutdown_hook.rb
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
# frozen_string_literal: false
|
|
3
|
-
|
|
4
|
-
# -*- mode: ruby -*-
|
|
5
|
-
# vi: set ft=ruby :
|
|
6
|
-
|
|
7
|
-
# =begin
|
|
8
|
-
#
|
|
9
|
-
# Copyright Nels Nelson 2016-2024 but freely usable (see license)
|
|
10
|
-
#
|
|
11
|
-
# =end
|
|
12
|
-
|
|
13
|
-
require 'java'
|
|
14
|
-
|
|
15
|
-
# The Server module
|
|
16
|
-
module Server
|
|
17
|
-
# The ShutdownHook class specifies a routine to be invoked when the
|
|
18
|
-
# java runtime is shutdown.
|
|
19
|
-
class ShutdownHook < java.lang.Thread
|
|
20
|
-
attr_reader :server
|
|
21
|
-
|
|
22
|
-
def initialize(server)
|
|
23
|
-
super()
|
|
24
|
-
@server = server
|
|
25
|
-
java.lang.Runtime.runtime.add_shutdown_hook(self)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def run
|
|
29
|
-
$stdout.write "\r\e[0K"
|
|
30
|
-
$stdout.flush
|
|
31
|
-
::Server.log.info 'Shutting down'
|
|
32
|
-
server.shutdown if server.respond_to?(:shutdown)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|