@deployanyway/doggo-log
v1.0.0
Published
Node.js logs with async request context, JSON, levels and configurable redaction. Good logs. Very good logs. Fewer lost request IDs.
Maintainers
Readme
doggo-log
Fetch the Context: async request scopes and redaction (1.0.0)
The Node-only @deployanyway/doggo-log/context entry exports createRequestLogger(options). Use one logger per service and run(context, callback, ...args) per request. AsyncLocalStorage carries the copied scalar context through awaited work; concurrent requests remain isolated. Child loggers share the active scope, and nested scopes restore the outer context when they finish.
import { createRequestLogger } from "@deployanyway/doggo-log/context";
const log = createRequestLogger({ json: true, context: { service: "api" } });
const db = log.child("database");
await log.run(
{ requestId: "request-42", authorization: "private-header" },
async () => {
await Promise.resolve();
db.info("Query finished"); // requestId follows the work; authorization is redacted
},
);
log.dispose(); // only after all work has completedrun preserves callback return values/promises/errors. Scoped fields override static context, nested fields merge, and getContext() returns a fresh raw scope copy (do not expose it publicly). Outside scopes only static context remains. dispose disables tracking and prevents future run calls. Do not dispose an active service per request. Async boundaries that lose Node context, worker threads and external processes require explicit handoff; scopes do not cross them automatically. Reference: Node asynchronous context documentation.
Redaction runs before writer callbacks and returned JSON/text. Default credential context keys are password, passwd, token, accessToken, refreshToken, authorization, cookie, secret and apiKey, case-insensitive with hyphens/underscores normalized. Configure redact: {keys: ['private'], values: ['literal-secret'], replacement: '[REDACTED]'}. keys replaces the default key list; values replaces exact literals in formatted messages, prefixes and string context values, longest first. redact: false explicitly disables it. Text logs now include supplied context, so request IDs are useful outside JSON too.
Redaction is scoped: context fields must be scalar; it does not inspect arbitrary objects formatted in message arguments, discover unknown secrets, decode transformed tokens or scrub another writer's output. Avoid logging credentials in arbitrary message objects. Protect context keys and configure known literal values where needed. Filtering skips providers/writers; failed writes preserve bark rotation.
doggo-log info 'Request complete' --context '{"requestId":"42","authorization":"private"}' --json
doggo-log info 'token=demo-only' --redact-values '["demo-only"]' --json
node node_modules/@deployanyway/doggo-log/examples/fetch-context.mjs--redact-keys accepts comma-separated context keys; --redact-values accepts a JSON string array. The runnable Node example makes two concurrent loopback HTTP requests and demonstrates isolated redacted logs. Browser demos can preview formatting/context redaction; AsyncLocalStorage itself runs in Node, not a browser shim.
Stable v1 contract
Node 22.13+ or Node 24. MIT licensed. CLI flags, structured fields, ESM/CommonJS exports and declarations are covered by tests and installed-package checks. Existing 0.4 APIs remain available except the explicitly documented doggo-log redaction/text-context changes. Future incompatible public API changes require a major release; callers should consume structured fields rather than parse jokes. Exact humorous wording and seeded catalog choices are version-specific. No telemetry, external API keys or network service is needed for core use.
Run npm test, npm run lint, npm run format:check, npm run coverage, npm run test:types and npm run verify:package from a source checkout. Runnable examples are shipped under examples/. The root demo is https://deployanyway.github.io/.
Commentary that stays useful (0.4.0)
48 original lines: eight per log level. Default barkMode: 'classic' preserves the existing first-line commentary. Opt into barkMode: 'rotate' for variation without repeats until that level's eight lines have been emitted. A seed selects a repeatable starting point by prefix and level; omitted seed starts with the first line. Filtering and quiet mode do not consume rotation. Each child logger owns its own sequence.
npx @deployanyway/doggo-log warn 'Retry budget almost exhausted' --bark --bark-mode rotate --seed demo --jsonimport { createDogLogger, barkLines } from "@deployanyway/doggo-log";
const log = createDogLogger({
bark: true,
barkMode: "rotate",
seed: "job-42",
json: true,
});
const job = log.child("worker", { jobId: "42" });
job.info("Job accepted");
job.warn("Retry budget almost exhausted");
job.success("Job complete");
console.log(barkLines("warn"));Caller messages and JSON context remain separate from commentary. barkLines(level) returns a fresh catalog copy. The logger is intentionally small: it does not provide persistence, transport, redaction or a production observability backend.
Version 0.4.0: install from npm with Node 22.13+ or Node 24. See MIGRATION.md for changes from 0.2.0.
A tiny Node.js console logger with JSON output, log levels, and dog emojis. Good logs. Very good logs.
🐶 INFO Server started
🐾 SUCCESS Tests passed
🦴 WARN API is getting slow
🚨 ERROR Database connection failedInstallation
Available on npm. Requires Node 22 or later. You can also run from source with Node 22 or 24:
git clone https://github.com/DeployAnyway/doggo-log.git
cd doggo-log
git checkout main
npm ci
node examples/basic.jsInstall from npm: npm install @deployanyway/doggo-log.
Quick start
import { doglog, createDogLogger } from "@deployanyway/doggo-log";
doglog.info("Server started");
doglog.success("Tests passed");
doglog.warn("API is getting slow");
doglog.error("Database connection failed");
const logger = createDogLogger({
timestamp: true,
level: "debug",
prefix: "app",
});
logger.debug("Listening on port %d", 3000);CLI example
node bin/cli.js success "Tests passed" --no-emoji
node bin/cli.js info "Server started" --json --timestampRun with npx: npx @deployanyway/doggo-log info "Server started".
API
doglog is the default logger. createDogLogger(options = {}) makes an independent
logger. Both expose log, info, success, warn, error, and debug.
Methods accept the same message arguments as Node's util.format, including
format placeholders, objects, and Error instances. Zero arguments log the label
alone. Each method returns its emitted string, or undefined if filtered/quiet.
Default output sends warn/error to stderr and other methods to stdout. Logging an error does not set an exit code. The library never calls process.exit. Errors from a custom output function propagate to the caller.
Options
| Option | Default | Behavior |
| ----------- | -------------- | ------------------------------------------------------ |
| emoji | true | Dog-themed level symbols |
| color | false | ANSI color for text lines; ignored for JSON |
| timestamp | false | UTC ISO timestamp |
| json | false | One JSON object per call; emoji/color omitted |
| quiet | false | Suppress all output |
| prefix | empty string | Text prefix or JSON prefix field |
| level | info | Minimum level |
| write | console output | Function (line, level) for each emitted line |
| clock | current Date | Function returning a valid Date when timestamp enabled |
Levels: debug (10), log/info/success (20), warn (30), error (40). Thresholds
include all levels with equal or higher ranks. At info, debug is suppressed.
At warn, only warn and error appear. JSON always includes level and message,
with prefix and timestamp included when enabled/nonempty. Object arguments
are formatted into the message string; they are not separate JSON fields.
Invalid options throw TypeError; unknown levels throw RangeError. Names are case sensitive. Unknown option keys are ignored. Quiet/filtered calls skip message formatting, clock calls, and output. No transports, rotation, telemetry, remote service, or production dependencies are required.
CLI reference
doggo-log <method> <message> [options]
| Flag | Behavior |
| ----------------- | --------------------------------- |
| --json | JSON output |
| --timestamp | ISO timestamp |
| --no-emoji | Plain labels |
| --color | ANSI color |
| --prefix text | Prefix |
| --level name | Minimum level (CLI default debug) |
| --quiet | Suppress output |
| --help, -h | Usage |
| --version, -v | Version |
Quote messages containing shell punctuation. Use -- before positional arguments
containing dash-prefixed text. CLI messages are strings, without placeholder
interpolation. Exit 0 means success (including filtered calls and error logging);
exit 2 means invalid arguments. No stdin support in this MVP.
Development and examples
npm ci
node examples/basic.js
npm test
npm run lint
npm run format:check
npm pack --dry-runES modules and Node's test runner. CI runs Node 22/24. Development tooling requires Node 22.13+ or 24. Styles and behavior are separate for easy contributions.
Contributing
See CONTRIBUTING.md.
License
MIT.
More from DeployAnyway
Tools for developers who probably know better.
Scoped logs, optional barks
Use logger.child("database") to create an independent logger with a nested prefix. Enable { bark: true } or CLI --bark for dog commentary. JSON preserves the original message and adds a separate commentary field. Filtering still suppresses output.
npx @deployanyway/doggo-log success "Migration complete" --bark --prefix databaseAPI (import the named functions from this package):
createDogLogger({ bark: true, prefix: "api" })
.child("database")
.success("Migration complete");Give your dog a request ID
import { createDogLogger } from "@deployanyway/doggo-log";
const log = createDogLogger({ json: true, context: { service: "api" } });
const requestLog = log.child("request", { requestId: "abc" });
requestLog.info("Fetching the evidence.");
log.withContext({ retry: 1 }).warn("Suspicious squirrel detected.");JSON records carry a separate context object. Fields must be strings, finite numbers, booleans or null. Configuration is copied; children override fields without mutating parents. Context is intentionally omitted from plain output. Nested data is rejected rather than producing circular or ambiguous logs. Do not log secrets; this is not a redaction framework.
echo "Build passed" | node bin/cli.js success --stdin --bark
node bin/cli.js info "Request accepted" --json --context '{"requestId":"abc"}'--stdin explicitly reads UTF-8 input up to 256 KiB; message arguments win. Warn/error go to stderr, other methods to stdout. Logging error still exits 0; malformed configuration exits 2. --no-color and NO_COLOR win over --color. PowerShell quoting differs from POSIX shells; use a simple JSON file or the API when shell quoting becomes the least funny part.
Run from source
git clone --branch main https://github.com/DeployAnyway/doggo-log.git
cd doggo-log
npm ci
npm run build
node bin/cli.js --helpCandidate quality standard
Version 0.3 provides useful declaration types, ESM/CommonJS exports, installed-archive checks, and coverage gates (90% statements/lines/functions, 85% branches). CI covers Linux Node 22/24 and Windows/macOS Node 24. Node 22.13+ is required. No runtime dependencies, telemetry or network requests.
From a source checkout: npm ci, npm run build, npm run coverage, npm run test:types, npm run verify:package. Pack verification installs a temporary local archive and checks module entries, types, executable and offline npm exec.
Contribution guide · Conduct · Security · Roadmap · Migration.
Tools for developers who probably know better. Software nobody requested, built with questionable priorities, and shipped with absolute confidence!
