gadget/docs/drone-logger.md

4.7 KiB

Gadget Code: GadgetLogTransportSocket

GadgetLog now ships four transports out of the box: Console, File, Socket, and the abstract base. The socket transport (GadgetLogTransportSocket) transmits every log entry from gadget-dronegadget-code:backendgadget-code:frontend over Socket.IO, rendering live in the IDE's LogPanel.

Message Flow

gadget-drone
  │ GadgetLogTransportSocket.writeLog()
  │ socket.emit("log", timestamp, component, level, message, metadata?)
  ▼
gadget-code:backend (DroneSession.onLog)
  │ SocketService.getCodeSessionByChatSessionId(chatSessionId)
  │ codeSession.onLog(...)
  ▼
gadget-code:backend (CodeSession.onLog)
  │ socket.emit("log", timestamp, component, level, message, metadata?)
  ▼
gadget-code:frontend (SocketClient)
  │ raw socket "log" → internal "log:entry" event
  │ { level, component, message, metadata, timestamp }
  ▼
ChatSessionView.handleLogEntry
  │ setLogs(...)
  ▼
LogPanel — terminal-styled live log viewer

Transport: GadgetLogTransportSocket

File: packages/api/src/lib/log-transport-socket.ts

Accepts a generic emit function (no Socket.IO dependency in @gadget/api):

export type LogEmitFunction = (
  event: string,
  timestamp: Date,
  component: GadgetComponent,
  level: GadgetLogLevel,
  message: string,
  metadata?: unknown,
) => void;

writeLog() calls this.emit("log", ...) with the same parameters GadgetLog.writeLog() receives.

Registration in gadget-drone

Registered in gadget-drone.ts connectSocket(), after the Socket.IO connection succeeds:

const socketTransport = new GadgetLogTransportSocket((event, ...args) => {
  (this.socket as any)?.emit(event, ...args);
});
GadgetLog.addDefaultTransport(socketTransport);
this.log.transports.push(socketTransport);
AgentService.log.transports.push(socketTransport);
AiService.log.transports.push(socketTransport);
PlatformService.log.transports.push(socketTransport);

The transport is injected into all existing loggers (main process + 3 services) and set as a default for future GadgetLog instances.

Backend Routing

DroneSession (gadget-code/src/lib/drone-session.ts)

  • Registers this.socket.on("log", this.onLog.bind(this))
  • onLog() guards on this.chatSessionId, looks up the CodeSession via SocketService.getCodeSessionByChatSessionId(), forwards the call.

CodeSession (gadget-code/src/lib/code-session.ts)

  • onLog() calls this.socket.emit("log", timestamp, component, level, message, metadata) forwards to the IDE.

Frontend Bridging

SocketClient (gadget-code/frontend/src/lib/socket.ts)

The raw Socket.IO log event is forwarded to the internal log:entry event system:

this.socket.on("log", (timestamp, component, level, message, metadata) => {
  this.emit("log:entry", {
    level,
    component: component.name,
    message,
    metadata,
    timestamp: new Date(timestamp).getTime(),
  });
});

ChatSessionView

handleLogEntry callback builds a LogEntry with all fields and appends to the logs state array.

LogPanel Display

File: gadget-code/frontend/src/components/LogPanel.tsx

Styled to match the Console Transport:

Element Console Color Tailwind Class
Timestamp darkGray text-gray-600
Level: debug darkGray text-gray-500
Level: info green text-green-400
Level: warn yellow text-yellow-400
Level: alert red text-red-400
Level: error bgRed + white bg-red-800 text-white
Level: crit bgRed + yellow bg-red-800 text-yellow-300
Level: fatal bgRed + darkGray bg-red-800 text-gray-400
Component cyan text-cyan-400
Message darkGray text-text-secondary

Metadata is displayed as expandable JSON below the log line (toggled with /).

Files Changed

File Action
packages/api/src/lib/log-transport-socket.ts NEW — socket transport
packages/api/src/index.ts MODIFY — export new transport
gadget-drone/src/gadget-drone.ts MODIFY — register transport on connect
gadget-drone/src/lib/service.ts MODIFYlog public for transport injection
gadget-code/src/lib/drone-session.ts MODIFYonLog handler
gadget-code/src/lib/code-session.ts MODIFYonLog forwarding
gadget-code/frontend/src/lib/socket.ts MODIFY — bridge loglog:entry
gadget-code/frontend/src/pages/ChatSessionView.tsx MODIFY — enriched LogEntry
gadget-code/frontend/src/components/LogPanel.tsx REWRITE — console-styled display