Module: Bolt::Logger

Defined in:
lib/bolt/logger.rb

Constant Summary collapse

LEVELS =
%w[trace debug info warn error fatal].freeze

Class Method Summary collapse

Class Method Details

.analytics=(analytics) ⇒ Object



101
102
103
# File 'lib/bolt/logger.rb', line 101

def self.analytics=(analytics)
  @analytics = analytics
end

.configure(destinations, color, disable_warnings = nil) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/bolt/logger.rb', line 45

def self.configure(destinations, color, disable_warnings = nil)
  root_logger = Bolt::Logger.logger(:root)

  root_logger.add_appenders Logging.appenders.stderr(
    'console',
    layout: console_layout(color),
    level: default_console_level
  )

  # We set the root logger's level so that it logs everything but we do
  # limit what's actually logged in every appender individually.
  root_logger.level = :all

  destinations.each_pair do |name, params|
    appender = Logging.appenders[name]
    if appender.nil?
      unless name.start_with?('file:')
        raise Bolt::Error.new("Unexpected log: #{name}", 'bolt/internal-error')
      end

      begin
        appender = Logging.appenders.file(
          name,
          filename: name[5..-1], # strip the "file:" prefix
          truncate: (params[:append] == false),
          layout: default_layout,
          level: default_file_level
        )
      rescue ArgumentError => e
        raise Bolt::Error.new("Failed to open log #{name}: #{e.message}", 'bolt/log-error')
      end

      root_logger.add_appenders appender
    end

    appender.level = params[:level] if params[:level]
  end

  # Set the list of disabled warnings and mark the logger as configured.
  # Log all messages in the message queue and flush the queue.
  if disable_warnings
    @mutex.synchronize { @disable_warnings = disable_warnings }
  end
end

.configured?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/bolt/logger.rb', line 90

def self.configured?
  Logging.logger[:root].appenders.any?
end

.console_layout(color) ⇒ Object



105
106
107
108
109
110
111
# File 'lib/bolt/logger.rb', line 105

def self.console_layout(color)
  color_scheme = :bolt if color
  Logging.layouts.pattern(
    pattern: '%m\e[0m\n',
    color_scheme: color_scheme
  )
end

.debug(msg) ⇒ Object



166
167
168
# File 'lib/bolt/logger.rb', line 166

def self.debug(msg)
  log(type: :debug, msg: msg)
end

.default_console_levelObject



120
121
122
# File 'lib/bolt/logger.rb', line 120

def self.default_console_level
  :warn
end

.default_file_levelObject



124
125
126
# File 'lib/bolt/logger.rb', line 124

def self.default_file_level
  :warn
end

.default_layoutObject



113
114
115
116
117
118
# File 'lib/bolt/logger.rb', line 113

def self.default_layout
  Logging.layouts.pattern(
    pattern: '%d %-6l [%T] [%c] %m\n',
    date_pattern: '%Y-%m-%dT%H:%M:%S.%6N'
  )
end

.deprecate(id, msg) ⇒ Object



158
159
160
# File 'lib/bolt/logger.rb', line 158

def self.deprecate(id, msg)
  log(type: :deprecate, msg: "#{msg} [ID: #{id}]", id: id)
end

.deprecate_once(id, msg) ⇒ Object



162
163
164
# File 'lib/bolt/logger.rb', line 162

def self.deprecate_once(id, msg)
  log(type: :deprecate_once, msg: "#{msg} [ID: #{id}]", id: id)
end

.flush_queueObject

Logs all messages in the message queue and then flushes the queue.



195
196
197
198
199
200
201
202
203
# File 'lib/bolt/logger.rb', line 195

def self.flush_queue
  @mutex.synchronize do
    @message_queue.each do |message|
      log_message(message)
    end

    @message_queue.clear
  end
end

.info(msg) ⇒ Object



170
171
172
# File 'lib/bolt/logger.rb', line 170

def self.info(msg)
  log(type: :info, msg: msg)
end

.initialize_loggingObject

This method provides a single point-of-entry to setup logging for both the CLI and for tests. This is necessary because we define custom log levels which create corresponding methods on the logger instances; without first initializing the Logging system, calls to those methods will fail.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/bolt/logger.rb', line 22

def self.initialize_logging
  # Initialization isn't idempotent and will result in warnings about const
  # redefs, so skip it if the log levels we expect are present. If it's
  # already been initialized with an insufficient set of levels, go ahead
  # and call init anyway or we'll have failures when calling log methods
  # for missing levels.
  unless levels & LEVELS == LEVELS
    Logging.init(*LEVELS)
  end

  # As above, only create the color scheme if we haven't already created it.
  unless Logging.color_scheme('bolt')
    Logging.color_scheme(
      'bolt',
      lines: {
        warn: :yellow,
        error: :red,
        fatal: i[white on_red]
      }
    )
  end
end

.levelsObject



134
135
136
# File 'lib/bolt/logger.rb', line 134

def self.levels
  Logging::LNAMES.map(&:downcase)
end

.logger(name) ⇒ Object

A helper to ensure the Logging library is always initialized with our custom log levels before retrieving a Logger instance.



96
97
98
99
# File 'lib/bolt/logger.rb', line 96

def self.logger(name)
  initialize_logging
  Logging.logger[name]
end

.reset_loggingObject



138
139
140
# File 'lib/bolt/logger.rb', line 138

def self.reset_logging
  Logging.reset
end

.valid_level?(level) ⇒ Boolean

Explicitly check the log level names instead of the log level number, as levels that are stringified integers (e.g. “level” => “42”) will return a truthy value

Returns:

  • (Boolean)


130
131
132
# File 'lib/bolt/logger.rb', line 130

def self.valid_level?(level)
  Logging::LEVELS.include?(Logging.levelify(level))
end

.warn(id, msg) ⇒ Object

The following methods are used in place of the Logging.logger methods of the same name when logging warning messages or logging any messages prior to the logger being configured. If the logger is not configured when any of these methods are called, the message will be added to a queue, otherwise they are logged immediately. The message queue is flushed by calling #flush_queue, which is called from Bolt::CLI after configuring the logger.



150
151
152
# File 'lib/bolt/logger.rb', line 150

def self.warn(id, msg)
  log(type: :warn, msg: "#{msg} [ID: #{id}]", id: id)
end

.warn_once(id, msg) ⇒ Object



154
155
156
# File 'lib/bolt/logger.rb', line 154

def self.warn_once(id, msg)
  log(type: :warn_once, msg: "#{msg} [ID: #{id}]", id: id)
end