The Log
class provides a logging utility that you can use to output messages.
The messages, or Log::Entry
have associated levels, such as Info
or Error
that indicate their importance. See Log::Severity
.
To log a message #trace
, #debug
, #info
, #notice
, #warn
, #error
, and #fatal
methods can be used. They expect a block that will evaluate to the message of the entry.
require "log" Log.info { "Program started" }
Data can be associated with a log entry via the Log::Emitter
yielded in the logging methods.
Log.info &.emit("User logged in", user_id: 42)
If you want to log an exception, you can indicate it in the exception:
named argument.
Log.warn(exception: e) { "Oh no!" } Log.warn exception: e, &.emit("Oh no!", user_id: 42)
The block is only evaluated if the current message is to be emitted to some Log::Backend
.
To add structured information to the message you can use the Log::Context
.
When creating log messages they belong to a source. If the top-level Log
is used as in the above examples its source is the empty string.
The source can be used to identify the module or part of the application that is logging. You can configure for each source a different level to filter the messages.
A recommended pattern is to declare a Log
constant in the namespace of your shard or module as follows:
module DB Log = ::Log.for("db") # => Log for db source def do_something Log.info { "this is logged in db source" } end end DB::Log.info { "this is also logged in db source" } Log.for("db").info { "this is also logged in db source" } Log.info { "this is logged in top-level source" }
That way, any Log.info
call within the DB
module will use the db
source. And not the top-level ::Log.info
.
Sources can be nested. Continuing the last example, to declare a Log
constant db.pool
source you can do as follows:
class DB::Pool Log = DB::Log.for("pool") # => Log for db.pool source end
A Log
will emit the messages to the Log::Backend
s attached to it as long as the configured severity filter #level
permits it.
Logs can also be created from a type directly. For the type DB::Pool
the source db.pool
will be used. For generic types as Foo::Bar(Baz)
the source foo.bar
will be used (i.e. without generic arguments).
module DB Log = ::Log.for(self) # => Log for db source end
By default entries from all sources with Info
and above severity will be logged to STDOUT
using the Log::IOBackend
.
If you need to change the default level, backend or sources call Log.setup
upon startup.
Log.setup(:debug) # Log debug and above for all sources to STDOUT Log.setup("myapp.*, http.*", :notice) # Log notice and above for myapp.* and http.* sources only, and log nothing for any other source. backend_with_formatter = Log::IOBackend.new(formatter: custom_formatter) Log.setup(:debug, backend_with_formatter) # Log debug and above for all sources to using a custom backend
Use Log.setup
methods to indicate which sources should go to which backends.
You can indicate actual sources or patterns.
*
matches all the sourcesfoo.bar.*
matches foo.bar
and every nested sourcefoo.bar
matches foo.bar
, but not its nested sourcesThe following configuration will setup for all sources to emit warnings (or higher) to STDOUT
, allow any of the db.*
and nested source to emit debug (or higher), and to also emit for all sources errors (or higher) to an elasticsearch backend.
Log.setup |c| backend = Log::IOBackend.new c.bind "*", :warn, backend c.bind "db.*", :debug, backend c.bind "*", :error, ElasticSearchBackend.new("http://localhost:9200") end
Include the following line to allow configuration from environment variables.
Log.setup_from_env
The environment variable LOG_LEVEL
is used to indicate which severity level to emit. By default entries from all sources with Info
and above severity will be logged to STDOUT
using the Log::IOBackend
.
To change the level and sources change the environment variable value:
$ LOG_LEVEL=DEBUG ./bin/app
You can tweak the default values (used when LOG_LEVEL
variable is not defined):
Log.setup_from_env(default_level: :error)
Creates a Log
for the given type.
Creates a Log
for the given source.
Returns the default Log::Builder
used for Log.for
calls.
Returns and yields an EntriesChecker
that allows checking specific log entries were emitted.
Returns and yields an EntriesChecker
that allows checking specific log entries were emitted.
Returns the current fiber logging context.
Sets the current fiber logging context.
Sets the current fiber logging context.
See Log#debug
.
See Log#error
.
See Log#fatal
.
See Log#info
.
See Log#notice
.
The program name used for log entries
The program name used for log entries
Setups logging bindings discarding all previous configurations.
Setups logging for sources using the specified level, backend.
Setups logging for all sources using the specified level, backend.
DEPRECATED Use default_level, default_sources named arguments
Setups logging based on LOG_LEVEL
environment variable.
See Log#trace
.
See Log#warn
.
Method to save and restore the current logging context.
Returns the current fiber logging context.
Sets the current fiber logging context.
Logs a message if the logger's current severity is lower or equal to 1
.
Logs a message if the logger's current severity is lower or equal to 5
.
Logs a message if the logger's current severity is lower or equal to 6
.
Creates a Log
for the given nested source.
Creates a Log
for the given type.
Logs a message if the logger's current severity is lower or equal to 2
.
Change this log severity level filter.
Logs a message if the logger's current severity is lower or equal to 3
.
Logs a message if the logger's current severity is lower or equal to 0
.
Logs a message if the logger's current severity is lower or equal to 4
.
Method to save and restore the current logging context.
Generate subclasses of Log::StaticFormatter
from a string with interpolations
Reference
Reference
Object
Object
Creates a Log
for the given type. A type Foo::Bar(Baz)
corresponds to the source foo.bar
. If level is given, it will override the configuration.
Creates a Log
for the given source. If level is given, it will override the configuration.
Returns the default Log::Builder
used for Log.for
calls.
Returns and yields an EntriesChecker
that allows checking specific log entries were emitted.
This capture will even work if there are currently no backends configured, effectively adding a temporary backend.
require "spec" require "log" require "log/spec" Log.setup(:none) def greet(name) Log.info { "Greeting #{name}" } end it "greets" do Log.capture do |logs| greet("Harry") greet("Hermione") greet("Ron") logs.check(:info, /greeting harry/i) logs.next(:info, /greeting hermione/i) end end
By default logs of all sources and severities will be captured.
Use level to only capture of the given severity or above.
Use source to narrow which source are captured. Values that represent single pattern like http.*
are allowed.
The EntriesChecker
will hold a list of emitted entries.
EntriesChecker#check
will find the next entry which matches the level and message. EntriesChecker#next
will validate that the following entry in the list matches the given level and message. EntriesChecker#clear
will clear the emitted and captured entries.
With these methods it is possible to express expected traces in either a strict or loose way, while checking ordering.
EntriesChecker#entry
returns the last matched Entry
. Useful to check additional entry properties other than the message.
EntriesChecker#empty
validates there are no pending entries to match.
Using the yielded EntriesChecker
allows clearing the entries between statements.
Invocations can be nested in order to capture each source in their own EntriesChecker
.
Returns and yields an EntriesChecker
that allows checking specific log entries were emitted.
This capture will even work if there are currently no backends configured, effectively adding a temporary backend.
require "spec" require "log" require "log/spec" Log.setup(:none) def greet(name) Log.info { "Greeting #{name}" } end it "greets" do Log.capture do |logs| greet("Harry") greet("Hermione") greet("Ron") logs.check(:info, /greeting harry/i) logs.next(:info, /greeting hermione/i) end end
By default logs of all sources and severities will be captured.
Use level to only capture of the given severity or above.
Use source to narrow which source are captured. Values that represent single pattern like http.*
are allowed.
The EntriesChecker
will hold a list of emitted entries.
EntriesChecker#check
will find the next entry which matches the level and message. EntriesChecker#next
will validate that the following entry in the list matches the given level and message. EntriesChecker#clear
will clear the emitted and captured entries.
With these methods it is possible to express expected traces in either a strict or loose way, while checking ordering.
EntriesChecker#entry
returns the last matched Entry
. Useful to check additional entry properties other than the message.
EntriesChecker#empty
validates there are no pending entries to match.
Using the yielded EntriesChecker
allows clearing the entries between statements.
Invocations can be nested in order to capture each source in their own EntriesChecker
.
Returns the current fiber logging context.
Sets the current fiber logging context.
Sets the current fiber logging context.
See Log#notice
.
The program name used for log entries
Defaults to the executable name
The program name used for log entries
Defaults to the executable name
Setups logging bindings discarding all previous configurations.
Setups logging for sources using the specified level, backend.
Setups logging for all sources using the specified level, backend.
DEPRECATED Use default_level, default_sources named arguments
Setups logging based on LOG_LEVEL
environment variable.
Method to save and restore the current logging context.
Log.context.set a: 1 Log.info { %(message with {"a" => 1} context) } Log.with_context do Log.context.set b: 2 Log.info { %(message with {"a" => 1, "b" => 2} context) } end Log.info { %(message with {"a" => 1} context) }
Returns the current fiber logging context.
Sets the current fiber logging context.
Logs a message if the logger's current severity is lower or equal to 1
.
Logs a message if the logger's current severity is lower or equal to 5
.
Logs a message if the logger's current severity is lower or equal to 6
.
Creates a Log
for the given nested source. If level is given, it will override the configuration.
Creates a Log
for the given type. A type Foo::Bar(Baz)
corresponds to the source foo.bar
. If level is given, it will override the configuration.
Logs a message if the logger's current severity is lower or equal to 2
.
Logs a message if the logger's current severity is lower or equal to 3
.
Logs a message if the logger's current severity is lower or equal to 0
.
Logs a message if the logger's current severity is lower or equal to 4
.
Method to save and restore the current logging context.
Log.context.set a: 1 Log.info { %(message with {"a" => 1} context) } Log.with_context do Log.context.set b: 2 Log.info { %(message with {"a" => 1, "b" => 2} context) } end Log.info { %(message with {"a" => 1} context) }
Generate subclasses of Log::StaticFormatter
from a string with interpolations
Example:
Log.define_formatter MyFormat, "- #{severity}: #{message}"
See Log::StaticFormatter
for the available methods that can be called within the interpolations.
© 2012–2020 Manas Technology Solutions.
Licensed under the Apache License, Version 2.0.
https://crystal-lang.org/api/0.35.1/Log.html