statsd/statsd · error

Undefined log level: ${level}

Error message

Undefined log level: ${level}

What it means

When logging to the syslog backend, Logger.log() maps the requested type to a syslog priority constant by building the string 'LOG_' + type.toUpperCase() (or falls back to the configured default level). If modern-syslog does not export a constant with that name (e.g. LOG_FOO is undefined), the throw fires before calling this.util.log.

Source

Thrown at lib/logger.js:35

};

Logger.prototype = {
  log: function (msg, type) {
    if (this.backend == 'stdout') {
      if (!type) {
        type = 'DEBUG';
      }
      this.util.log(type + ": " + msg);
    } else {
      let level;
      if (!type) {
        level = this.level;
      } else {
        level = "LOG_" + type.toUpperCase();
      }

      if (!this.util[level]) {
        throw "Undefined log level: " + level;
      }

      this.util.log(this.util[level], msg);
    }
  }
};

exports.Logger = Logger;

View on GitHub (pinned to f7157b8806)

Solutions

  1. Use a valid syslog type when calling log(): 'debug', 'info', 'notice', 'warning', 'err', 'crit', 'alert', or 'emerg'.
  2. Set config `level` to a defined modern-syslog constant name such as 'LOG_INFO' or 'LOG_DEBUG'.
  3. Validate type/level strings before calling log(), e.g. with an allowlist check.
  4. If stdout semantics are needed (any label accepted), keep backend as 'stdout' rather than syslog.

Example fix

// before
logger.log("cache expired", "warn");

// after
logger.log("cache expired", "warning"); // maps to LOG_WARNING
Defensive patterns

Strategy: validation

Validate before calling

const SYSLOG_LEVELS = ['debug','info','notice','warning','err','crit','alert','emerg'];
function assertLogLevel(type) {
  if (type && !SYSLOG_LEVELS.includes(String(type).toLowerCase())) {
    throw new Error(`Invalid log level '${type}' for syslog backend`);
  }
}

Type guard

function isSyslogLevel(t) {
  return typeof t === 'string' &&
    ['LOG_DEBUG','LOG_INFO','LOG_NOTICE','LOG_WARNING','LOG_ERR','LOG_CRIT','LOG_ALERT','LOG_EMERG']
      .includes('LOG_' + t.toUpperCase());
}

Try / catch

try {
  logger.log(msg, type);
} catch (e) {
  if (String(e).startsWith('Undefined log level')) {
    console.error(`Bad log level '${type}', retrying at LOG_INFO`);
    logger.log(msg, 'info');
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling logger.log('message', 'foo') with a syslog backend where 'foo' does not map to a modern-syslog constant (valid types derive from LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_CRIT, LOG_ALERT, LOG_EMERG); or configuring `level: "LOG_VERBOSE"`/any non-standard default level in the config so that the no-type call path resolves to an undefined constant.

Common situations: Typo'd or custom level strings in the config `level` option; calling log() with a type string like 'warn' instead of 'warning' or 'error' instead of 'err'; switching from a logger that accepted arbitrary level names to the syslog backend; using log types that worked under stdout (where any type string is accepted verbatim) then enabling syslog.

Related errors


AI-assisted analysis of statsd/statsd@f7157b8806 (2026-09-02). Data as JSON: /api/errors/59cb550bf56c4734. Report an issue: GitHub.