npm
Source
Description
@wolfstar/plugin-logger replaces the built-in console logger of @wolfstar/http-framework
with one that fans every entry out to a list of transports. It implements the same ILogger contract, so code that
already writes through container.logger keeps working. It replaces
@wolfstar/logger, which has been removed.
Every logging backend is an optional peer dependency. Install only the ones you use:
SentryTransport takes the Sentry client you already use (@sentry/node, @sentry/bun, and so on) through its
constructor, so it needs no extra dependency.
Usage
Import theregister entry point before you create your Client:
console, like the framework’s built-in one.
Activating with modules
On framework 6.1 and later, list the ./module entry in modules in stars.config instead of importing register.
It needs the optional @wolfstar/kit peer dependency, at ^0.2.0 || ^0.3.0.
logger key of stars.config. The [specifier, options] tuple of modules
still works. Its options are merged over the logger key, so they win.
The optional @wolfstar/schema peer dependency types the logger key in defineConfig.
TypeScript only loads that type once the module is imported, so import @wolfstar/plugin-logger/module in stars.config.ts.
Module options must be JSON-serialisable. Transports are objects, so set them through ClientOptions.logger.transports.
The one exception is evlog, which the module can set up for you through its evlog option.
Without the stars CLI, pass the ./plugin definePlugin factory to the
plugins client option:
./plugin factory, and register. Combining them installs the plugin’s hooks twice.
Transports
A transport is any object implementingTransport:
LogPayload carries the raw values the caller passed, plus three fields derived from them. Every transport reads
an entry the same way through these fields:
createLogPayload():
level filters on top of the logger’s own level, so a Sentry sink can take only errors while the console keeps
everything:
console.error.
Sentry
SentryTransport takes its Sentry client through the constructor, so the package has no runtime dependency on a
Sentry SDK. Pass the module namespace of the SDK you use. What Sentry receives depends on the entry’s level:
Error, the transport reports it with captureException and keeps the entry’s message and
context in extra. Breadcrumbs are off by default because Sentry’s default console integration already records
them for console.*. Turning them on next to a ConsoleTransport duplicates them. Closing the logger flushes the
client, so the last fatal entry before an exit is delivered.
Backend adapters
Each adapter wraps a third-party logger as a transport and lives behind its own subpath, so the dependency is only resolved when you import it:evlog
EvlogTransport hands each entry to evlog as a structured event. The event holds message,
the context fields, tag, and the error with its cause chain. The transport does not format or deliver anything
itself. evlog owns the pipeline, so drains, enrichers, sampling, and redaction configured in initLogger apply to
your bot’s logs. All six levels map to the evlog method of the same name.
drain pipeline so closing the logger flushes it. Otherwise, events still buffered are lost when the
process exits. evlog also ships a Sentry drain, which makes SentryTransport redundant when evlog is already your
sink.
winston
WinstonTransport writes the message and the context fields, and serialises an Error into an error field with name, message, and stack. winston’s default npm levels have no fatal, so a fatal
entry is written as error with a fatal: true field. Closing the logger more than once is safe.
Create the winston logger with
level: 'silly'. winston’s own level (info by default) filters on top of the plugin’s and silently drops lower
entries.evlog plugin
The@wolfstar/plugin-logger/evlog/plugin entry sets up evlog for you. It runs evlog’s initLogger, adds an
EvlogTransport to the logger, and emits one wide event per interaction. Use it when evlog is your logging backend
and you want per-interaction events without wiring initLogger yourself.
evlog through the module
With the Stars module, set theevlog option. Use evlog: true for evlog’s defaults, or write the options inline:
Every other option (
env, pretty, silent, minLevel, sampling, redact, and so on) goes to evlog’s
initLogger. The options must be JSON-serialisable, since they are written into the built entry. The drain is a
function, so it comes from a file that Stars bundles with your bot. evlog: true, or options without drain, need
no file.
A drain that already has a flush method is used as is. Either way, closing the logger flushes it. evlog prints to
the console itself, so the module adds no ConsoleTransport next to it. Set silent: true when the drain should be
the only output.
Without the stars CLI, pass the drain to the evlogPlugin factory directly, before the logger plugin:
Wide events per interaction
The evlog plugin follows the client’s interaction lifecycle and drains one wide event per interaction. The event is created when a command, component, or modal starts, filled with its outcome, and emitted when it finishes. It goes through the same drain, sampling, redaction, and plugins as every other evlog event.interactions accepts true, false, or an object with commands, handlers, and autocomplete flags. Commands
and handlers are on by default. Autocomplete is off by default, since Discord sends a request for every keystroke.
useInteractionLogger() returns the interaction’s evlog request logger so
you can add fields to its wide event. It throws when called outside an interaction.
Upgrading the transports
The transport rework changes what some backends receive and which peer dependencies the package declares:- Custom transports:
LogPayloadnow hasmessage,error, andcontext. Read those instead of parsingvalues, and build test payloads withcreateLogPayload(). - Sentry: the
@sentry/nodepeer dependency is gone. Keep installing the Sentry SDK you pass asclient. Issues created from anErrornow carry the message and context inextrainstead of the rawvalues. - evlog: the
evlogpeer requires^2.30.0. Entries are structured events instead of flattened strings, andtraceandfatalno longer collapse intodebuganderror. Update queries or dashboards that relied on the old string output. - winston: entries now spread the context fields at the top level instead of a
valuesarray. AnErroris written as anerrorfield withname,message, andstack(JSON used to turn it into{}).fatalentries are still written aserror, now with afatal: truefield.
Migration from @wolfstar/logger
trace, debug, info, warn, error, and fatal methods behave the same. LogLevel keeps its ordering and is
now imported from @wolfstar/http-framework.