How to Enhance Firebase Emulator Logs

Beautify, denoise, and improve Firebase emulator logs.

I’m a huge fan of Firebase and use the emulator extensively for local development with social media APIs. There are many great features of emulator like cloud function simulation, firestore and even pub/sub. If you output JSON logs to the console using console.logThe output is acceptable, especially if you specify the format. JSON.stringify({...}, null, "t"). However, things get complicated with Firebase. suggestion woodcutter. Logger by default google cloud loggerYou can structure your logs and JSON for easy viewing and search in the Google Cloud dashboard.

The Firebase logger output looks great in the Google Cloud Dashboard, but doesn’t look very nice in the terminal output.

Improved Firebase emulator log

What would you ideally want from your Firebase emulator logs?

  • Formatting of JSON objects when using loggers.
  • Color the output to highlight errors.
  • “functions: Running the Functions emulator in debug mode (port=9229). This means the functions are executed in sequence rather than in parallel.”

Firebase doesn’t provide these features “yet”, so let’s build our own enhancements.

Save the output of the Firebase emulator to a file, monitor the file for changes, process the changes (format, etc.), and output the processed data to the console.

  1. a copy Firebase-Emulator-Logging GitHub repository. This is a Node.js app. general run npm install in the cloned directory.
  2. Start the Firebase emulator as usual and output to a file. for example: firebase emulators:start > save.txt or npm run serve > save.txt.
  3. Return to the cloned directory and run the Node app with: node index.js --file {file location}. for example: node index.js --file ./save.txt
  4. Enjoy the new log!
Firebase format log
Formatted Firebase emulator logs

Improved log parameters

When running a Node app, you have several options. I already looked at –file, but you can also set the output to quiet. This means that system output starting with “function” or “hosting” is suppressed and pretty formatting can be turned off.

parameter explanation required
-file source file of log yes
-quiet Suppress system logging such as “function”, “hosting”, “storage” and “pubsub” no
-pretty Turn off pretty formatting of JSON objects. default: true no
Firebase emulator logging parameters

behind the scenes

To view all codes, go to: GitHubOr here is the index.js file:

import readline from "readline";
import TailFile from "@logdna/tail-file";
import colorizer from "json-colorizer";

const QUIET_STRING = ["functions", "hosting", "storage", "pubsub"];

const quiet = process.argv.indexOf("--quiet");
const prettyOff = process.argv.indexOf("--pretty-off");
const fileIndex = process.argv.indexOf("--file");

if (fileIndex <= -1 || !process.argv[fileIndex + 1]) {
  console.error(
    "You seem to be missing the --file argument. Please provide a file to tail."
  );
  process.exit(1);
}

const options = {
  pretty: prettyOff <= -1 ? true : false,
  colors: { STRING_LITERAL: "white" },
};

async function startTail() {
  const tail = new TailFile(process.argv[fileIndex + 1]).on(
    "tail_error",
    (err) => {
      console.error("TailFile had an error!", err);
    }
  );

  try {
    await tail.start();
    const linesplitter = readline.createInterface({
      input: tail,
    });

    linesplitter.on("line", (line) => {
      if (
        quiet &&
        QUIET_STRING.some((str) =>
          new RegExp(`(?<=^...)(.*)${str}`, "gm").test(line)
        )
      )
        return;

      let newLine = line;
      if (newLine.startsWith(">") && newLine.endsWith("}")) {
        const overrideOptions = { ...options };

        try {
          const json = JSON.parse(newLine.slice(3));
          switch (json?.severity) {
            case "INFO":
              overrideOptions.colors.STRING_KEY = "blue";
              overrideOptions.colors.BRACE = "blue";
              break;
            case "WARNING":
              overrideOptions.colors.STRING_KEY = "yellow";
              overrideOptions.colors.BRACE = "yellow";
              break;
            case "ERROR":
              overrideOptions.colors.STRING_KEY = "red";
              overrideOptions.colors.BRACE = "red";
              break;
            default:
              break;
          }

          newLine = colorizer(newLine.slice(3), overrideOptions);
        } catch (err) {
          // ignore
        }
      }

      console.log(newLine);
    });
  } catch (err) {
    console.error("Cannot start. Does the file exist?", err);
  }
}

startTail().catch((err) => {
  process.nextTick(() => {
    throw err;
  });
});

Two external NPM packages are used.
import TailFile from "@logdna/tail-file";
import colorizer from "json-colorizer";

tail-file is a nice package that allows “tailing” of files. An event is fired whenever something changes. JSON colorizer is a package that allows you to specify which elements of JSON to apply color to.

Source

Explore additional categories

Explore Other Classes