Module: Logging

Defined in:
lib/tcp_server/logging.rb,
lib/tcp_server/logging.rb

Overview

The Logging class

Defined Under Namespace

Classes: Proxy

Constant Summary collapse

DEFAULT_TIME_FORMAT =
'%Y-%m-%d %H:%M:%S'.freeze
DEFAULT_APP_NAME =
'app'.freeze
DEFAULT_LOG_PATTERN =
'%d{ABSOLUTE} %-5p [%X{category}] %m%n'.freeze
DEFAULT_RUBY_LOG_FORMAT =
"%<timestamp>s %-5<severity>s %<category>s] %<msg>s\n".freeze
EMPTY_STRING =
''.freeze
NUMERIC_TO_SYMBOL =

rubocop: enable Metrics/MethodLength

{
  5 => :off,
  4 => :fatal,
  3 => :error,
  2 => :warn,
  1 => :info,
  0 => :debug,
  -1 => :trace
}.freeze
SYMBOL_TO_RUBY =
{
  off: Logger::FATAL,
  fatal: Logger::FATAL,
  error: Logger::ERROR,
  warn: Logger::WARN,
  info: Logger::INFO,
  debug: Logger::DEBUG,
  trace: Logger::DEBUG,
  all: Logger::DEBUG
}.freeze

Class Method Summary collapse

Class Method Details

.app_config(context_configuration, sym) ⇒ Object



234
235
236
237
238
239
# File 'lib/tcp_server/logging.rb', line 234

def app_config(context_configuration, sym)
  app_cfg = context_configuration.getLoggerConfig(app_logger_name)
  return app_cfg if !app_cfg.nil? && app_cfg.getName == app_logger_name

  init_app_logging_config(context_configuration, app_logger_name, sym)
end

.app_logger_nameObject



68
69
70
# File 'lib/tcp_server/logging.rb', line 68

def app_logger_name
  DEFAULT_APP_NAME
end

.app_nameObject



64
65
66
# File 'lib/tcp_server/logging.rb', line 64

def app_name
  DEFAULT_APP_NAME
end

.apply_backend_level(sym) ⇒ Object



221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/tcp_server/logging.rb', line 221

def apply_backend_level(sym)
  if jruby?
    ctx = @log4j2_context || LoggerContext.getContext(false)
    app_cfg = app_config(ctx.getConfiguration, sym)
    app_cfg.setLevel(symbol_to_java_level(sym))
    ctx.updateLoggers
  else
    backend.level = SYMBOL_TO_RUBY.fetch(sym, Logger::INFO)
  end

  sym
end

.backendObject



37
38
39
# File 'lib/tcp_server/logging.rb', line 37

def backend
  @backend ||= init_backend
end

.configure_log4jObject



102
103
104
105
# File 'lib/tcp_server/logging.rb', line 102

def configure_log4j
  @log4j2_context = Configurator.initialize(log4j_configuration.build)
  @log4j2_context.updateLoggers
end

.derive_category(receiver, callsite) ⇒ Object

rubocop: enable Metrics/AbcSize rubocop: enable Metrics/MethodLength



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/tcp_server/logging.rb', line 128

def derive_category(receiver, callsite)
  if receiver.is_a?(Module)
    receiver.name.to_s
  elsif receiver.respond_to?(:class) && receiver.class.respond_to?(:name)
    receiver.class.name.to_s
  else
    EMPTY_STRING
  end.tap do |cat|
    return cat unless cat.empty?
  end

  File.basename(callsite.path.to_s)
end

.dispatch(level, *args, &block) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/tcp_server/logging.rb', line 142

def dispatch(level, *args, &block)
  if jruby?
    backend.public_send(level, *args, &block)
  else
    case level
    when :fatal then backend.fatal(*args, &block)
    when :warn then backend.warn(*args, &block)
    else
      backend.public_send(level, *args, &block)
    end
  end
end

.init_app_logging_config(context_configuration, app_logger_name, sym) ⇒ Object



241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/tcp_server/logging.rb', line 241

def init_app_logging_config(context_configuration, app_logger_name, sym)
  app_cfg = LoggerConfig.newBuilder.withConfig(context_configuration)
    .withLoggerName(app_logger_name).withLevel(symbol_to_java_level(sym))
    .withAdditivity(false).build
  if (appender = context_configuration.getAppender('stdout')).nil?
    app_cfg.setAdditive(true)
  else
    app_cfg.addAppender(appender, Level::INFO, nil)
  end
  context_configuration.addLogger(app_logger_name, app_cfg)
  app_cfg
end

.init_backendObject



41
42
43
44
# File 'lib/tcp_server/logging.rb', line 41

def init_backend
  return init_log4j_backend if jruby?
  init_logger_backend
end

