Skip to content

Commit 7547430

Browse files
authored
Merge pull request #1974 from Stijnus/BOLTDIY_LOGGING_DEBUGGING_FEAT
feat: comprehensive debug logging system with capture and download
2 parents ded6884 + 36f1b9c commit 7547430

File tree

7 files changed

+1495
-12
lines changed

7 files changed

+1495
-12
lines changed

app/components/@settings/core/AvatarDropdown.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,29 @@ export const AvatarDropdown = ({ onSelectTab }: AvatarDropdownProps) => {
130130
Report Bug
131131
</DropdownMenu.Item>
132132

133+
<DropdownMenu.Item
134+
className={classNames(
135+
'flex items-center gap-2 px-4 py-2.5',
136+
'text-sm text-gray-700 dark:text-gray-200',
137+
'hover:bg-purple-50 dark:hover:bg-purple-500/10',
138+
'hover:text-purple-500 dark:hover:text-purple-400',
139+
'cursor-pointer transition-all duration-200',
140+
'outline-none',
141+
'group',
142+
)}
143+
onClick={async () => {
144+
try {
145+
const { downloadDebugLog } = await import('~/utils/debugLogger');
146+
await downloadDebugLog();
147+
} catch (error) {
148+
console.error('Failed to download debug log:', error);
149+
}
150+
}}
151+
>
152+
<div className="i-ph:download w-4 h-4 text-gray-400 group-hover:text-purple-500 dark:group-hover:text-purple-400 transition-colors" />
153+
Download Debug Log
154+
</DropdownMenu.Item>
155+
133156
<DropdownMenu.Item
134157
className={classNames(
135158
'flex items-center gap-2 px-4 py-2.5',

app/components/header/HeaderActionButtons.client.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,35 @@ export function HeaderActionButtons({ chatStarted: _chatStarted }: HeaderActionB
1919
{/* Deploy Button */}
2020
{shouldShowButtons && <DeployButton />}
2121

22-
{/* Bug Report Button */}
22+
{/* Debug Tools */}
2323
{shouldShowButtons && (
2424
<div className="flex border border-bolt-elements-borderColor rounded-md overflow-hidden text-sm">
2525
<button
2626
onClick={() =>
2727
window.open('https://github.com/stackblitz-labs/bolt.diy/issues/new?template=bug_report.yml', '_blank')
2828
}
29-
className="rounded-md items-center justify-center [&:is(:disabled,.disabled)]:cursor-not-allowed [&:is(:disabled,.disabled)]:opacity-60 px-3 py-1.5 text-xs bg-accent-500 text-white hover:text-bolt-elements-item-contentAccent [&:not(:disabled,.disabled)]:hover:bg-bolt-elements-button-primary-backgroundHover outline-accent-500 flex gap-1.5"
29+
className="rounded-l-md items-center justify-center [&:is(:disabled,.disabled)]:cursor-not-allowed [&:is(:disabled,.disabled)]:opacity-60 px-3 py-1.5 text-xs bg-accent-500 text-white hover:text-bolt-elements-item-contentAccent [&:not(:disabled,.disabled)]:hover:bg-bolt-elements-button-primary-backgroundHover outline-accent-500 flex gap-1.5"
3030
title="Report Bug"
3131
>
3232
<div className="i-ph:bug" />
3333
<span>Report Bug</span>
3434
</button>
35+
<div className="w-px bg-bolt-elements-borderColor" />
36+
<button
37+
onClick={async () => {
38+
try {
39+
const { downloadDebugLog } = await import('~/utils/debugLogger');
40+
await downloadDebugLog();
41+
} catch (error) {
42+
console.error('Failed to download debug log:', error);
43+
}
44+
}}
45+
className="rounded-r-md items-center justify-center [&:is(:disabled,.disabled)]:cursor-not-allowed [&:is(:disabled,.disabled)]:opacity-60 px-3 py-1.5 text-xs bg-accent-500 text-white hover:text-bolt-elements-item-contentAccent [&:not(:disabled,.disabled)]:hover:bg-bolt-elements-button-primary-backgroundHover outline-accent-500 flex gap-1.5"
46+
title="Download Debug Log"
47+
>
48+
<div className="i-ph:download" />
49+
<span>Debug Log</span>
50+
</button>
3551
</div>
3652
)}
3753
</div>

app/root.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,24 @@ export default function App() {
9393
userAgent: navigator.userAgent,
9494
timestamp: new Date().toISOString(),
9595
});
96+
97+
// Initialize debug logging with improved error handling
98+
import('./utils/debugLogger')
99+
.then(({ debugLogger }) => {
100+
/*
101+
* The debug logger initializes itself and starts disabled by default
102+
* It will only start capturing when enableDebugMode() is called
103+
*/
104+
const status = debugLogger.getStatus();
105+
logStore.logSystem('Debug logging ready', {
106+
initialized: status.initialized,
107+
capturing: status.capturing,
108+
enabled: status.enabled,
109+
});
110+
})
111+
.catch((error) => {
112+
logStore.logError('Failed to initialize debug logging', error);
113+
});
96114
}, []);
97115

98116
return (

app/routes/api.git-info.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { json } from '@remix-run/cloudflare';
2+
import { execSync } from 'child_process';
3+
import { existsSync } from 'fs';
4+
5+
export async function loader() {
6+
try {
7+
// Check if we're in a git repository
8+
if (!existsSync('.git')) {
9+
return json({
10+
branch: 'unknown',
11+
commit: 'unknown',
12+
isDirty: false,
13+
});
14+
}
15+
16+
// Get current branch
17+
const branch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
18+
19+
// Get current commit hash
20+
const commit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
21+
22+
// Check if working directory is dirty
23+
const statusOutput = execSync('git status --porcelain', { encoding: 'utf8' });
24+
const isDirty = statusOutput.trim().length > 0;
25+
26+
// Get remote URL
27+
let remoteUrl: string | undefined;
28+
29+
try {
30+
remoteUrl = execSync('git remote get-url origin', { encoding: 'utf8' }).trim();
31+
} catch {
32+
// No remote origin, leave as undefined
33+
}
34+
35+
// Get last commit info
36+
let lastCommit: { message: string; date: string; author: string } | undefined;
37+
38+
try {
39+
const commitInfo = execSync('git log -1 --pretty=format:"%s|%ci|%an"', { encoding: 'utf8' }).trim();
40+
const [message, date, author] = commitInfo.split('|');
41+
lastCommit = {
42+
message: message || 'unknown',
43+
date: date || 'unknown',
44+
author: author || 'unknown',
45+
};
46+
} catch {
47+
// Could not get commit info
48+
}
49+
50+
return json({
51+
branch,
52+
commit,
53+
isDirty,
54+
remoteUrl,
55+
lastCommit,
56+
});
57+
} catch (error) {
58+
console.error('Error fetching git info:', error);
59+
return json(
60+
{
61+
branch: 'error',
62+
commit: 'error',
63+
isDirty: false,
64+
error: error instanceof Error ? error.message : 'Unknown error',
65+
},
66+
{ status: 500 },
67+
);
68+
}
69+
}

0 commit comments

Comments
 (0)