From 769d99e7bde4967edfca1aa56ed5d5bb77478e92 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 20 May 2025 11:22:56 +0800 Subject: [PATCH] Tweak debug logging 1 - Add a log_level build option to control the default log level from the build (e.g. -Dlog_level=debug). Defaults to info 2 - Add a new boolean log_unknown_properties build option to enable logging unknown properties. Defautls to false. 3 - Remove the log debug for script eval - this can be a huge value (i.e. hundreds of KB), which makes the debug log unusable IMO. --- build.zig | 14 +++++++++++++- src/browser/page.zig | 6 +----- src/main.zig | 6 +++--- src/runtime/js.zig | 28 ++++++++++++++++++++++++++++ src/telemetry/lightpanda.zig | 4 ++-- 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/build.zig b/build.zig index 97cf4c06..50b01afe 100644 --- a/build.zig +++ b/build.zig @@ -44,6 +44,18 @@ pub fn build(b: *std.Build) !void { b.option([]const u8, "git_commit", "Current git commit") orelse "dev", ); + opts.addOption( + std.log.Level, + "log_level", + b.option(std.log.Level, "log_level", "The log level") orelse std.log.Level.info, + ); + + opts.addOption( + bool, + "log_unknown_properties", + b.option(bool, "log_unknown_properties", "Log access to unknown properties") orelse false, + ); + const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); @@ -175,7 +187,7 @@ fn common(b: *std.Build, opts: *std.Build.Step.Options, step: *std.Build.Step.Co else => {}, } - mod.addImport("build_info", opts.createModule()); + mod.addImport("build_config", opts.createModule()); mod.addObjectFile(mod.owner.path(lib_path)); } diff --git a/src/browser/page.zig b/src/browser/page.zig index f34604f3..88f61764 100644 --- a/src/browser/page.zig +++ b/src/browser/page.zig @@ -647,11 +647,7 @@ pub const Page = struct { } return error.JsErr; }; - - if (builtin.mode == .Debug) { - const msg = try res.toString(page.arena); - log.debug("eval script {s}: {s}", .{ src, msg }); - } + _ = res; if (self.onload) |onload| { _ = page.scope.exec(onload, "script_on_load") catch { diff --git a/src/main.zig b/src/main.zig index f6b73bec..f5eb4086 100644 --- a/src/main.zig +++ b/src/main.zig @@ -25,14 +25,14 @@ const App = @import("app.zig").App; const Platform = @import("runtime/js.zig").Platform; const Browser = @import("browser/browser.zig").Browser; +const build_config = @import("build_config"); const parser = @import("browser/netsurf.zig"); -const version = @import("build_info").git_commit; const log = std.log.scoped(.cli); pub const std_options = std.Options{ // Set the log level to info - .log_level = .info, + .log_level = @enumFromInt(@intFromEnum(build_config.log_level)), // Define logFn to override the std implementation .logFn = logFn, @@ -59,7 +59,7 @@ pub fn main() !void { return std.process.cleanExit(); }, .version => { - std.debug.print("{s}\n", .{version}); + std.debug.print("{s}\n", .{build_config.git_commit}); return std.process.cleanExit(); }, else => {}, diff --git a/src/runtime/js.zig b/src/runtime/js.zig index 2de606a4..d1a21d06 100644 --- a/src/runtime/js.zig +++ b/src/runtime/js.zig @@ -1407,6 +1407,9 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { fn generateNamedIndexer(comptime Struct: type, template_proto: v8.ObjectTemplate) void { if (@hasDecl(Struct, "named_get") == false) { + if (comptime @import("build_config").log_unknown_properties) { + generateDebugNamedIndexer(Struct, template_proto); + } return; } const configuration = v8.NamedPropertyHandlerConfiguration{ @@ -1441,6 +1444,31 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { template_proto.setNamedProperty(configuration, null); } + fn generateDebugNamedIndexer(comptime Struct: type, template_proto: v8.ObjectTemplate) void { + const configuration = v8.NamedPropertyHandlerConfiguration{ + .getter = struct { + fn callback(c_name: ?*const v8.C_Name, raw_info: ?*const v8.C_PropertyCallbackInfo) callconv(.c) u8 { + const info = v8.PropertyCallbackInfo.initFromV8(raw_info); + const isolate = info.getIsolate(); + const context = isolate.getCurrentContext(); + + const scope: *Scope = @ptrFromInt(context.getEmbedderData(1).castTo(v8.BigInt).getUint64()); + + const property = valueToString(scope.call_arena, .{ .handle = c_name.? }, isolate, context) catch "???"; + log.debug("unknwon named property {s}.{s}", .{ @typeName(Struct), property }); + return v8.Intercepted.No; + } + }.callback, + + // This is really cool. Without this, we'd intercept _all_ properties + // even those explicitly set. So, node.length for example would get routed + // to our `named_get`, rather than a `get_length`. This might be + // useful if we run into a type that we can't model properly in Zig. + .flags = v8.PropertyHandlerFlags.OnlyInterceptStrings | v8.PropertyHandlerFlags.NonMasking, + }; + template_proto.setNamedProperty(configuration, null); + } + fn generateUndetectable(comptime Struct: type, template: v8.ObjectTemplate) void { const has_js_call_as_function = @hasDecl(Struct, "jsCallAsFunction"); diff --git a/src/telemetry/lightpanda.zig b/src/telemetry/lightpanda.zig index 06b0a610..3a336a53 100644 --- a/src/telemetry/lightpanda.zig +++ b/src/telemetry/lightpanda.zig @@ -1,6 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); -const build_info = @import("build_info"); +const build_config = @import("build_config"); const Thread = std.Thread; const Allocator = std.mem.Allocator; @@ -151,7 +151,7 @@ const LightPandaEvent = struct { try writer.write(builtin.cpu.arch); try writer.objectField("version"); - try writer.write(build_info.git_commit); + try writer.write(build_config.git_commit); try writer.objectField("event"); try writer.write(@tagName(std.meta.activeTag(self.event)));