module Logit

Overview

Logit - Annotation-based logging with OpenTelemetry support for Crystal.

Logit provides automatic method instrumentation through annotations, structured logging with wide events, and full OpenTelemetry compatibility. Simply annotate methods with @[Logit::Log] and Logit handles the rest.

Quick Start

require "logit"

# Configure Logit (optional - defaults to console output)
Logit.configure do |config|
  config.console(level: Logit::LogLevel::Debug)
end

class MyService
  @[Logit::Log]
  def process(data : String) : String
    data.upcase
  end
end

Annotation Options

The @[Logit::Log] annotation supports the following options:

Key Features

See Logit.configure for configuration options and Logit::Backend for available output backends.

Defined in:

logit/api.cr
logit/backend.cr
logit/backends/buffered.cr
logit/backends/console.cr
logit/backends/file.cr
logit/backends/null.cr
logit/backends/otlp.cr
logit/backends/otlp/batch_processor.cr
logit/backends/otlp/config.cr
logit/backends/otlp/http_client.cr
logit/backends/otlp/payload_builder.cr
logit/config.cr
logit/context.cr
logit/events/attributes.cr
logit/events/event.cr
logit/formatter.cr
logit/formatters/human.cr
logit/formatters/json.cr
logit/integrations/crystal_log_adapter.cr
logit/log_level.cr
logit/logit.cr
logit/macros/metadata.cr
logit/macros/register.cr
logit/macros/wrapper.cr
logit/namespace_binding.cr
logit/pattern_matcher.cr
logit/redaction.cr
logit/tracing/span.cr
logit/tracing/tracer.cr
logit/utils/id_generator.cr
logit/utils/safe_output.cr
logit/version.cr

Constant Summary

VERSION = "0.1.0"

Class Method Summary

Macro Summary

Class Method Detail

def self.add_context(hash : Hash(String, String)) : Nil #

Adds method-local context from a hash.


[View source]
def self.add_context(named_tuple : NamedTuple) : Nil #

Adds method-local context from a named tuple.


[View source]
def self.add_context(**kwargs) : Nil #

Adds method-local context that is cleared after the current method completes.

@[Logit::Log]
def process(item : Item) : Bool
  Logit.add_context(item_type: item.type)
  # ... context is included in this method's log event
  true
end  # context cleared here

[View source]
def self.add_fiber_context(hash : Hash(String, String)) : Nil #

Adds fiber-local context from a hash.


[View source]
def self.add_fiber_context(named_tuple : NamedTuple) : Nil #

Adds fiber-local context from a named tuple.


[View source]
def self.add_fiber_context(**kwargs) : Nil #

Adds fiber-local context that persists across method calls in this fiber.

Use this for request-scoped data like request IDs or user information.

# At the start of a request
Logit.add_fiber_context(request_id: request.id, user_id: current_user.id)

# All logs in this fiber now include request_id and user_id
process_request
save_data

# At the end of the request
Logit.clear_fiber_context

[View source]
def self.clear_context : Nil #

Clears all method-local context.


[View source]
def self.clear_fiber_context : Nil #

Clears all fiber-local context.


[View source]
def self.configure(&) : Config #

Configures Logit with the provided block and applies the configuration.

This is the main entry point for setting up Logit. The configuration is applied immediately after the block completes.

Logit.configure do |config|
  config.console(level: Logit::LogLevel::Debug)
  config.file("logs/app.log")
  config.redact_common_patterns
end

If you don't call .configure, Logit uses a default console backend at Info level.


[View source]
def self.debug(message : String, **kwargs) : Nil #

Logs a message at Debug level.


[View source]
def self.debug(**kwargs, &block : -> String) : Nil #

Logs a message at Debug level with lazy evaluation.


[View source]
def self.error(message : String, **kwargs) : Nil #

Logs a message at Error level.


[View source]
def self.error(**kwargs, &block : -> String) : Nil #

Logs a message at Error level with lazy evaluation.


[View source]
def self.exception(message : String, ex : Exception, level : LogLevel, **kwargs) : Nil #

Logs an exception at a specific level.


[View source]
def self.exception(message : String, ex : Exception, **kwargs) : Nil #

Logs an exception with full details at Error level.


[View source]
def self.fatal(message : String, **kwargs) : Nil #

Logs a message at Fatal level.


[View source]
def self.fatal(**kwargs, &block : -> String) : Nil #

Logs a message at Fatal level with lazy evaluation.


[View source]
def self.get_context(key : String) : String | Nil #

Gets a method-local context value.


[View source]
def self.get_fiber_context(key : String) : String | Nil #

Gets a fiber-local context value.


[View source]
def self.info(message : String, **kwargs) : Nil #

Logs a message at Info level.


[View source]
def self.info(**kwargs, &block : -> String) : Nil #

Logs a message at Info level with lazy evaluation.


[View source]
def self.trace(message : String, **kwargs) : Nil #

Logs a message at Trace level.


[View source]
def self.trace(**kwargs, &block : -> String) : Nil #

Logs a message at Trace level with lazy evaluation.


[View source]
def self.warn(message : String, **kwargs) : Nil #

Logs a message at Warn level.


[View source]
def self.warn(**kwargs, &block : -> String) : Nil #

Logs a message at Warn level with lazy evaluation.


[View source]

Macro Detail

macro logit_add_context(**kwargs) #

Add key-value pairs to the current logging context


[View source]
macro logit_with_context(**kwargs, &block) #

Execute a block with additional context that is automatically removed after


[View source]
macro setup_instrumentation(type_name) #

Setup macro to be called at the END of a class definition (for manual instrumentation) This generates wrapper methods for all @Log annotated methods Note: In most cases, you should rely on the global macro finished hook instead


[View source]