Reduce some debug logs

1 - Remove the double logging of "load" dispatch
2 - On even registration, just log the event target type, not the full node
3 - Most significantly, rather than logging unknown properties (both global and
    per object) as they happen, collect them and log the on context ends. This
    log includes a count of how often it happened. On some pages, this reduces
    the number of unknown property messages by thousands.
This commit is contained in:
Karl Seguin
2026-02-08 14:38:50 +08:00
parent aca3fae6b1
commit 403ee9ff9e
5 changed files with 37 additions and 17 deletions

View File

@@ -92,7 +92,7 @@ pub const Callback = union(enum) {
pub fn register(self: *EventManager, target: *EventTarget, typ: []const u8, callback: Callback, opts: RegisterOptions) !void {
if (comptime IS_DEBUG) {
log.debug(.event, "eventManager.register", .{ .type = typ, .capture = opts.capture, .once = opts.once, .target = target });
log.debug(.event, "eventManager.register", .{ .type = typ, .capture = opts.capture, .once = opts.once, .target = target.toString() });
}
// If a signal is provided and already aborted, don't register the listener

View File

@@ -713,10 +713,6 @@ fn _documentIsComplete(self: *Page) !void {
ls.toLocal(maybe_inline_listener),
.{ .context = "Page dispatch load events" },
);
if (comptime IS_DEBUG) {
log.debug(.page, "load event for element", .{ .element = element });
}
}
// `_to_load` can be cleaned here.

View File

@@ -126,6 +126,8 @@ scheduler: Scheduler,
// down.
shutting_down: bool = false,
unknown_properties: (if (IS_DEBUG) std.StringHashMapUnmanaged(UnknownPropertyStat) else void) = if (IS_DEBUG) .{} else {},
const ModuleEntry = struct {
// Can be null if we're asynchrously loading the module, in
// which case resolver_promise cannot be null.
@@ -158,6 +160,16 @@ pub fn fromIsolate(isolate: js.Isolate) *Context {
}
pub fn deinit(self: *Context) void {
if (comptime IS_DEBUG) {
var it = self.unknown_properties.iterator();
while (it.next()) |kv| {
log.debug(.unknown_prop, "unknown property", .{
.property = kv.key_ptr.*,
.occurrences = kv.value_ptr.count,
.first_stack = kv.value_ptr.first_stack,
});
}
}
defer self.env.app.arena_pool.release(self.arena);
var hs: js.HandleScope = undefined;
@@ -1092,3 +1104,8 @@ pub fn stopHeapProfiler(self: *Context) !struct { []const u8, []const u8 } {
return .{ allocating, snapshot };
}
const UnknownPropertyStat = struct {
count: usize,
first_stack: []const u8,
};

View File

@@ -459,11 +459,8 @@ pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8
.{ "CLOSURE_FLAGS", {} },
});
if (!ignored.has(property)) {
log.debug(.unknown_prop, "unknown global property", .{
.info = "but the property can exist in pure JS",
.stack = local.stackTrace() catch "???",
.property = property,
});
const key = std.fmt.bufPrint(&local.ctx.page.buf, "Window:{s}", .{property}) catch return 0;
logUnknownProperty(local, key) catch return 0;
}
}
@@ -514,12 +511,8 @@ pub fn unknownObjectPropertyCallback(comptime JsApi: type) *const fn (?*const v8
const ignored = std.StaticStringMap(void).initComptime(.{});
if (!ignored.has(property)) {
log.debug(.unknown_prop, "unknown object property", .{
.object = if (@hasDecl(JsApi.Meta, "name")) JsApi.Meta.name else @typeName(JsApi),
.info = "but the property can exist in pure JS",
.stack = local.stackTrace() catch "???",
.property = property,
});
const key = std.fmt.bufPrint(&local.ctx.page.buf, "{s}:{s}", .{ if (@hasDecl(JsApi.Meta, "name")) JsApi.Meta.name else @typeName(JsApi), property }) catch return 0;
logUnknownProperty(local, key) catch return 0;
}
// not intercepted
return 0;
@@ -527,6 +520,20 @@ pub fn unknownObjectPropertyCallback(comptime JsApi: type) *const fn (?*const v8
}.wrap;
}
fn logUnknownProperty(local: *const js.Local, key: []const u8) !void {
const ctx = local.ctx;
const gop = try ctx.unknown_properties.getOrPut(ctx.arena, key);
if (gop.found_existing) {
gop.value_ptr.count += 1;
} else {
gop.key_ptr.* = try ctx.arena.dupe(u8, key);
gop.value_ptr.* = .{
.count = 1,
.first_stack = try ctx.arena.dupe(u8, (try local.stackTrace()) orelse "???"),
};
}
}
// Given a Type, returns the length of the prototype chain, including self
fn prototypeChainLength(comptime T: type) usize {
var l: usize = 1;

View File

@@ -137,7 +137,7 @@ pub fn format(self: *EventTarget, writer: *std.Io.Writer) !void {
pub fn toString(self: *EventTarget) []const u8 {
return switch (self._type) {
.node => |n| return n.className(),
.node => return "[object Node]",
.generic => return "[object EventTarget]",
.window => return "[object Window]",
.xhr => return "[object XMLHttpRequestEventTarget]",