Class: Gallus::Log

Inherits:
Object
  • Object
show all
Defined in:
lib/gallus/log.rb

Overview

Public: The brain of logging. All defined loggers inherit from this class.

Constant Summary collapse

@@global_context_mutex =

Global context requires a semaphore to be thread-safe.

Mutex.new
@@global_context =

Global context stores context variables that will be printed by any logger alongside with its local information.

{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, name) {|_self| ... } ⇒ Log

Internal: Constructs new logger with configuration inherited from given parent. Yields itself so it can be reconfigured with a block. Don’t use this method directly. Use Gallus::Log.configure class method if you wanna define or reconfigure a logger.

Yields:

  • (_self)

Yield Parameters:

  • _self (Gallus::Log)

    the object that the method was called on



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/gallus/log.rb', line 101

def initialize(parent, name, &block)
  @parent, @name = parent, name.to_s

  if parent
    @output = @parent.output.dup
    self.level = @parent.level
  end

  @output ||= []

  yield self if block_given?
end

Instance Attribute Details

#levelObject

Public: Logger name, log level and context serializtion handler.



90
91
92
# File 'lib/gallus/log.rb', line 90

def level
  @level
end

#nameObject

Public: Logger name, log level and context serializtion handler.



90
91
92
# File 'lib/gallus/log.rb', line 90

def name
  @name
end

#outputObject (readonly)

Public: A list with configured outputs.



93
94
95
# File 'lib/gallus/log.rb', line 93

def output
  @output
end

#parentObject (readonly)

Internal: Parent logger. Used for testing purposes.



96
97
98
# File 'lib/gallus/log.rb', line 96

def parent
  @parent
end

Class Method Details

.[](name) ⇒ Object

Public: Returns logger registered under given name.



27
28
29
# File 'lib/gallus/log.rb', line 27

def [](name)
  configure(name)
end

.configure(name = '', &block) ⇒ Object

Public: Configures logger with given name. When no name specified, root logger will be configured.

Example:

Gallus::Log.configure do |log|
  log.level = :INFO
  log.output << -> (event) { puts event.inspect }
end

Returns configured logger.



22
23
24
# File 'lib/gallus/log.rb', line 22

def configure(name = '', &block)
  Repository.get_or_create_logger(name, &block)
end

.current_thread_context {|(Thread.current[:log_context] ||= {})| ... } ⇒ Object

Public: Yields context for current thread. Just to conform with the behavior of #global_context we’re using block call here as well.

Example:

log.current_thread_context { |ctx| ctx[:location] = "Castle Black" }
log.info("I know nothing!", name: "Jon Snow")
# => I know nothing! name="Jon Snow" location="Castle Black"

Yields:

  • ((Thread.current[:log_context] ||= {}))


79
80
81
# File 'lib/gallus/log.rb', line 79

def current_thread_context
  yield (Thread.current[:log_context] ||= {})
end

.define_log_methods!(log_level) ⇒ Object

Internal: Performance magic. It dynamically defines log level methods to avoid overhead of not-logged levels. For example if log level is WARN it’ll define empty ‘trace`, `debug` and `info` methods and fully working `warn` and `error`. Effectively log methods call `log` under the hood.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/gallus/log.rb', line 39

def define_log_methods!(log_level)
  Level.each do |level|
    method_name = level.name.downcase
    remove_method(method_name) if method_defined?(method_name)

    if level >= log_level
      define_method(method_name) do |message = nil, payload = {}, &block|
        log(level, message, payload, &block)
      end
    else
      define_method(method_name) do |message = nil, payload = {}, &block|
        # supressed...
      end
    end
  end
end

.delete(name) ⇒ Object

Internal: For testing purposes we should be able to remove logger with given name.



32
33
34
# File 'lib/gallus/log.rb', line 32

def delete(name)
  Repository.delete_with_children(name)
end

.global_contextObject

Public: Yields global context. Only block calls are allowed since this operation must be thread-safe.

Example:

log.global_context { |ctx| ctx[:location] = "Castle Black" }
samwell_log.info("I always wanted to be a Wizard", name: "Samwell Tarly")
# => I always wanted to be a Wizard; name="Samwell Tarly" location="Castle Black"
jon_snow_log.info("I know nothing", name: "Jon Snow")
# => I know nothing; name="Jon Snow" location="Castle Black"


66
67
68
# File 'lib/gallus/log.rb', line 66

def global_context
  @@global_context_mutex.synchronize { yield @@global_context }
end

.rootObject

Public: Returns root logger.



84
85
86
# File 'lib/gallus/log.rb', line 84

def root
  @@root
end

Instance Method Details

#current_thread_context(&block) ⇒ Object

Public: Shortand to Gallus::Log.current_thread_context.



128
129
130
# File 'lib/gallus/log.rb', line 128

def current_thread_context(&block)
  self.class.current_thread_context(&block)
end

#global_context(&block) ⇒ Object

Public: Shortand to Gallus::Log.global_context.



123
124
125
# File 'lib/gallus/log.rb', line 123

def global_context(&block)
  self.class.global_context(&block)
end