Search code examples
javascriptangularjsionic-frameworkremote-debugging

How to remote debug console.log


Problem: when developing an Ionic2 app, I would like to see the console.log messages generated on my IPhone but I do not have a Mac or I do have one but found that the web inspector feature sucks.

Note this is applicable to any kind of remote javascript, not only to Angular/ionic.

This is a Q&A style question, meaning I'll provide the answer below because I think it's very useful for lots of people.


Solution

  • The solution is a hook into your javascript that will intercept all console.log and errors and send them to a server.

    Place the following code into your index.html page:

    <script>
    // Function that will call your webserver
    logToServer = function(consoleMsg) {
        // only do this if on device
        if (window.cordova) {
            let jsonTxt = customStringify(consoleMsg);
            var xmlHttp = new XMLHttpRequest();
            xmlHttp.open("GET", 'http://yourserver/console2server.php?msg=' + jsonTxt, true); //async
            xmlHttp.send(null);
        }
    }
    
    // Test if you receive this on the server
    logToServer("OPENING IONIC APP");
    
    // intercept console logs
    (function () {
        var oldLog = console.log;
        console.log = function (message) {
            // DO MESSAGE HERE.
            logToServer(message);
            oldLog.apply(console, arguments);
        };
    })();
    
    // intecept errors
    if (window && !window.onerror) {
        window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
            logToServer(errorMsg);
            logToServer(errorObj);
            return false;
        }
    }
    
    // this is optional, but it avoids 'converting circular structure' errors
    customStringify = function (inp) {
        return JSON.stringify(inp, function (key, value) {
            if (typeof value === 'object' && value !== null) {
                if (cache.indexOf(value) !== -1) {
                    // Circular reference found, discard key
                    console.log("circular dep found!!");
                    return;
                }
                // Store value in our collection
                cache.push(value);
            }
            return value;
        });
    }
    </script>
    

    On the server side, I use PHP but you could use whatever you want:

    <?php
    //allow CORS request
    header('Access-Control-Allow-Origin: *');
    
    if(isset($_GET['msg'])) {
        //you can also log to a file or whatever, I just log to standard logs
        error_log("[CONSOLE.LOG] ".json_decode($_GET['msg'], true));
    }
    ?>
    

    Happy debugging!