Class: LLM::Tracer::EnhancedLogger

Inherits:
Tracer
  • Object
show all
Defined in:
lib/llm/tracer/enhanced_logger.rb

Overview

The LLM::Tracer::EnhancedLogger class writes a readable log of every chat request, tool call and interrupt, then a summary when the tracer exits. Color is used when the IO the tracer writes to is a terminal.

Examples:

llm = LLM.openai(key: ENV["KEY"])
llm.tracer = LLM::Tracer.enhanced_logger(llm)

Writing to a file

llm.tracer = LLM::Tracer.enhanced_logger(llm, path: "log.txt")

Constant Summary collapse

RULE =

Returns The width of a rule.

Returns:

  • (Integer) —

    The width of a rule

58

Instance Method Summary collapse

Constructor Details

#initialize(llm, options = {}) ⇒ EnhancedLogger

Returns a new instance of EnhancedLogger.

Parameters:

  • llm (LLM::Provider) —

    A provider

  • options (Hash) (defaults to: {}) —

    A hash of options



24
25
26
27
# File 'lib/llm/tracer/enhanced_logger.rb', line 24

def initialize(llm, options = {})
  super
  setup!(**options)
end

Instance Method Details

#on_exit ⇒ nil

Writes the summary, then closes the file the tracer opened.

Returns:

  • (nil)


111
112
113
114
115
116
# File 'lib/llm/tracer/enhanced_logger.rb', line 111

def on_exit
  summary
  @file&.close
  @file = nil
  nil
end

#on_request_start(operation:, model: nil, request_id:)

This method returns an undefined value.

Parameters:

  • operation (String)
  • model (String) (defaults to: nil)
  • inputs (Hash, nil) —

    Optional span attributes (e.g. gen_ai.input.messages) from llm.rb or caller.

  • request_id (String) —

    The id of the request. It is a UUIDv7, and it is shared by #on_request_start, #on_request_finish, and #on_request_error for the same request.



32
33
34
35
36
37
38
39
# File 'lib/llm/tracer/enhanced_logger.rb', line 32

def on_request_start(operation:, model: nil, request_id:, **)
  @model = model || @model
  @started[request_id] = clock
  return unless operation == "chat"
  @counts.requests += 1
  header
  say "#{paint("->", :cyan)} #{llm.name}#{model ? " #{model}" : ""}"
end

#on_request_finish(operation:, res:, request_id:)

This method returns an undefined value.

Parameters:

  • operation (String)
  • res (LLM::Response)
  • span (Object, nil)
  • model (String)
  • outputs (Hash, nil) —

    Optional span attributes (e.g. gen_ai.output.messages) from llm.rb or caller.

  • metadata (Hash, nil) —

    Optional metadata from llm.rb or caller.

  • request_id (String) —

    The id of the request that can be matched back to #on_request_start



44
45
46
47
48
49
50
51
52
# File 'lib/llm/tracer/enhanced_logger.rb', line 44

def on_request_finish(operation:, res:, request_id:, **)
  elapsed = elapsed!(request_id)
  return unless operation == "chat"
  tokens = format_tokens(res)
  parts = [paint("<-", :green)]
  parts << format("%.2fs", elapsed) if elapsed
  parts << tokens if tokens
  say parts.join("  ")
end

#on_request_error(ex:)

This method returns an undefined value.

Parameters:



57
58
59
60
# File 'lib/llm/tracer/enhanced_logger.rb', line 57

def on_request_error(ex:, **)
  @counts.errors += 1
  say "#{paint("!!", :red)} #{ex.class}: #{ex.message}"
end

#on_tool_start(id:, name:, arguments:) ⇒ LLM::Object

Returns The span an ending is handed, with the call's id and name.

Parameters:

  • id (String) —

    The tool call ID assigned by the model/provider

  • name (String) —

    The tool (function) name.

  • arguments (Hash) —

    The parsed tool arguments.

  • model (String) —

    The model name

Returns:

  • (LLM::Object) —

    The span an ending is handed, with the call's id and name



66
67
68
69
70
71
# File 'lib/llm/tracer/enhanced_logger.rb', line 66

def on_tool_start(id:, name:, arguments:, **)
  @spans[id] = clock
  @counts.tools[name] = @counts.tools.fetch(name, 0) + 1
  say "   #{paint("..", :yellow)} #{name}(#{format_arguments(arguments)})"
  LLM::Object.from(id:, name:)
end

#on_tool_finish(result:)

This method returns an undefined value.

Parameters:



76
77
78
79
80
81
82
83
# File 'lib/llm/tracer/enhanced_logger.rb', line 76

def on_tool_finish(result:, **)
  duration = span!(result.id)
  if duration && (@counts.slowest.nil? || duration > @counts.slowest.last)
    @counts.slowest = [result.name, duration]
  end
  timing = duration ? "  #{format("%.2fs", duration)}" : ""
  say "   #{paint("ok", :green)} #{result.name}#{timing}"
end

#on_tool_error(ex:)

This method returns an undefined value.

Parameters:



88
89
90
91
# File 'lib/llm/tracer/enhanced_logger.rb', line 88

def on_tool_error(ex:, **)
  @counts.failed += 1
  say "   #{paint("no", :red)} #{ex.value[:type]}: #{ex.value[:message]}"
end

#on_tool_interrupt(ex:, span:)

This method returns an undefined value.

Parameters:



96
97
98
99
# File 'lib/llm/tracer/enhanced_logger.rb', line 96

def on_tool_interrupt(ex:, span:, **)
  @counts.failed += 1
  say "   #{paint("no", :red)} tool #{span.name} (#{format_id(span.id)}) received an interrupt"
end

#on_interrupt(scope:)

This method returns an undefined value.

Parameters:



104
105
106
# File 'lib/llm/tracer/enhanced_logger.rb', line 104

def on_interrupt(scope:, **)
  say "#{paint("!!", :red)} #{llm.name} interrupt received (scope=#{scope})"
end