.init_log4j2!Object



91
92
93
94
95
96
97
98
99
100
# File 'lib/tcp_server/logging.rb', line 91

def init_log4j2!
  return if @log4j2_initialized

  Java::java.lang.System.setProperty(
    'log4j.shutdownHookEnabled', Java::java.lang.Boolean.toString(false))

  configure_log4j

  @log4j2_initialized = true
end

.init_log4j_backendObject



54
55
56
57
58
# File 'lib/tcp_server/logging.rb', line 54

def init_log4j_backend
  init_log4j2!
  apply_backend_level(log_level)
  LogManager.getLogger(app_logger_name)
end

.init_logger_backendObject



46
47
48
49
50
51
52
# File 'lib/tcp_server/logging.rb', line 46

def init_logger_backend
  log = Logger.new($stdout)
  log.formatter = method(:ruby_formatter)
  @backend = log
  apply_backend_level(log_level)
  log
end

.int_to_symbol_level(level) ⇒ Object



254
255
256
257
258
# File 'lib/tcp_server/logging.rb', line 254

def int_to_symbol_level(level)
  NUMERIC_TO_SYMBOL.fetch(level) do
    level > 5 ? :off : :all
  end
end

.java_log_patternObject



80
81
82
# File 'lib/tcp_server/logging.rb', line 80

def java_log_pattern
  DEFAULT_LOG_PATTERN
end

.log4j_configuration(config = ConfigurationBuilderFactory.newConfigurationBuilder) ⇒ Object

rubocop: disable Metrics/AbcSize rubocop: disable Metrics/MethodLength



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/tcp_server/logging.rb', line 109

def log4j_configuration(
    config = ConfigurationBuilderFactory.newConfigurationBuilder)
  layout = config.newLayout('PatternLayout')
    .addAttribute('pattern', java_log_pattern)
  console = config.newAppender('stdout', 'CONSOLE')
    .addAttribute('target', ConsoleAppender::Target::SYSTEM_OUT).add(layout)
  config.add(console)
  root = config.newRootLogger(Level::INFO)
    .add(config.newAppenderRef('stdout'))
  config.add(root)
  app_logger = config.newLogger(app_logger_name, Level::INFO)
    .add(config.newAppenderRef('stdout'))
    .addAttribute('additivity', false)
  config.add(app_logger)
  config
end

.log_levelObject



204
205
206
# File 'lib/tcp_server/logging.rb', line 204

def log_level
  @log_level ||= :info
end

.log_level=(level) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/tcp_server/logging.rb', line 208

def log_level=(level)
  @log_level = case level
  when Integer
    int_to_symbol_level(level)
  when Symbol, String
    level.to_s.downcase.to_sym
  else
    :info
  end

  apply_backend_level(@log_level)
end

.proxyObject



60
61
62
# File 'lib/tcp_server/logging.rb', line 60

def proxy
  @proxy ||= Proxy.new
end

.ruby_formatter(severity, datetime, _progname, msg) ⇒ Object



84
85
86
87
88
89
# File 'lib/tcp_server/logging.rb', line 84

def ruby_formatter(severity, datetime, _progname, msg)
  category = (Thread.current[:logging_category] || app_name).to_s
  timestamp = datetime.strftime(time_format)
  format(ruby_log_format, timestamp: timestamp, severity: severity,
    category: category, msg: msg)
end

.ruby_log_formatObject



76
77
78
# File 'lib/tcp_server/logging.rb', line 76

def ruby_log_format
  DEFAULT_RUBY_LOG_FORMAT
end

.symbol_to_java_level(sym) ⇒ Object

rubocop: disable Metrics/CyclomaticComplexity



261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/tcp_server/logging.rb', line 261

def symbol_to_java_level(sym)
  case sym
  when :off then Level::OFF
  when :fatal then Level::FATAL
  when :error then Level::ERROR
  when :warn then Level::WARN
  when :debug then Level::DEBUG
  when :trace then Level::TRACE
  when :all then Level::ALL
  else Level::INFO
  end
end

.time_formatObject



72
73
74
# File 'lib/tcp_server/logging.rb', line 72

def time_format
  DEFAULT_TIME_FORMAT
end

.with_category(category) ⇒ Object

rubocop: disable Metrics/MethodLength



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/tcp_server/logging.rb', line 156

def with_category(category)
  if jruby?
    prev = ThreadContext.get('category')

    begin
      ThreadContext.put('category', category)
      yield
    ensure
      if prev.nil?
        ThreadContext.remove('category')
      else
        ThreadContext.put('category', prev)
      end
    end
  else
    prev = Thread.current[:logging_category]

    begin
      Thread.current[:logging_category] = category
      yield
    ensure
      Thread.current[:logging_category] = prev
    end
  end
end