class Logbuch::Tracer

Overview

Converts one traced value into trace data. It carries the detail, the limits for the value being converted, and the path of objects from the traced value down to that value, which cuts reference cycles and limits nesting. The item and length limits hold for the value being converted only; the depth limit is handed down to the values inside it.

A value takes a level of nesting when it can hold other values: an object, a collection, a tuple or named tuple, and a struct logged by its fields or with inspect. Strings, numbers, Bool, Nil, characters, symbols, enums, Time, the value types such as UUID, Path and URI, and a struct with a to_trace of its own take none, so they are logged by value at the depth limit; the values such a to_trace converts take their own levels. An object with a to_trace of its own takes a level, since unlike a struct it can contain itself.

A type controls how it appears in a trace by defining to_trace(tracer : Logbuch::Tracer) : Log::Metadata::Value, and converts the values it contains with #convert. A Logbuch.convert there, or a traced method it calls, continues the conversion with a detail and limits of its own but the same path, so cycles and DEPTH_CEILING still cut it off:

class JobQueue
  def to_trace(tracer : Logbuch::Tracer) : Log::Metadata::Value
    @lock.synchronize { tracer.convert(@jobs) }
  end
end

Defined in:

logbuch/tracer.cr

Instance Method Summary

Instance methods inherited from class Reference

inspect(io : IO) : Nil inspect

Instance methods inherited from class Object

to_trace(tracer : Logbuch::Tracer) : Log::Metadata::Value to_trace

Instance Method Detail

def cap : UInt32 #

The items the array, deque, set, slice or hash being converted may show, its cap; the rest are counted. It holds for that collection only: #convert gives each value inside it the settings again.


[View source]
def convert(value, *, cap : UInt32 | Nil = nil, length : UInt32 | Nil = nil) : Log::Metadata::Value #

Converts value, a value inside the one being converted. It gets the limits of Logbuch.settings unless cap or length set its own, which hold for value itself, not for the values inside it: cap limits the items of an array, deque, set, slice or hash, and length cuts a string, the keys of a hash, an exception's message, inspect text or an identity. The limits are unsigned, so a negative one fails to compile.

An object or collection that is already on the path is a cycle, and a value that takes a level of nesting is not shown at the depth limit, nor is any other object or struct nested DEPTH_CEILING levels deep: each converts to its identity instead, as Detail::Id logs it, such as "a", #<Order:0x10a3f2c40> or #<Point>.


[View source]
def convert(value, *, cap : UInt32 | Nil = nil, length : UInt32 | Nil = nil, &) : Log::Metadata::Value #

Converts what the block returns for value instead of value, like #convert. If the block raises, or converting its result does, the trace shows a placeholder naming the exception class.


[View source]
def detail : Detail #

How much of each value goes into the trace.


[View source]
def length : UInt32 #

The characters the string being converted may show, or the keys of the hash, or the inspect text or exception message of the value being converted. It holds for that value only, like #cap.


[View source]