Skip to content

Commit 3fea108

Browse files
committed
feat: add log level selection
1 parent a4cc3e6 commit 3fea108

6 files changed

Lines changed: 109 additions & 32 deletions

File tree

go-app/app.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ const (
4848
AppEventType_ProfilesUpdated AppEventType = "profiles_updated"
4949
AppEventType_RawEvent AppEventType = "rawevent"
5050
AppEventType_ChangeEvent AppEventType = "changeevent"
51-
AppEventType_Log AppEventType = "log"
51+
AppEventType_Log_Debug AppEventType = "log/debug"
52+
AppEventType_Log_Info AppEventType = "log/info"
53+
AppEventType_Log_Error AppEventType = "log/error"
5254
)
5355

5456
type AppConfig_Mode = string
@@ -243,7 +245,14 @@ func (a *App) startupRun() {
243245
case <-a.ctx.Done():
244246
return
245247
case msg := <-channel:
246-
runtime.EventsEmit(a.ctx, AppEventType_Log, msg)
248+
switch msg.LogLevel {
249+
case "debug":
250+
runtime.EventsEmit(a.ctx, AppEventType_Log_Debug, msg.Message)
251+
case "info":
252+
runtime.EventsEmit(a.ctx, AppEventType_Log_Info, msg.Message)
253+
case "error":
254+
runtime.EventsEmit(a.ctx, AppEventType_Log_Error, msg.Message)
255+
}
247256
}
248257
}
249258
}()

go-app/frontend/src/events.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@ export const events = {
33
profiles_updated: "profiles_updated",
44
rawevent: "rawevent",
55
changeevent: "changeevent",
6-
log: "log",
6+
log: {
7+
debug: "log/debug",
8+
info: "log/info",
9+
error: "log/error"
10+
},
711
};

go-app/frontend/src/logs.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { EventsOn } from "../wailsjs/runtime/runtime";
22
import { events } from "./events";
33

4-
export const logs: string[] = [];
4+
export type LogLevel = 'debug' | 'info' | 'error'
55

6-
EventsOn(events.log, (msg: string) => {
7-
logs.push(msg);
8-
});
6+
export const logs: [LogLevel, string][] = [];
7+
8+
EventsOn(events.log.debug, (msg: string) => { logs.push(['debug', msg]) });
9+
EventsOn(events.log.info, (msg: string) => { logs.push(['info', msg]) });
10+
EventsOn(events.log.error, (msg: string) => { logs.push(['error', msg]) });

go-app/frontend/src/tabs/logs/LogsTab.tsx

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,121 @@
11
import { useEffect, useRef } from "react";
22
import { EventsOn } from "../../../wailsjs/runtime/runtime";
33
import { events } from "../../events";
4-
import { logs } from "../../logs";
4+
import { LogLevel, logs } from "../../logs";
55
import { SaveLogs } from "../../../wailsjs/go/main/App";
66
import { alert } from "../../utils/alert";
7+
import { useForm } from "react-hook-form";
8+
import clsx from "clsx";
9+
10+
type FormValues = {
11+
/* debug | info | error */
12+
loglevel: 0 | 1 | 2;
13+
};
714

