telnet-server 1.1.1-java → 1.1.2-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 +18 -17
- data/exe/telnet +1 -1
- data/lib/logging.rb +253 -0
- data/lib/telnet/argument_parser.rb +11 -4
- data/lib/telnet/config.rb +1 -1
- data/lib/telnet/instance_methods.rb +2 -2
- data/lib/telnet/server.rb +1 -1
- data/lib/telnet/version.rb +2 -2
- data/lib/telnet-server.rb +1 -1
- data/lib/telnet_client.rb +12 -9
- data/lib/telnet_server.rb +2 -2
- metadata +7 -48
- data/lib/log.rb +0 -241
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84d2494fa8c37050f8ab4f7187ef39d352bc1569b1346bfded57de2901594cd8
|
4
|
+
data.tar.gz: 37b08f5eac69e685ca09e9be008bc230a93407747bb7e022caa07570d7f07041
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a34f127f66a713c02b0044717f89433bb0b057adcd29a78551ccf955e89bc4b00b4666e10b5a1777a673fd508e225da5f42a3bc8c7f997be6de7cc7077a93745
|
7
|
+
data.tar.gz: 4c61a18edc92a8b2445f68a3c6a72ed042aa13ed8825bb91befa822e21d476016e6890767498fe50106513bfbee60535c6c5ab572a2e9b42ee4a58bb51d1849a
|
data/README.md
CHANGED
@@ -27,7 +27,7 @@ docker-compose down
|
|
27
27
|
Building the image or running the container:
|
28
28
|
|
29
29
|
```sh
|
30
|
-
docker build --
|
30
|
+
docker build --tag telnet-server-jruby .
|
31
31
|
docker run --detach --publish 21:21 --name telnet-server-jruby telnet-server-jruby
|
32
32
|
```
|
33
33
|
|
@@ -36,39 +36,40 @@ docker run --detach --publish 21:21 --name telnet-server-jruby telnet-server-jru
|
|
36
36
|
|
37
37
|
Run directly with the required dependencies installed.
|
38
38
|
|
39
|
-
### Install asdf
|
40
39
|
|
41
|
-
|
40
|
+
## Install mise-en-place
|
41
|
+
|
42
|
+
The [mise] CLI tool used to manage multiple runtime versions.
|
43
|
+
|
44
|
+
See: https://mise.jdx.dev/getting-started.html
|
42
45
|
|
43
46
|
```sh
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
+
curl https://mise.jdx.dev/install.sh | sh
|
48
|
+
~/.local/bin/mise --version
|
49
|
+
mise 2024.x.x
|
47
50
|
```
|
48
51
|
|
49
|
-
|
50
|
-
|
51
|
-
Download and install the latest version of the [Java JDK].
|
52
|
+
Enable mise activation in future zsh sessions.
|
52
53
|
|
53
54
|
```sh
|
54
|
-
|
55
|
-
asdf install java openjdk-17.0.2
|
55
|
+
echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc
|
56
56
|
```
|
57
57
|
|
58
58
|
|
59
|
-
|
59
|
+
## Install required runtime software
|
60
|
+
|
61
|
+
Use mise to install the runtime software defined as requirements
|
62
|
+
in the .tool-versions file.
|
60
63
|
|
61
64
|
```sh
|
62
|
-
|
63
|
-
asdf plugin update --all
|
64
|
-
asdf list all ruby
|
65
|
-
asdf install
|
65
|
+
mise install
|
66
66
|
```
|
67
67
|
|
68
68
|
|
69
69
|
Install the project dependencies.
|
70
70
|
|
71
71
|
```sh
|
72
|
+
gem install bundler
|
72
73
|
bundle install
|
73
74
|
```
|
74
75
|
|
@@ -186,7 +187,7 @@ curl --silent --show-error --location --request POST "https://gitlab.com/api/v4/
|
|
186
187
|
```
|
187
188
|
|
188
189
|
[license]: https://gitlab.com/nelsnelson/telnet-server-jruby/blob/master/LICENSE
|
189
|
-
[
|
190
|
+
[mise]: https://mise.jdx.dev/
|
190
191
|
[Netty project]: https://github.com/netty/netty
|
191
192
|
[Java JDK]: https://www.java.com/en/download/
|
192
193
|
[JRuby]: https://jruby.org/download
|
data/exe/telnet
CHANGED
data/lib/logging.rb
ADDED
@@ -0,0 +1,253 @@
|
|
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
|
+
module_function
|
22
|
+
|
23
|
+
# rubocop: disable Metrics/MethodLength
|
24
|
+
def config
|
25
|
+
@config ||= begin
|
26
|
+
lib_dir_path = File.expand_path(__dir__)
|
27
|
+
project_dir_path = File.expand_path(File.dirname(lib_dir_path))
|
28
|
+
logs_dir_path = File.expand_path(File.join(project_dir_path, 'logs'))
|
29
|
+
FileUtils.mkdir_p(logs_dir_path)
|
30
|
+
log_file_path = File.expand_path(File.join(logs_dir_path, 'server.log'))
|
31
|
+
FileUtils.touch(log_file_path)
|
32
|
+
{
|
33
|
+
level: Logger::INFO,
|
34
|
+
name: 'telnet',
|
35
|
+
lib_dir_path: lib_dir_path,
|
36
|
+
logs_dir_path: logs_dir_path,
|
37
|
+
log_file_path: log_file_path,
|
38
|
+
rolling_log_file_name_template: File.expand_path(
|
39
|
+
File.join(logs_dir_path, 'server-%d{yyyy-MM-dd}.log.gz')),
|
40
|
+
logging_pattern_template: {
|
41
|
+
java: '%d{ABSOLUTE} %-5p [%c{1}] %m%n',
|
42
|
+
ruby: "%<timestamp>s %-5<severity>s [%<progname>s] %<msg>s\n"
|
43
|
+
},
|
44
|
+
schedule: '0 0 0 * * ?',
|
45
|
+
size: '100M'
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
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
|
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
# =begin
|
8
8
|
#
|
9
|
-
# Copyright Nels Nelson 2016-
|
9
|
+
# Copyright Nels Nelson 2016-2024 but freely usable (see license)
|
10
10
|
#
|
11
11
|
# =end
|
12
12
|
|
@@ -25,7 +25,7 @@ module Telnet
|
|
25
25
|
@parser = option_parser
|
26
26
|
@options = ::Telnet.server_config.dup
|
27
27
|
@flags = %i[banner port idle_reading idle_writing log_requests log_level help version]
|
28
|
-
@flags.each { |method_name| method(method_name)
|
28
|
+
@flags.each { |method_name| method(method_name)&.call if respond_to?(method_name) }
|
29
29
|
end
|
30
30
|
|
31
31
|
def banner
|
@@ -35,7 +35,9 @@ module Telnet
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def validated_port(val, integer_pattern = /^\d+$/)
|
38
|
-
raise "Invalid port: #{v}" unless
|
38
|
+
raise OptionParser::InvalidArgument, "Invalid port: #{v}" unless \
|
39
|
+
integer_pattern.match?(val.to_s) && val.positive? && val < 65_536
|
40
|
+
|
39
41
|
val
|
40
42
|
end
|
41
43
|
|
@@ -90,7 +92,12 @@ module Telnet
|
|
90
92
|
def parse_arguments(arguments_parser = ::Telnet::ArgumentsParser.new)
|
91
93
|
arguments_parser.parser.parse!(ARGV)
|
92
94
|
arguments_parser.options
|
93
|
-
rescue OptionParser::
|
95
|
+
rescue OptionParser::InvalidArgument, OptionParser::InvalidOption,
|
96
|
+
OptionParser::MissingArgument, OptionParser::NeedlessArgument => e
|
97
|
+
puts e.message
|
98
|
+
puts parser
|
99
|
+
exit
|
100
|
+
rescue OptionParser::AmbiguousOption => e
|
94
101
|
abort e.message
|
95
102
|
end
|
96
103
|
end
|
data/lib/telnet/config.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
# =begin
|
8
8
|
#
|
9
|
-
# Copyright Nels Nelson 2016-
|
9
|
+
# Copyright Nels Nelson 2016-2024 but freely usable (see license)
|
10
10
|
#
|
11
11
|
# =end
|
12
12
|
|
@@ -41,7 +41,7 @@ module Telnet
|
|
41
41
|
# Writing to a ChannelBuffer is not needed here.
|
42
42
|
# The encoder will do the conversion.
|
43
43
|
def handle_message(ctx, message)
|
44
|
-
request =
|
44
|
+
request = message.to_s.strip
|
45
45
|
return handle_empty_request(ctx) if request.empty?
|
46
46
|
return close(ctx) if quit_command?(request)
|
47
47
|
ctx.write "Server echo: #{request}\r\n"
|
data/lib/telnet/server.rb
CHANGED
data/lib/telnet/version.rb
CHANGED
@@ -6,11 +6,11 @@
|
|
6
6
|
|
7
7
|
# =begin
|
8
8
|
#
|
9
|
-
# Copyright Nels Nelson 2016-
|
9
|
+
# Copyright Nels Nelson 2016-2024 but freely usable (see license)
|
10
10
|
#
|
11
11
|
# =end
|
12
12
|
|
13
13
|
# The Telnet module
|
14
14
|
module Telnet
|
15
|
-
VERSION = '1.1.
|
15
|
+
VERSION = '1.1.2'.freeze
|
16
16
|
end
|
data/lib/telnet-server.rb
CHANGED
data/lib/telnet_client.rb
CHANGED
@@ -8,21 +8,25 @@
|
|
8
8
|
|
9
9
|
# =begin
|
10
10
|
#
|
11
|
-
# Copyright Nels Nelson 2016-
|
11
|
+
# Copyright Nels Nelson 2016-2024 but freely usable (see license)
|
12
12
|
#
|
13
13
|
# =end
|
14
14
|
|
15
|
-
require 'logger'
|
16
15
|
require 'optparse'
|
17
16
|
|
18
17
|
require 'java'
|
19
18
|
require 'netty'
|
20
19
|
|
21
|
-
require_relative '
|
20
|
+
require_relative 'logging'
|
22
21
|
require_relative 'telnet/version'
|
23
22
|
|
24
23
|
# Simple telnet client
|
25
24
|
|
25
|
+
# The TelnetClient module
|
26
|
+
module TelnetClient
|
27
|
+
VERSION = '1.0.2'.freeze unless defined?(VERSION)
|
28
|
+
end
|
29
|
+
|
26
30
|
# The Telnet module
|
27
31
|
module Telnet
|
28
32
|
def client_config
|
@@ -416,14 +420,13 @@ end
|
|
416
420
|
module Telnet
|
417
421
|
# The ArgumentsParser class
|
418
422
|
class ArgumentsParser
|
419
|
-
IntegerPattern = /^\d+$/.freeze
|
420
|
-
Flags = %i[banner ssl log_level help version].freeze
|
421
423
|
attr_reader :parser, :options
|
422
424
|
|
423
425
|
def initialize(parser = OptionParser.new, options = ::Telnet.client_config.dup)
|
424
426
|
@parser = parser
|
425
427
|
@options = options
|
426
|
-
|
428
|
+
@flags = %i[banner ssl log_level help version]
|
429
|
+
@flags.each { |method_name| method(method_name)&.call if respond_to?(method_name) }
|
427
430
|
end
|
428
431
|
|
429
432
|
def banner
|
@@ -448,14 +451,14 @@ module Telnet
|
|
448
451
|
|
449
452
|
def version
|
450
453
|
@parser.on_tail('--version', 'Show version') do
|
451
|
-
puts "#{$PROGRAM_NAME} version #{
|
454
|
+
puts "#{File.basename($PROGRAM_NAME)} version #{::TelnetClient::VERSION}"
|
452
455
|
exit
|
453
456
|
end
|
454
457
|
end
|
455
458
|
|
456
459
|
def validated_port(val)
|
457
460
|
raise OptionParser::InvalidArgument, "Invalid port: #{val}" unless \
|
458
|
-
|
461
|
+
/^\d+$/.match?(val.to_s) && val.positive? && val < 65_536
|
459
462
|
|
460
463
|
val
|
461
464
|
end
|
@@ -515,4 +518,4 @@ module Telnet
|
|
515
518
|
end
|
516
519
|
# module Telnet
|
517
520
|
|
518
|
-
Object.new.extend(
|
521
|
+
Object.new.extend(Telnet).main if $PROGRAM_NAME == __FILE__
|
data/lib/telnet_server.rb
CHANGED
@@ -8,14 +8,14 @@
|
|
8
8
|
|
9
9
|
# =begin
|
10
10
|
#
|
11
|
-
# Copyright Nels Nelson 2016-
|
11
|
+
# Copyright Nels Nelson 2016-2024 but freely usable (see license)
|
12
12
|
#
|
13
13
|
# =end
|
14
14
|
|
15
15
|
require 'java'
|
16
16
|
require 'tcp-server'
|
17
17
|
|
18
|
-
require_relative '
|
18
|
+
require_relative 'logging'
|
19
19
|
require_relative 'telnet/argument_parser'
|
20
20
|
require_relative 'telnet/server'
|
21
21
|
|
metadata
CHANGED
@@ -1,71 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: telnet-server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Nels Nelson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
16
|
- - "~>"
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 1.1.
|
18
|
+
version: 1.1.3
|
19
19
|
name: tcp-server
|
20
|
-
prerelease: false
|
21
20
|
type: :runtime
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 1.1.0
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
29
|
-
requirements:
|
30
|
-
- - "~>"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 12.3.0
|
33
|
-
name: rake
|
34
|
-
prerelease: false
|
35
|
-
type: :development
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 12.3.0
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
43
|
-
requirements:
|
44
|
-
- - "~>"
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: 3.11.0
|
47
|
-
name: rspec
|
48
|
-
prerelease: false
|
49
|
-
type: :development
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 3.11.0
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
requirement: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - "~>"
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: 1.25.0
|
61
|
-
name: rubocop
|
62
21
|
prerelease: false
|
63
|
-
type: :development
|
64
22
|
version_requirements: !ruby/object:Gem::Requirement
|
65
23
|
requirements:
|
66
24
|
- - "~>"
|
67
25
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.
|
26
|
+
version: 1.1.3
|
27
|
+
force_ruby_platform: false
|
69
28
|
description: Telnet Server for JRuby is a telnet server with a file server to support
|
70
29
|
a demo javascript client application which interfaces with a demo echo server application.
|
71
30
|
email: nels@nelsnelson.org
|
@@ -78,7 +37,7 @@ files:
|
|
78
37
|
- README.md
|
79
38
|
- Rakefile
|
80
39
|
- exe/telnet
|
81
|
-
- lib/
|
40
|
+
- lib/logging.rb
|
82
41
|
- lib/telnet-server.rb
|
83
42
|
- lib/telnet/argument_parser.rb
|
84
43
|
- lib/telnet/config.rb
|
@@ -109,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
68
|
- !ruby/object:Gem::Version
|
110
69
|
version: '0'
|
111
70
|
requirements: []
|
112
|
-
rubygems_version: 3.
|
71
|
+
rubygems_version: 3.3.26
|
113
72
|
signing_key:
|
114
73
|
specification_version: 4
|
115
74
|
summary: Telnet Server for JRuby packaged as a gem.
|
data/lib/log.rb
DELETED
@@ -1,241 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# frozen_string_literal: false
|
3
|
-
|
4
|
-
# =begin
|
5
|
-
|
6
|
-
# Copyright Nels Nelson 2016-2019 but freely usable (see license)
|
7
|
-
|
8
|
-
# =end
|
9
|
-
|
10
|
-
require 'java'
|
11
|
-
require 'logger'
|
12
|
-
|
13
|
-
require 'log4j-2'
|
14
|
-
|
15
|
-
require 'fileutils'
|
16
|
-
|
17
|
-
# The Logging module
|
18
|
-
module Logging
|
19
|
-
module_function
|
20
|
-
|
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
|
-
server_log_file = File.expand_path(File.join(logs_dir_path, 'server.log'))
|
28
|
-
{
|
29
|
-
level: :info,
|
30
|
-
name: 'telnet',
|
31
|
-
logs_dir_path: logs_dir_path,
|
32
|
-
server_log_file: server_log_file,
|
33
|
-
rolling_log_file_name_template: 'server-%d{yyyy-MM-dd}.log.gz',
|
34
|
-
logger_pattern_template: '%d{ABSOLUTE} %-5p [%c{1}] %m%n',
|
35
|
-
schedule: '0 0 0 * * ?',
|
36
|
-
size: '100M'
|
37
|
-
}
|
38
|
-
end
|
39
|
-
end
|
40
|
-
# rubocop: enable Metrics/MethodLength
|
41
|
-
end
|
42
|
-
|
43
|
-
# The LogInitialization module
|
44
|
-
module LogInitialization
|
45
|
-
module_function
|
46
|
-
|
47
|
-
def init
|
48
|
-
init_log_file
|
49
|
-
init_log4j if defined? Java
|
50
|
-
end
|
51
|
-
|
52
|
-
def init_log_file
|
53
|
-
FileUtils.mkdir_p(Logging.config[:logs_dir_path])
|
54
|
-
return if File.file?(Logging.config[:server_log_file])
|
55
|
-
|
56
|
-
File.write(Logging.config[:server_log_file], '')
|
57
|
-
end
|
58
|
-
|
59
|
-
# rubocop: disable Metrics/AbcSize
|
60
|
-
# rubocop: disable Metrics/MethodLength
|
61
|
-
def init_log4j(log_level = org.apache.logging.log4j.Level::INFO)
|
62
|
-
server_log_file = Logging.config[:server_log_file]
|
63
|
-
logs_dir_path = Logging.config[:logs_dir_path]
|
64
|
-
rolling_log_file_name_template = Logging.config[:rolling_log_file_name_template]
|
65
|
-
rolling_log_file_path = File.join(logs_dir_path, rolling_log_file_name_template)
|
66
|
-
|
67
|
-
java.lang::System.setProperty('log4j.shutdownHookEnabled', java.lang::Boolean.toString(false))
|
68
|
-
factory = org.apache.logging.log4j.core.config.builder.api::ConfigurationBuilderFactory
|
69
|
-
config = factory.newConfigurationBuilder()
|
70
|
-
|
71
|
-
if log_level.is_a?(Symbol)
|
72
|
-
log_level = org.apache.logging.log4j.Level.to_level(
|
73
|
-
log_level.to_s.upcase
|
74
|
-
)
|
75
|
-
end
|
76
|
-
config.setStatusLevel(log_level)
|
77
|
-
config.setConfigurationName(Logging.config['name'])
|
78
|
-
|
79
|
-
# Create a console appender
|
80
|
-
target = org.apache.logging.log4j.core.appender::ConsoleAppender::Target::SYSTEM_OUT
|
81
|
-
layout = config.newLayout('PatternLayout')
|
82
|
-
layout = layout.addAttribute('pattern', Logging.config[:logger_pattern_template])
|
83
|
-
appender = config.newAppender('stdout', 'CONSOLE')
|
84
|
-
appender = appender.addAttribute('target', target)
|
85
|
-
appender = appender.add(layout)
|
86
|
-
config.add(appender)
|
87
|
-
|
88
|
-
# Create a root logger
|
89
|
-
root_logger = config.newRootLogger(log_level)
|
90
|
-
root_logger = root_logger.add(config.newAppenderRef('stdout'))
|
91
|
-
|
92
|
-
# Create a rolling file appender
|
93
|
-
cron = config.newComponent('CronTriggeringPolicy')
|
94
|
-
cron = cron.addAttribute('schedule', Logging.config[:schedule])
|
95
|
-
|
96
|
-
size = config.newComponent('SizeBasedTriggeringPolicy')
|
97
|
-
size = size.addAttribute('size', Logging.config[:size])
|
98
|
-
|
99
|
-
policies = config.newComponent('Policies')
|
100
|
-
policies = policies.addComponent(cron)
|
101
|
-
policies = policies.addComponent(size)
|
102
|
-
|
103
|
-
appender = config.newAppender('rolling_file', 'RollingFile')
|
104
|
-
appender = appender.addAttribute('fileName', server_log_file)
|
105
|
-
appender = appender.addAttribute('filePattern', rolling_log_file_path)
|
106
|
-
appender = appender.add(layout)
|
107
|
-
appender = appender.addComponent(policies)
|
108
|
-
config.add(appender)
|
109
|
-
|
110
|
-
root_logger = root_logger.addAttribute('additivity', false)
|
111
|
-
root_logger = root_logger.add(config.newAppenderRef('rolling_file'))
|
112
|
-
config.add(root_logger)
|
113
|
-
|
114
|
-
logging_configuration = config.build()
|
115
|
-
ctx = org.apache.logging.log4j.core.config::Configurator.initialize(logging_configuration)
|
116
|
-
ctx.updateLoggers()
|
117
|
-
end
|
118
|
-
# rubocop: enable Metrics/AbcSize
|
119
|
-
# rubocop: enable Metrics/MethodLength
|
120
|
-
# def init_log4j
|
121
|
-
end
|
122
|
-
# module LogInitialization
|
123
|
-
|
124
|
-
::LogInitialization.init
|
125
|
-
|
126
|
-
# The Apache log4j Logger class
|
127
|
-
# rubocop: disable Style/ClassAndModuleChildren
|
128
|
-
class org.apache.logging.log4j.core::Logger
|
129
|
-
alias log4j_error error
|
130
|
-
def error(error_or_message, error = nil)
|
131
|
-
return extract_backtrace(error_or_message) if error.nil?
|
132
|
-
log4j_error(generate_message(error_or_message, error))
|
133
|
-
extract_backtrace(error)
|
134
|
-
end
|
135
|
-
|
136
|
-
def generate_message(error_or_message, error)
|
137
|
-
error_message = "#{error_or_message}: #{error.class.name}"
|
138
|
-
error_message << ": #{error.message}" if error.respond_to?(:message)
|
139
|
-
error_message
|
140
|
-
end
|
141
|
-
|
142
|
-
def extract_backtrace(error, default_result = nil)
|
143
|
-
log4j_error(error)
|
144
|
-
if error.respond_to?(:backtrace)
|
145
|
-
error.backtrace.each { |trace| log4j_error(trace) unless trace.nil? }
|
146
|
-
elsif error.respond_to?(:getStackTrace)
|
147
|
-
error.getStackTrace().each { |trace| log4j_error(trace) unless trace.nil? }
|
148
|
-
else
|
149
|
-
default_result
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
# rubocop: enable Style/ClassAndModuleChildren
|
154
|
-
|
155
|
-
# The Logging module
|
156
|
-
module Logging
|
157
|
-
def init_logger(level = :all, logger_name = nil)
|
158
|
-
return init_java_logger(level, logger_name, caller[2]) if defined?(Java)
|
159
|
-
init_ruby_logger(level)
|
160
|
-
end
|
161
|
-
|
162
|
-
def init_ruby_logger(level)
|
163
|
-
logger_instance = Logger.new
|
164
|
-
logger_instance.level = Logging::Level.to_level(level.to_s.upcase)
|
165
|
-
logger_instance
|
166
|
-
end
|
167
|
-
|
168
|
-
# rubocop: disable Metrics/AbcSize
|
169
|
-
def init_java_logger(level, logger_name = nil, source_location = nil)
|
170
|
-
logger_name = get_formatted_logger_name(logger_name)
|
171
|
-
logger_name = source_location.split(/\//).last if logger_name.empty?
|
172
|
-
logger_instance = org.apache.logging.log4j.LogManager.getLogger(logger_name)
|
173
|
-
logger_instance.level = org.apache.logging.log4j.Level.to_level(level.to_s.upcase)
|
174
|
-
logger_instance
|
175
|
-
end
|
176
|
-
# rubocop: enable Metrics/AbcSize
|
177
|
-
|
178
|
-
def get_formatted_logger_name(logger_name = nil)
|
179
|
-
return logger_name.to_s[/\w+$/] unless logger_name.nil?
|
180
|
-
return name[/\w+$/] if is_a?(Class) || is_a?(Module)
|
181
|
-
self.class.name[/\w+$/]
|
182
|
-
end
|
183
|
-
|
184
|
-
def log(level = Logging.log_level, log_name = nil)
|
185
|
-
@log ||= init_logger(level, log_name)
|
186
|
-
end
|
187
|
-
alias logger log
|
188
|
-
|
189
|
-
module_function
|
190
|
-
|
191
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
192
|
-
# OFF: 0
|
193
|
-
# FATAL: 100
|
194
|
-
# ERROR: 200
|
195
|
-
# WARN: 300
|
196
|
-
# INFO: 400
|
197
|
-
# DEBUG: 500
|
198
|
-
# TRACE: 600
|
199
|
-
# ALL: 2147483647
|
200
|
-
# See: https://logging.apache.org/log4j/2.x/log4j-api/apidocs/org/apache/logging/log4j/Level.html
|
201
|
-
def symbolize_numeric_log_level(level)
|
202
|
-
case level
|
203
|
-
when 5..Float::INFINITY then :off
|
204
|
-
when 4 then :fatal
|
205
|
-
when 3 then :error
|
206
|
-
when 2 then :warn
|
207
|
-
when 1 then :info
|
208
|
-
when 0 then :debug
|
209
|
-
when -1 then :trace
|
210
|
-
when -2..-Float::INFINITY then :all
|
211
|
-
end
|
212
|
-
end
|
213
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
214
|
-
|
215
|
-
def log_level=(log_level)
|
216
|
-
Logging.config[:level] = symbolize_numeric_log_level(log_level)
|
217
|
-
end
|
218
|
-
|
219
|
-
def log_level
|
220
|
-
Logging.config[:level]
|
221
|
-
end
|
222
|
-
end
|
223
|
-
# module Logging
|
224
|
-
|
225
|
-
# The Module class
|
226
|
-
class Module
|
227
|
-
# Universally include Logging
|
228
|
-
include ::Logging
|
229
|
-
end
|
230
|
-
|
231
|
-
# The Class class
|
232
|
-
class Class
|
233
|
-
# Universally include Logging
|
234
|
-
include ::Logging
|
235
|
-
end
|
236
|
-
|
237
|
-
# The Object class
|
238
|
-
class Object
|
239
|
-
# Universally include Logging
|
240
|
-
include ::Logging
|
241
|
-
end
|