# How Debug Logs and Troubleshooting Work in Markdown Here: A Complete Guide

> Learn how debug logs are generated and troubleshooting mechanisms work in Markdown Here. Explore the DEBUG flag, Utils.consoleLog(), and extensibility for Chrome, Firefox, and Thunderbird.

- Repository: [Adam Pritchard/markdown-here](https://github.com/adam-p/markdown-here)
- Tags: how-to-guide
- Published: 2026-03-05

---

**Debug logs in Markdown Here are controlled by a module-level `DEBUG` flag in [`src/common/common-logic.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/common-logic.js), which when enabled formats and routes diagnostic strings through `Utils.consoleLog()` to the browser console, while an extensible `mylog` placeholder and safety wrappers provide additional troubleshooting flexibility across Chrome, Firefox, and Thunderbird.**

Markdown Here is a browser extension and email client add-on that converts Markdown to rich text. Understanding its **debug logs** and **troubleshooting** mechanisms is essential for developers maintaining the codebase or diagnosing cross-platform rendering issues.

## Debug Log Generation Mechanism

The logging system follows a deliberate five-step pipeline to minimize overhead in production while providing detailed traces during development.

### The DEBUG Flag and Gatekeeping

At the heart of the system is a module-level constant defined in [`src/common/common-logic.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/common-logic.js):

```javascript
var DEBUG = false;

```

This Boolean acts as a global switch. All diagnostic functions check this flag before performing any work. When `DEBUG` is `false`, the application avoids the overhead of string concatenation and console I/O entirely.

### Building and Forwarding Log Messages

The `debugLog()` function in [`src/common/common-logic.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/common-logic.js) handles message construction. It accepts variadic arguments and joins them with a ` // ` delimiter:

```javascript
function debugLog() {
  if (!DEBUG) { return; }
  
  var log = '';
  for (var i = 0; i < arguments.length; i++) {
    log += String(arguments[i]) + ' // ';
  }
  
  Utils.consoleLog(log);
}

```

This formatting makes multi-part trace statements readable at a glance. For example, calling `debugLog('forgotToRenderIntervalCheck', 'pref disabled')` produces the output `forgotToRenderIntervalCheck // pref disabled //`.

### Safe Console Output via Utils

All log output funnels through `Utils.consoleLog()` in [`src/common/utils.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/utils.js), which provides environment safety:

```javascript
function consoleLog(logString) {
  if (typeof(console) !== 'undefined') {
    console.log(logString);
  }
}

```

This wrapper ensures the extension does not throw reference errors in restricted contexts where `console` might be undefined, such as certain Thunderbird sandboxes or content security policy-restricted pages.

## Extending Troubleshooting Capabilities

Beyond the basic `DEBUG` system, Markdown Here provides several specialized mechanisms for different troubleshooting scenarios.

### External Logger Integration (mylog)

For production diagnostics or Firefox-specific deployments, the code includes a stub function in [`src/common/markdown-here.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/markdown-here.js):

```javascript
var mylog = function() {};

```

This intentionally empty function serves as an injection point. Developers can replace this stub with a remote logging implementation to capture diagnostic data from end users without requiring browser console access:

```javascript
var mylog = function(message) {
  fetch('https://log.myapp.example/collect', {
    method: 'POST',
    body: JSON.stringify({msg: message, timestamp: Date.now()}),
    headers: {'Content-Type': 'application/json'}
  });
};

```

### Test Suite Debugging

The Mocha test runner in [`src/common/test/mocha.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/test/mocha.js) utilizes the `debug` npm module for detailed test-time tracing:

```javascript
var debug = require('browser/debug');
// Later usage:
debug('timeout %d', ms);

```

This provides granular visibility into asynchronous test execution without cluttering the production build.

### Permanent Error Messages

Certain critical failure paths bypass the `DEBUG` gate entirely to surface urgent issues. In [`src/common/common-logic.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/common-logic.js), hard failures such as missing DOM elements trigger unconditional logs:

```javascript
Utils.consoleLog('Markdown Here was unable to find the Gmail "Send" button…');

```

These messages appear regardless of the debug flag state, ensuring users and developers immediately see configuration errors or breaking changes in email client DOM structures.

## Practical Debugging Examples

To enable comprehensive tracing during development, modify [`src/common/common-logic.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/common-logic.js):

```javascript
var DEBUG = true;

```

With this enabled, internal functions like `forgotToRenderIntervalCheck` emit detailed traces:

```javascript
function forgotToRenderIntervalCheck(focusedElem, MarkdownHere, MdhHtmlToText, marked, prefs) {
  if (!prefs['forgot-to-render-check-enabled-2']) {
    debugLog('forgotToRenderIntervalCheck', 'pref disabled');
    return;
  }
  debugLog('forgotToRenderIntervalCheck', 'starting check', focusedElem.tagName);
  // ... logic continues
}

```

Console output with `DEBUG = true`:

```

forgotToRenderIntervalCheck // pref disabled //

```

To capture logs from users experiencing issues in Firefox, combine the `mylog` replacement with the existing `debugLog` calls. Since `debugLog` routes through the console by default, you may also patch `Utils.consoleLog` to dual-write to both the console and your remote endpoint:

```javascript
var originalConsoleLog = Utils.consoleLog;
Utils.consoleLog = function(logString) {
  originalConsoleLog(logString); // Keep browser console output
  mylog(logString);              // Send to external service
};

```

## Summary

- **The `DEBUG` flag** in [`src/common/common-logic.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/common-logic.js) acts as a master switch; set it to `true` to enable all diagnostic output.
- **The `debugLog()` function** formats messages with ` // ` separators and forwards them to `Utils.consoleLog()`.
- **The `Utils.consoleLog()` wrapper** in [`src/common/utils.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/utils.js) safely calls `console.log` only when the environment supports it.
- **The `mylog` placeholder** in [`src/common/markdown-here.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/markdown-here.js) allows injection of remote logging for Firefox or production diagnostics.
- **Permanent error messages** bypass the debug flag to report critical failures like missing DOM elements immediately.

## Frequently Asked Questions

### How do I enable debug logs in Markdown Here?

Set `var DEBUG = true;` in [`src/common/common-logic.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/common-logic.js). This activates the `debugLog()` function throughout the codebase. You must reload the extension for the change to take effect in Chrome, or restart Thunderbird/Firefox depending on your installation method.

### Where are debug logs output when enabled?

Logs route to the browser's native console via `Utils.consoleLog()` in [`src/common/utils.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/utils.js). The wrapper checks `typeof(console) !== 'undefined'` before writing, preventing errors in restricted environments. No log files are created on disk; output appears in the Developer Tools console or Error Console depending on the platform.

### Can I send logs to an external server instead of the console?

Yes. Replace the empty `mylog` function in [`src/common/markdown-here.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/markdown-here.js) with your own implementation that POSTs data to your endpoint. While `debugLog` itself does not call `mylog` directly, you can override `Utils.consoleLog` to call both the native console and your `mylog` implementation for comprehensive remote monitoring.

### What's the difference between `debugLog` and `Utils.consoleLog`?

**`debugLog()`** is a developer-facing function in [`common-logic.js`](https://github.com/adam-p/markdown-here/blob/main/common-logic.js) that builds formatted strings and checks the `DEBUG` flag before doing any work. **`Utils.consoleLog()`** is a low-level utility in [`utils.js`](https://github.com/adam-p/markdown-here/blob/main/utils.js) that performs the actual environment-safe console write. All debug output flows through both functions, while critical error messages may call `Utils.consoleLog` directly to bypass the debug flag check.