815
export const LogsTab = () => {
916
const logsRef = useRef<HTMLDivElement | null>(null);
17+
const form = useForm<FormValues>({
18+
defaultValues: {
19+
loglevel: 1,
20+
},
21+
});
22+
const loglevel = form.watch("loglevel");
1023

1124
const handleSave = () => {
12-
SaveLogs(logs).catch((err) => alert(String(err), "error"));
25+
SaveLogs(logs.map(([, msg]) => msg)).catch((err) =>
26+
alert(String(err), "error"),
27+
);
1328
};
1429

1530
useEffect(() => {
1631
/* add initial logs once */
32+
console.log(logs);
1733
if (logsRef.current) {
18-
logsRef.current.innerHTML = "";
34+
logsRef.current.replaceChildren();
1935
}
2036
if (logsRef.current && logs.length) {
2137
const LOGS_LIMIT = 1000;
2238
const logsSlice = logs.slice(-LOGS_LIMIT);
23-
const textNode = document.createTextNode(
24-
(logs.length > LOGS_LIMIT
25-
? "\n...only showing the last 1000 logs, for all logs please save them as a file...\n\n" +
26-
logsSlice.join("\n")
27-
: logs.join("\n")) + "\n",
39+
logsRef.current.appendChild(
40+
document.createTextNode(
41+
"\n...only showing the last 1000 logs, for all logs please save them as a file...\n\n",
42+
),
2843
);
29-
logsRef.current.appendChild(textNode);
44+
for (const [loglevel, msg] of logsSlice) {
45+
const span = document.createElement("span");
46+
span.dataset.loglevel = loglevel;
47+
span.appendChild(document.createTextNode(msg + "\n"));
48+
logsRef.current.appendChild(span);
49+
}
3050
}
3151
}, []);
3252

3353
useEffect(() => {
34-
return EventsOn(events.log, (msg: string) => {
54+
const handleLogMessageReceived = (level: LogLevel, msg: string) => {
3555
/* add new logs as they come in */
3656
requestAnimationFrame(() => {
3757
if (logsRef.current) {
3858
const isNearBottom =
3959
document.documentElement.scrollTop + window.innerHeight >=
4060
document.documentElement.scrollHeight - window.innerHeight * 0.1;
41-
const textNode = document.createTextNode(msg + "\n");
42-
logsRef.current.appendChild(textNode);
61+
const span = document.createElement("span");
62+
span.dataset.loglevel = level;
63+
span.appendChild(document.createTextNode(msg + "\n"));
64+
logsRef.current.appendChild(span);
4365
if (isNearBottom) {
4466
/* scroll bottom if near bottom */
4567
document.documentElement.scrollTop =
4668
document.documentElement.scrollHeight;
4769
}
4870
}
4971
});
50-
});
72+
};
73+
74+
const unsubscribe_debug = EventsOn(events.log.debug, (msg: string) =>
75+
handleLogMessageReceived("debug", msg),
76+
);
77+
const unsubscribe_info = EventsOn(events.log.info, (msg: string) =>
78+
handleLogMessageReceived("info", msg),
79+
);
80+
const unsubscribe_error = EventsOn(events.log.error, (msg: string) =>
81+
handleLogMessageReceived("error", msg),
82+
);
83+
84+
return () => {
85+
unsubscribe_debug();
86+
unsubscribe_info();
87+
unsubscribe_error();
88+
};
5189
}, []);
5290

5391
return (
5492
<div>
5593
<div
5694
ref={logsRef}
5795
key="logs"
58-
className="whitespace-pre-wrap text-xs font-mono w-full overflow-hidden peer"
96+
className={clsx(
97+
"whitespace-pre-wrap text-xs font-mono w-full overflow-hidden peer *:data-[loglevel=error]:text-error",
98+
{
99+
"*:data-[loglevel=debug]:hidden": loglevel > 0,
100+
"*:data-[loglevel=info]:hidden": loglevel > 1,
101+
"*:data-[loglevel=error]:hidden": loglevel > 2,
102+
},
103+
)}
59104
/>
60-
<div className="sticky bottom-0 left-0 right-0 py-3 bg-[var(--root-bg,var(--color-base-100))] border-t border-t-base-100 peer-empty:hidden">
61-
<button className="btn btn-primary btn-xs" onClick={handleSave}>
62-
Save logs
63-
</button>
105+
<div className="sticky bottom-0 left-0 right-0 py-3 bg-(--root-bg,var(--color-base-100)) border-t border-t-base-100">
106+
<div className="flex items-center gap-2">
107+
<select
108+
className="select select-xs w-20"
109+
{...form.register("loglevel", { valueAsNumber: true })}
110+
>
111+
<option value="0">Debug</option>
112+
<option value="1">Info</option>
113+
<option value="2">Error</option>
114+
</select>
115+
<button className="btn btn-primary btn-xs" onClick={handleSave}>
116+
Save logs
117+
</button>
118+
</div>
64119
</div>
65120
</div>
66121
);

go-app/logger/logger.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,22 @@ import (
99

1010
const LOGGER_BUFFER_SIZE = 128
1111

12+
type GlobalLogger_Event struct {
13+
LogLevel string
14+
Message string
15+
}
16+
1217
type GlobalLogger struct {
1318
mutex sync.RWMutex
1419
slogger *slog.Logger
15-
listeners []chan string
20+
listeners []chan GlobalLogger_Event
1621
}
1722

18-
func (g *GlobalLogger) Listen() (chan string, func()) {
23+
func (g *GlobalLogger) Listen() (chan GlobalLogger_Event, func()) {
1924
g.mutex.Lock()
2025
defer g.mutex.Unlock()
2126

22-
channel := make(chan string, LOGGER_BUFFER_SIZE)
27+
channel := make(chan GlobalLogger_Event, LOGGER_BUFFER_SIZE)
2328
g.listeners = append(g.listeners, channel)
2429
unsubscribe := func() {
2530
g.mutex.Lock()
@@ -56,7 +61,7 @@ func (g *GlobalLogger) Debug(msg string, args ...any) {
5661
if len(g.listeners) > 0 {
5762
properties := g.PropertiesFromArgs(args...)
5863
for _, c := range g.listeners {
59-
c <- fmt.Sprintf("%s | %v", msg, properties)
64+
c <- GlobalLogger_Event{LogLevel: "debug", Message: fmt.Sprintf("%s | %v", msg, properties)}
6065
}
6166
}
6267
}
@@ -70,7 +75,7 @@ func (g *GlobalLogger) Info(msg string, args ...any) {
7075
if len(g.listeners) > 0 {
7176
properties := g.PropertiesFromArgs(args...)
7277
for _, c := range g.listeners {
73-
c <- fmt.Sprintf("%s | %v", msg, properties)
78+
c <- GlobalLogger_Event{LogLevel: "info", Message: fmt.Sprintf("%s | %v", msg, properties)}
7479
}
7580
}
7681
}
@@ -84,7 +89,7 @@ func (g *GlobalLogger) Error(msg string, args ...any) {
8489
if len(g.listeners) > 0 {
8590
properties := g.PropertiesFromArgs(args...)
8691
for _, c := range g.listeners {
87-
c <- fmt.Sprintf("%s | %v", msg, properties)
92+
c <- GlobalLogger_Event{LogLevel: "error", Message: fmt.Sprintf("%s | %v", msg, properties)}
8893
}
8994
}
9095
}
@@ -93,5 +98,5 @@ var Logger = GlobalLogger{
9398
slogger: slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
9499
Level: slog.LevelDebug,
95100
})),
96-
listeners: []chan string{},
101+
listeners: []chan GlobalLogger_Event{},
97102
}

go-app/profile_runner/profile_runner.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,8 @@ func (p *ProfileRunner) Run(ctx context.Context) context.CancelFunc {
683683
if !has_selected_profile {
684684
logger.Logger.Debug("[ProfileRunner::Run] skipping event, no profile selected", "event", change_event)
685685
return
686+
} else {
687+
logger.Logger.Debug("[ProfileRunner::Run] using profile", selected_profile.Profile.Name)
686688
}
687689

688690
control_name := change_event.ControlName

0 commit comments

Comments
 (0)