Skip to main content
You can retrieve the build logs using the SDK.

Default Logger

We provide a default logger that you can use to filter logs by level:
import { Template, defaultBuildLogger } from "e2b";

await Template.build(template, {
  alias: "my-template",
  onBuildLogs: defaultBuildLogger({
    minLevel: "info", // Minimum log level to show
  }),
});

Custom Logger

You can customize how logs are handled:
// Simple logging
onBuildLogs: (logEntry) => console.log(logEntry.toString());

// Custom formatting
onBuildLogs: (logEntry) => {
  const time = logEntry.timestamp.toISOString();
  console.log(`[${time}] ${logEntry.level.toUpperCase()}: ${logEntry.message}`);
};

// Filter by log level
onBuildLogs: (logEntry) => {
  if (logEntry.level === "error" || logEntry.level === "warn") {
    console.error(logEntry.toString());
  }
};
The onBuildLogs/on_build_logs callback receives structured LogEntry objects with the following properties:
type LogEntryLevel = 'debug' | 'info' | 'warn' | 'error'

class LogEntry {
  constructor(
    public readonly timestamp: Date,
    public readonly level: LogEntryLevel,
    public readonly message: string
  )

  toString() // Returns formatted log string
}

// Indicates the start of the build process
class LogEntryStart extends LogEntry {
  constructor(timestamp: Date, message: string) {
    super(timestamp, 'debug', message)
  }
}

// Indicates the end of the build process
class LogEntryEnd extends LogEntry {
  constructor(timestamp: Date, message: string) {
    super(timestamp, 'debug', message)
  }
}
Together with the LogEntry type, there are also LogEntryStart and LogEntryEnd types that indicate the start and end of the build process. Their default log level is debug and you can use them to like this:
if (logEntry instanceof LogEntryStart) {
  // Build started
  return
}

if (logEntry instanceof LogEntryEnd) {
  // Build ended
  return
}
I