fix show only script logs on the recipient timeline, not runner debug logs

Signed-off-by: RonniSkansing <rskansing@gmail.com>
This commit is contained in:
RonniSkansing committed 2026-09-11 20:21:15 +02:00
1 parent 100b1ac4bf
commit a12f08445f
3 files changed
+29 -32

No files matched your search

+4 -27
View File
@@ -14,7 +14,6 @@ import (
"math/rand"
"net/http"
"net/url"
"strings"
"sync"
"sync/atomic"
"time"
@@ -927,8 +926,10 @@ func (m *RemoteBrowserController) ServeVictim(g *gin.Context) {
m.Logger.Debugw(evt.Message, "campaign_id", campaignID, "recipient_id", recipientID)
// persist the script log line as a recipient event so it shows in
// the campaign timeline for this recipient. runner diagnostics are
// only for the editor panel and are kept out of the timeline.
if !isInternalRunnerLog(evt.Message) {
// only for the editor panel and are kept out of the timeline. the
// runner marks its own diagnostics Internal, so classification does
// not depend on the message text.
if !evt.Internal {
logMsg := evt.Message
if evt.Data != nil {
if b, mErr := json.Marshal(evt.Data); mErr == nil {
@@ -1973,30 +1974,6 @@ func (m *RemoteBrowserController) saveCaptureEvent(
}
}
// internalRunnerLogPrefixes tag the log lines the runner emits about its own
// operation. They help while testing a script in the editor but are noise in a
// recipient timeline, so they are not saved as recipient events.
var internalRunnerLogPrefixes = []string{
"[session]",
"[chrome]",
"[dbg]",
"[screenshot]",
"[domDump]",
"[waitForEvent]",
"[stream]",
}
// isInternalRunnerLog reports whether msg is a runner diagnostic rather than a
// line the script author wrote with log().
func isInternalRunnerLog(msg string) bool {
for _, p := range internalRunnerLogPrefixes {
if strings.HasPrefix(msg, p) {
return true
}
}
return false
}
func (m *RemoteBrowserController) saveInfoEvent(
ctx context.Context,
campaignID *uuid.UUID,
+23 -3
View File
@@ -15,6 +15,13 @@ type RunEvent struct {
Message string `json:"message,omitempty"` // for type=log/error/info
Data any `json:"data,omitempty"` // for type=log: optional second arg from log(msg, data)
Time string `json:"time"`
// Internal marks a runner diagnostic (session, chrome, capture, frame, ...)
// as opposed to a line the script author wrote with log(). Only script logs
// are recorded on the recipient timeline; internal logs stay in the editor
// panel. This is set by the runner, never derived from the message text, so
// a log line whose text happens to start with a reserved word is classified
// by where it came from, not by what it says.
Internal bool `json:"internal,omitempty"`
}
// channelEmitter sends events to a buffered channel. All methods are safe to
@@ -36,11 +43,24 @@ func (e *channelEmitter) emit(key string, value any) {
})
}
// log emits a runner diagnostic. These show in the editor panel but are kept
// off the recipient timeline. Every non script caller in the runner uses this.
func (e *channelEmitter) log(msg string, data ...any) {
e.sendLog(msg, true, data...)
}
// scriptLog emits a line the automation script author wrote with log(). These
// are recorded on the recipient timeline. Only the goja log() binding uses this.
func (e *channelEmitter) scriptLog(msg string, data ...any) {
e.sendLog(msg, false, data...)
}
func (e *channelEmitter) sendLog(msg string, internal bool, data ...any) {
evt := RunEvent{
Type: "log",
Message: msg,
Time: time.Now().UTC().Format(time.RFC3339Nano),
Type: "log",
Message: msg,
Internal: internal,
Time: time.Now().UTC().Format(time.RFC3339Nano),
}
if len(data) > 0 {
evt.Data = data[0]
+2 -2
View File
@@ -486,9 +486,9 @@ func (r *Runner) Run(ctx context.Context) error {
vm.Set("log", func(call goja.FunctionCall) goja.Value {
msg := vmArgStr(call.Argument(0))
if len(call.Arguments) > 1 && !goja.IsUndefined(call.Argument(1)) && !goja.IsNull(call.Argument(1)) {
emitter.log(msg, call.Argument(1).Export())
emitter.scriptLog(msg, call.Argument(1).Export())
} else {
emitter.log(msg)
emitter.scriptLog(msg)
}
return goja.Undefined()
})