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
- Use a valid syslog type when calling log(): 'debug', 'info', 'notice', 'warning', 'err', 'crit', 'alert', or 'emerg'.
- Set config `level` to a defined modern-syslog constant name such as 'LOG_INFO' or 'LOG_DEBUG'.
- Validate type/level strings before calling log(), e.g. with an allowlist check.
- 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
- Centralize logging through a wrapper that normalizes type names ('warn' -> 'warning', 'error' -> 'err') before calling logger.log().
- Set config `level` only to documented modern-syslog constant names like LOG_INFO or LOG_DEBUG.
- Check level strings are uppercase constants when switching backends from stdout to syslog.
- Wrap logger.log calls so a bad level degrades to LOG_INFO instead of crashing the stats server.
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.