Module: Bolt::Logger

Defined in:
lib/bolt/logger.rb

Class Method Summary collapse

Class Method Details

.analytics=(analytics) ⇒ Object



76
77
78
# File 'lib/bolt/logger.rb', line 76

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

.configure(destinations, color) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/bolt/logger.rb', line 30

def self.configure(destinations, color)
  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
end

.console_layout(color) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/bolt/logger.rb', line 80

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

.default_console_levelObject



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

def self.default_console_level
  :warn
end

.default_file_levelObject



99
100
101
# File 'lib/bolt/logger.rb', line 99

def self.default_file_level
  :warn
end

.default_layoutObject



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

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

.deprecation_warning(type, msg) ⇒ Object



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

def self.deprecation_warning(type, msg)
  @analytics&.event('Warn', 'deprecation', label: type)
  warn_once(type, 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.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/bolt/logger.rb', line 12

def self.initialize_logging
  # Initialization isn't idempotent and will result in warnings about const
  # redefs, so skip it if it's already been initialized
  return if Logging.initialized?

  Logging.init :trace, :debug, :info, :notice, :warn, :error, :fatal, :any
  @mutex = Mutex.new

  Logging.color_scheme(
    'bolt',
    lines: {
      warn: :yellow,
      error: :red,
      fatal: %i[white on_red]
    }
  )
end

.levelsObject



109
110
111
# File 'lib/bolt/logger.rb', line 109

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.



71
72
73
74
# File 'lib/bolt/logger.rb', line 71

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

.reset_loggingObject



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

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)


105
106
107
# File 'lib/bolt/logger.rb', line 105

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

.warn_once(type, msg) ⇒ Object



117
118
119
120
121
122
123
124
125
126
# File 'lib/bolt/logger.rb', line 117

def self.warn_once(type, msg)
  @mutex.synchronize {
    @warnings ||= []
    @logger ||= Bolt::Logger.logger(self)
    unless @warnings.include?(type)
      @logger.warn(msg)
      @warnings << type
    end
  }
end