Class: RosettAi::Desktop::GuiLogger

Inherits:
Object
  • Object
show all
Defined in:
lib/rosett_ai/desktop/gui_logger.rb

Overview

Structured GUI action logger for debugging and crash analysis.

Provides comprehensive logging of all GUI interactions including:

  • Action invocation with parameters
  • Success/failure outcomes with duration
  • Widget events and state changes
  • D-Bus operations

Log output is controlled by environment variables: RAI_GUI_LOG=1 Enable logging to stderr RAI_GUI_LOG_FILE=path Also log to file RAI_GUI_LOG_LEVEL=debug Set log level (debug, info, warn, error)

Log format is JSON Lines for easy parsing and analysis.

Examples:

Enable logging

RAI_GUI_LOG=1 bin/raictl desktop gtk4

Log to file

RAI_GUI_LOG=1 RAI_GUI_LOG_FILE=/tmp/rosett-ai-gui.log bin/raictl desktop gtk4

Constant Summary collapse

LEVELS =
{ debug: 0, info: 1, warn: 2, error: 3 }.freeze
DEFAULT_LEVEL =
:info

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGuiLogger

Returns a new instance of GuiLogger.



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 51

def initialize
  @enabled = ENV['RAI_GUI_LOG'] == '1'
  @log_file = ENV.fetch('RAI_GUI_LOG_FILE', nil)
  @level = parse_level(ENV.fetch('RAI_GUI_LOG_LEVEL', 'info'))
  @file_handle = nil
  @action_stack = []
  @mutex = Mutex.new

  setup_file_logging if @log_file
  at_exit { cleanup }
end

Class Method Details

.instanceGuiLogger

Get the singleton instance.

Returns:



40
41
42
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 40

def instance
  @instance ||= new
end

Instance Method Details

#action(name, context = {}) { ... } ⇒ Object

Log a complete action with automatic timing.

Parameters:

  • name (String, Symbol)

    action name

  • context (Hash) (defaults to: {})

    additional context

Yields:

  • the action block

Returns:

  • (Object)

    result of the block



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 76

def action(name, context = {})
  return yield unless @enabled

  action_start(name, context)
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)

  begin
    result = yield
    duration = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000).round(2)
    action_end(name, status: :success, duration_ms: duration)
    result
  rescue StandardError => e
    duration = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000).round(2)
    action_end(name, status: :error, duration_ms: duration, error: e.class.name, message: e.message)
    raise
  end
end

#action_end(name, context = {}) ⇒ Object

Log action end.

Parameters:

  • name (String, Symbol)

    action name

  • context (Hash) (defaults to: {})

    additional context (status, duration_ms, error)



109
110
111
112
113
114
115
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 109

def action_end(name, context = {})
  return unless @enabled

  @mutex.synchronize { @action_stack.pop }
  level = context[:status] == :error ? :error : :info
  write_log(level, 'action_end', { action: name.to_s }.merge(context))
end

#action_start(name, context = {}) ⇒ Object

Log action start.

Parameters:

  • name (String, Symbol)

    action name

  • context (Hash) (defaults to: {})

    additional context



98
99
100
101
102
103
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 98

def action_start(name, context = {})
  return unless @enabled

  @mutex.synchronize { @action_stack.push(name.to_s) }
  write_log(:info, 'action_start', { action: name.to_s }.merge(context))
end

#callback(name, context = {}) ⇒ Object

Log a callback invocation.

Parameters:

  • name (String, Symbol)

    callback name

  • context (Hash) (defaults to: {})

    additional context



121
122
123
124
125
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 121

def callback(name, context = {})
  return unless @enabled

  write_log(:debug, 'callback', { callback: name.to_s }.merge(context))
end

#dbus_call(operation, context = {}) ⇒ Object

Log a D-Bus operation.

Parameters:

  • operation (String, Symbol)

    operation name

  • context (Hash) (defaults to: {})

    additional context



145
146
147
148
149
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 145

def dbus_call(operation, context = {})
  return unless @enabled

  write_log(:debug, 'dbus_call', { operation: operation.to_s }.merge(context))
end

#debug(message, context = {}) ⇒ Object

Log debug message.

Parameters:

  • message (String)

    log message

  • context (Hash) (defaults to: {})

    additional context



155
156
157
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 155

def debug(message, context = {})
  write_log(:debug, 'debug', { message: message }.merge(context))
end

#enabled?Boolean

Check if logging is enabled.

Returns:

  • (Boolean)


66
67
68
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 66

def enabled?
  @enabled
end

#error(message, error = nil, context = {}) ⇒ Object

Log error message.

Parameters:

  • message (String)

    log message

  • error (Exception, nil) (defaults to: nil)

    optional exception

  • context (Hash) (defaults to: {})

    additional context



180
181
182
183
184
185
186
187
188
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 180

def error(message, error = nil, context = {})
  data = { message: message }.merge(context)
  if error
    data[:error_class] = error.class.name
    data[:error_message] = error.message
    data[:backtrace] = error.backtrace&.first(5)
  end
  write_log(:error, 'error', data)
end

#info(message, context = {}) ⇒ Object

Log info message.

Parameters:

  • message (String)

    log message

  • context (Hash) (defaults to: {})

    additional context



163
164
165
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 163

def info(message, context = {})
  write_log(:info, 'info', { message: message }.merge(context))
end

#warn(message, context = {}) ⇒ Object

Log warning message.

Parameters:

  • message (String)

    log message

  • context (Hash) (defaults to: {})

    additional context



171
172
173
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 171

def warn(message, context = {})
  write_log(:warn, 'warn', { message: message }.merge(context))
end

#widget_event(widget_type, event, context = {}) ⇒ Object

Log a widget event.

Parameters:

  • widget_type (String, Symbol)

    widget type (e.g., :switch_row, :combo_row)

  • event (String, Symbol)

    event name (e.g., :toggled, :selected)

  • context (Hash) (defaults to: {})

    additional context (value, widget_id, etc.)



132
133
134
135
136
137
138
139
# File 'lib/rosett_ai/desktop/gui_logger.rb', line 132

def widget_event(widget_type, event, context = {})
  return unless @enabled

  write_log(:debug, 'widget_event', {
    widget: widget_type.to_s,
    event: event.to_s
  }.merge(context))
end