-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: server web logging running server #3408
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,8 +43,10 @@ export abstract class ServerTask { | |
|
||
this.loggerObserver = new Observer((msg: string) => { | ||
console.log('Sending log_state:', msg); | ||
if (!this.window?.isDestroyed()) { | ||
// this.window.webContents.send('log_state', { msg }); | ||
if (msg.includes('stderr:')) { | ||
console.log(LOG_TYPES.SERVER_LOG_ERROR, msg); | ||
} else { | ||
console.log(LOG_TYPES.SERVER_LOG, msg); | ||
} | ||
}); | ||
|
||
|
@@ -72,16 +74,20 @@ export abstract class ServerTask { | |
|
||
const service = ChildProcessFactory.createProcess(this.processPath, this.args, signal); | ||
|
||
console.log(LOG_TYPES.SERVER_LOG, 'Service created', service.pid); | ||
this.loggerObserver.notify(`Service created ${service.pid}`) | ||
|
||
service.stdout?.on('data', (data: any) => { | ||
const msg = data.toString(); | ||
this.loggerObserver.notify(msg); | ||
if (msg.includes(this.successMessage)) { | ||
const name = String(this.args.serviceName); | ||
this.stateObserver.notify(true); | ||
console.log(this.args) | ||
this.loggerObserver.notify( | ||
`☣︎ ${name.toUpperCase()} running on http://${this.args.DESKTOP_WEB_SERVER_HOSTNAME}:${this.args.PORT}` | ||
); | ||
this.loggerObserver.notify( | ||
`☣︎ ${name.toUpperCase()} server listen to ${this.config.setting[`${name}Url`]}` | ||
`☣︎ ${name.toUpperCase()} connected to api ${this.args.GAUZY_API_SERVER_URL}` | ||
); | ||
resolve(); | ||
} | ||
|
@@ -93,12 +99,11 @@ export abstract class ServerTask { | |
}); | ||
|
||
service.stderr?.on('data', (data: any) => { | ||
console.log(LOG_TYPES.SERVER_LOG, 'stderr:', data.toString()); | ||
this.loggerObserver.notify(data.toString()); | ||
this.loggerObserver.notify(`stderr: ${data.toString()}`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Implement consistent error handling pattern The error handling is inconsistent between different event handlers. Standardize the approach across all handlers. - service.stderr?.on('data', (data: any) => {
- this.loggerObserver.notify(`stderr: ${data.toString()}`);
- });
+ service.stderr?.on('data', this.handleStdErr.bind(this));
- service.on('disconnect', () => {
- this.loggerObserver.notify('Webserver disconnected')
+ service.on('disconnect', this.handleDisconnect.bind(this));
+ private handleStdErr(data: any): void {
+ const errorMessage = data.toString();
+ this.loggerObserver.notify(`stderr: ${errorMessage}`);
+ this.handleError(new Error(errorMessage), false);
+ }
+
+ private handleDisconnect(): void {
+ this.loggerObserver.notify('Webserver disconnected');
+ this.stateObserver.notify(false);
+ if (this.eventEmitter) {
+ this.eventEmitter.emit(EventLists.webServerStopped);
+ }
+ } Also applies to: 106-106 |
||
}); | ||
|
||
service.on('disconnect', () => { | ||
console.log(LOG_TYPES.SERVER_LOG, 'Webserver disconnected'); | ||
this.loggerObserver.notify('Webserver disconnected') | ||
if (this.eventEmitter) { | ||
this.eventEmitter.emit(EventLists.webServerStopped); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,50 @@ | ||
import { useState, useEffect } from 'react'; | ||
import { useState, useEffect, useRef } from 'react'; | ||
import { ServerPageTypeMessage } from '../../main/helpers/constant'; | ||
import { IPC_TYPES, LOG_TYPES } from '../../main/helpers/constant'; | ||
import { EverTeamsLogo } from '../components/svgs'; | ||
import { useTranslation } from 'react-i18next'; | ||
|
||
export function ServerPage() { | ||
const logRef = useRef<HTMLDivElement>(null); | ||
const [isRun, setIsRun] = useState<boolean>(false); | ||
const [logs, setLogs] = useState<string[]>([]); | ||
const [logs, setLogs] = useState< | ||
{ | ||
message: string; | ||
type: 'error-log' | 'log'; | ||
}[] | ||
>([]); | ||
const [loading, setLoading] = useState<boolean>(false); | ||
const { t } = useTranslation(); | ||
const [logOpen, setLogOpen] = useState<boolean>(false); | ||
|
||
useEffect(() => { | ||
window.electron.ipcRenderer.removeEventListener(IPC_TYPES.SERVER_PAGE); | ||
window.electron.ipcRenderer.on(IPC_TYPES.SERVER_PAGE, (arg: any) => { | ||
switch (arg.type) { | ||
case LOG_TYPES.SERVER_LOG: | ||
setLogs((prev) => [...prev, arg.msg]); | ||
setLogs((prev) => [ | ||
...prev, | ||
{ | ||
message: arg.msg, | ||
type: 'log', | ||
}, | ||
]); | ||
scrollToLast(); | ||
break; | ||
case LOG_TYPES.SERVER_LOG_ERROR: | ||
setLogs((prev) => [ | ||
...prev, | ||
{ | ||
message: arg.msg, | ||
type: 'error-log', | ||
}, | ||
]); | ||
scrollToLast(); | ||
break; | ||
Comment on lines
+29
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Refactor log handling to reduce duplication. The log handling logic for both normal and error logs is duplicated. Consider extracting it into a helper function. +const addLog = (prev: typeof logs, message: string, type: 'log' | 'error-log') => [
+ ...prev,
+ { message, type }
+];
-setLogs((prev) => [
- ...prev,
- {
- message: arg.msg,
- type: 'log',
- },
-]);
+setLogs((prev) => addLog(prev, arg.msg, 'log'));
|
||
case ServerPageTypeMessage.SERVER_STATUS: | ||
if (arg.data.isRun) { | ||
setIsRun(true); | ||
setLogOpen(true); | ||
} else { | ||
setIsRun(false); | ||
} | ||
|
@@ -41,6 +66,12 @@ export function ServerPage() { | |
}); | ||
}; | ||
|
||
const scrollToLast = () => { | ||
logRef.current?.scrollIntoView({ | ||
behavior: 'smooth', | ||
}); | ||
}; | ||
|
||
return ( | ||
<div className="min-h-screen flex flex-col flex-auto flex-shrink-0 antialiased text-gray-800"> | ||
<div className="rounded-lg px-16 py-10"> | ||
|
@@ -60,7 +91,14 @@ export function ServerPage() { | |
</button> | ||
<div className="grid divide-y divide-neutral-200 dark:bg-[#25272D] dark:text-white mx-auto w-10/12 rounded-lg border-2 border-gray-200 dark:border-gray-600"> | ||
<div className="py-5 px-5"> | ||
<details className="group"> | ||
<details | ||
className="group" | ||
open={logOpen} | ||
onClick={(e) => { | ||
e.preventDefault(); | ||
setLogOpen((prev) => !prev); | ||
}} | ||
> | ||
<summary className="flex justify-between items-center font-medium cursor-pointer list-none"> | ||
<span className="p-2"> Server Logs</span> | ||
<span className="transition group-open:rotate-180"> | ||
|
@@ -91,10 +129,16 @@ export function ServerPage() { | |
{logs.length > 0 && | ||
logs.map((log, i) => ( | ||
<div className="py-1" key={i}> | ||
<span>{log}</span> | ||
{log.type === 'error-log' && ( | ||
<span className="text-red-600">{log.message}</span> | ||
)} | ||
{log.type === 'log' && ( | ||
<span className="text-white">{log.message}</span> | ||
)} | ||
</div> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error boundary for log rendering The log rendering logic should be wrapped in an error boundary to handle potential rendering failures gracefully. Create an error boundary component: class LogErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <div className="text-red-500">Error rendering logs</div>;
}
return this.props.children;
}
} Then wrap the log rendering: - {log.type === 'error-log' && (
- <span className="text-red-600">{log.message}</span>
- )}
- {log.type === 'log' && (
- <span className="text-white">{log.message}</span>
- )}
+ <LogErrorBoundary>
+ {log.type === 'error-log' ? (
+ <span className="text-red-600">{log.message}</span>
+ ) : (
+ <span className="text-white">{log.message}</span>
+ )}
+ </LogErrorBoundary> |
||
))} | ||
</div> | ||
<div className="py-1" ref={logRef}></div> | ||
</div> | ||
</details> | ||
</div> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance error logging with structured error information
The current error detection relies on string includes, which is fragile. Consider using a more structured approach for error detection and logging.
Add helper function: