WordPress / WordPress/wordpress-playground
[Enhancement]: Surface debug.log errors
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 2k
- Forks
- 462
- Avg merge
- 18h 44m
- Merged PRs (30d)
- 33
Description
Describe the solution you'd like
RIght now the Logs panel shows a 🎉 even if there were fatals that were logged to /wordpress/wp-content/debug.log. We should surface those.
Describe alternatives you've considered
A lower-level Playground client API such as stat(path) plus readFileRange(path, offset, length) may be the cleaner long-term solution.
The PHP-side tailing sketch is a workaround that avoids broadening the client API in the short term.
Additional context
I tried an implementation in #3601 but it was getting out of hand. We don't have a playground.stat() that allows reading the file at boot to determine if something was added.
This is a potential workaround:
const debugLogMaxUnreadChars = 256 * 1024;
const debugLogReadOffsets = new WeakMap<PlaygroundClient, number>();
type DebugLogTail = {
size: number;
content: string;
};
async function readDebugLogTail(
playground: PlaygroundClient
): Promise<DebugLogTail | null> {
const previousOffset = debugLogReadOffsets.get(playground) ?? 0;
const response = await playground.run({
code: `<?php
$path = '/wordpress/wp-content/debug.log';
$previousOffset = ${JSON.stringify(previousOffset)};
$maxBytes = ${JSON.stringify(debugLogMaxUnreadChars)};
if (!file_exists($path)) {
echo json_encode(null);
return;
}
$size = filesize($path);
$start = $previousOffset;
if ($start > $size) {
$start = 0;
}
$start = max($start, $size - $maxBytes);
$handle = fopen($path, 'rb');
if (!$handle) {
echo json_encode(null);
return;
}
fseek($handle, $start);
$content = stream_get_contents($handle);
fclose($handle);
echo json_encode(array(
'size' => $size,
'content' => $content,
));
`,
});
if (response.exitCode !== 0) {
return null;
}
return response.json as DebugLogTail | null;
}
async function surfaceDebugLogEntries(playground: PlaygroundClient) {
try {
const tail = await readDebugLogTail(playground);
if (!tail) {
return;
}
debugLogReadOffsets.set(playground, tail.size);
const filtered = tail.content
.split('\n')
.filter((line) => line.trim() && !isIgnoredLogLine(line))
.join('\n');
if (filtered.length > 0) {
logger.logMessage({
message: filtered,
severity: LogSeverity.Log,
raw: true,
});
}
} catch {
// Playground may not be ready yet.
}
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the Logs panel and the PlaygroundClient.run call shown in the issue; inspect how log messages are filtered and rendered. Confirm the implementation can detect new /wordpress/wp-content/debug.log content and that fatal entries appear instead of a success-only state, including when the Playground is not ready.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, php, wasm
- Domain
- backend, observability
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100