Skip to content

Instantly share code, notes, and snippets.

@liamcain
Last active April 22, 2024 05:57
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liamcain/3f21f1ee820cb30f18050d2f3ad85f3f to your computer and use it in GitHub Desktop.
Save liamcain/3f21f1ee820cb30f18050d2f3ad85f3f to your computer and use it in GitHub Desktop.
Save console messages to logfile for mobile debugging
declare module "obsidian" {
interface App {
isMobile: boolean;
}
}
// Call this method inside your plugin's `onLoad` function
function monkeyPatchConsole(plugin: Plugin) {
if (!plugin.app.isMobile) {
return;
}
const logFile = `${plugin.manifest.dir}/logs.txt`;
const logs: string[] = [];
const logMessages = (prefix: string) => (...messages: unknown[]) => {
logs.push(`\n[${prefix}]`);
for (const message of messages) {
logs.push(String(message));
}
plugin.app.vault.adapter.write(logFile, logs.join(" "));
};
console.debug = logMessages("debug");
console.error = logMessages("error");
console.info = logMessages("info");
console.log = logMessages("log");
console.warn = logMessages("warn");
}
@shabegom
Copy link

I added the following to make Typescript happier:

declare module "obsidian" {
    interface App {
        isMobile: boolean;
    }
}

and gave const logs a type:

const logs: string[] = []

optional unless you have strict typescript rules

@ryanpcmcquen
Copy link

This is beautiful!

@ryanpcmcquen
Copy link

Here's my slightly modified version. If you import Platform from obsidian, you get the isMobile type declaration:

// Call this method inside your plugin's
// `onload` function like so:
// monkeyPatchConsole(this);
const monkeyPatchConsole = (plugin: Plugin) => {
    if (!Platform.isMobile) {
        return;
    }

    const logFile = `${plugin.manifest.dir}/logs.txt`;
    const logs: string[] = [];
    const logMessages = (prefix: string) => (...messages: unknown[]) => {
        logs.push(`\n[${prefix}]`);
        for (const message of messages) {
            logs.push(String(message));
        }
        plugin.app.vault.adapter.write(logFile, logs.join(" "));
    };

    console.debug = logMessages("debug");
    console.error = logMessages("error");
    console.info = logMessages("info");
    console.log = logMessages("log");
    console.warn = logMessages("warn");
};

@AndrewNatoli
Copy link

Hiya @liamcain - I was wondering if you're still having luck if and when you ever need this script. I tried adding it to the obsidian-checklist-plugin to try and find why it fails to enable on iOS. If I knock out the platform restriction line and run it on desktop, I generate a log file just fine. Using it with the mobile app (Obsidian 1.1), I don't get a log file.

I've tried using an iCloud vault as well as an Obsidian Sync vault, having the log file saved to the plugin directory as well as a markdown file in the vault. Was hoping I would see a file appear in the Sync console that maybe Sync rejects (the way Sync seems to delete irrelevant files in plugin directories) but there was no trace of a log file being created.

@liamcain
Copy link
Author

@AndrewNatoli Since this script doesn't run until after the plugin is loaded, it won't help you track down initialization issues. For those, I recommend taking a look at your package dependencies and make sure that all the packages can run in a browser environment (as opposed to a node environment).


If you're still having trouble, another option would be loading this script from a separate plugin. You can do this either by creating an entirely barebones plugin that just calls this script, or making this a startup script with any of the existing plugins that allow for running arbitrary javascript (Templater, Dataview, CustomJS all come to mind).

That way, you can have this script run before trying to enable the plugin you're trying to debug.

@AndrewNatoli
Copy link

@liamcain That suggestion was a huge help, thanks!

@velebit
Copy link

velebit commented Mar 14, 2023

Thank you for this! I needed to debug a loading issue on mobile, so I did package this as a plugin:
https://github.com/velebit/obsidian-save-console-log
The plugin eliminates the check for isMobile, since you can just not enable the plugin if you don't want hot patching.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment