struct Log::Dexter

Defined in:

dexter/log.cr

Constant Summary

SEVERITY_MAP = {debug: Severity::Debug, info: Severity::Info, notice: Severity::Notice, warn: Severity::Warn, error: Severity::Error, fatal: Severity::Fatal}

Constructors

Instance Method Summary

Constructor Detail

def self.new(log : Log) #

[View source]

Instance Method Detail

def configure(severity : Log::Severity, backend : Log::Backend) : Nil #

Configure a Log and all child logs

This is a type-safe and simpler alternative to using Log.builder.bind. Rather than pass a string source you can configure a log using its class.

The backend can be left off and it will use the log's existing backend or a new Log::IOBackend

It also sets all child logs to the same configuration since this is the most common way to configure logs. If you want to configure a log and none of its children it is best to set the level or backend directly:

MyShard::Log.level = :error
MyShard::Log.backend = MyCustomBackend.new

Examples:

# Configure all logs.
# Similar to `Log.builder.bind "*"`
Log.dexter.configure(:info, backend)

# Configure Avram::Log and all child logs
# Similar to `Log.builder.bind "avram.*"
Avram::Log.dexter.configure(:warn)

# Can further customize child Logs
Avram::QueryLog.dexter.configure(:none)
Avram::FailedQueryLog.dexter.configure(:info, SomeOtherBackend.new)

[View source]
def debug(*, exception : Exception | Nil = nil, &block : -> NamedTuple | Hash) : Nil #

Logs key/value data in the Log::Context under the 'local' key

Log.dexter.debug { {path: "/comments", status: 200 }}

You can also pass an exception:

Log.dexter.debug(exception) { { query: "SELECT *" } }

[View source]
def error(*, exception : Exception | Nil = nil, &block : -> NamedTuple | Hash) : Nil #

Logs key/value data in the Log::Context under the 'local' key

Log.dexter.error { {path: "/comments", status: 200 }}

You can also pass an exception:

Log.dexter.error(exception) { { query: "SELECT *" } }

[View source]
def fatal(*, exception : Exception | Nil = nil, &block : -> NamedTuple | Hash) : Nil #

Logs key/value data in the Log::Context under the 'local' key

Log.dexter.fatal { {path: "/comments", status: 200 }}

You can also pass an exception:

Log.dexter.fatal(exception) { { query: "SELECT *" } }

[View source]
def info(*, exception : Exception | Nil = nil, &block : -> NamedTuple | Hash) : Nil #

Logs key/value data in the Log::Context under the 'local' key

Log.dexter.info { {path: "/comments", status: 200 }}

You can also pass an exception:

Log.dexter.info(exception) { { query: "SELECT *" } }

[View source]
def log : Log #

[View source]
def notice(*, exception : Exception | Nil = nil, &block : -> NamedTuple | Hash) : Nil #

Logs key/value data in the Log::Context under the 'local' key

Log.dexter.notice { {path: "/comments", status: 200 }}

You can also pass an exception:

Log.dexter.notice(exception) { { query: "SELECT *" } }

[View source]
def temp_config(io : IO = IO::Memory.new, level : Log::Severity = Log::Severity::Debug, formatter : Log::Formatter | Nil = nil, &) : Nil #

Temporarily reconfigure a Log

This is mostly helpful when running tests for your log messages. This can make sure you are logging what you expect to log.

If you leave off args the method will yield an IO::Memory and set the level to Debug so it logs all messages.

There are also options to configure the IO, Log::Severity, or Log::Formatter used.

Once the block ends or raises an exception the Log's configuration will be reverted to its original state.

Examples

MyShard::Log.dexter.temp_config do |log_io|
  MyShard::Log.info { "log me" }
  log_io.to_s.should contain("log me")
end

my_own_io = IO::Memory.new
MyShard::Log.dexter.temp_config(my_own_io) do
  MyShard::Log.info { "log me" }
  my_own_io.to_s.should contain("log me")
end

formatter = ::Log::Formatter.new do |entry, io|
  io << entry.severity
end

MyShard::Log.dexter.temp_config(level: :info, formatter: formatter) do |log_io|
  MyShard::Log.info { "log me" }
  # This is a useless test, but is here to show what can be done
  # with the formatter option. In this case, just log severity:
  my_own_io.to_s.chomp.should eq("Info")
end

You can use any combination of io, level, formatter. All are optional.


[View source]
def warn(*, exception : Exception | Nil = nil, &block : -> NamedTuple | Hash) : Nil #

Logs key/value data in the Log::Context under the 'local' key

Log.dexter.warn { {path: "/comments", status: 200 }}

You can also pass an exception:

Log.dexter.warn(exception) { { query: "SELECT *" } }

[View source]