On This Page

Logging and Diagnostics

21 symbols from @neontechspace/fluxerly

Interfaces#

ClientCounters#

Running totals for one client since creation, returned by diagnostics().counters

Values only increase

interface ClientCounters
cacheChangesDropped#

Cache changes not delivered to a cache.onChange listener because its waiting changes reached maxPendingChanges

number
cleanupFailures#

Shutdown or subscription cleanup steps that failed

number
commandRejections#

Prefix commands rejected by a guard, cooldown or argument parser

number
eventsDropped#

Events not delivered to a subscription, by reason

The reason overflow is a full queue, malformed is a rejected dispatch, collector is a full collector buffer and closed is a shutdown or closed subscription

closed

Events still waiting when a subscription or the client closed, plus events a draining shutdown refused after it stopped accepting new ones

number
collector

Messages or reactions dropped because a collector buffer was full

number
malformed

Gateway dispatches skipped because they failed validation

number
overflow

Events dropped because a subscription queue was full

number
eventsDroppedByEvent#

Events not delivered, by event name, counted at the same places as eventsDropped

A name appears after its first drop. Drops that have no known event name are counted only in the eventsDropped reasons, so the sum here can be lower than the sum there. That covers a malformed dispatch whose type several events share, such as CHANNEL_CREATE, which delivers both guildChannelCreate and directMessageCreate

Readonly<Partial<Record<EventName, number>>>Readonly<
  Partial<Record<EventName, number>>
>
handlerFailures#

Reported event handler and command failures, including a returned or resolved Err result

number
hookFailures#

Failed onError hooks, which threw or rejected while reporting a failure

number
protocolFailures#

Gateway messages rejected as invalid protocol data, including skipped malformed dispatches

number
rateLimitWaits#

REST rate-limit waits that took place

A limit whose wait would pass the request deadline fails the request without waiting, logs ratelimit.deadline and is not counted here

number
reconnects#

Gateway reconnection attempts after an established connection was lost

number
reportsDropped#

Failure reports that could not be queued for a busy hook and were logged instead

number
restBusy#

REST requests that failed with reason busy before sending, because the REST queue or the upload byte budget was full

The first such failure in a minute also logs rest.busy at Warn

number
restRetries#

Automatic REST request retries

number
resumes#

Successful session resumes

number
sinkFailures#

Log output failures: Sink and observe calls that threw or rejected, console or Effect logger output that failed, and failure reports that could not be formatted

The first one is described on standard error

number
unknownDispatches#

Dispatch types the SDK does not handle

number
unknownOpcodes#

Gateway opcodes the SDK does not handle

number
unmatchedCommands#

Messages with the command prefix that matched no command

number

ClientDiagnostics#

Inspect this client's current connection state, occupied request slots and cache usage

These local values do not describe other processes or guarantee that a later request can start or the gateway will stay ready. Diagnostics include no token, remote route, resource ID or cached payload

interface ClientDiagnostics
caches#

Accounting for each local cache category

Closure releases retained snapshots but leaves configured capacity values available for inspection

Readonly<Record<CacheKind, CacheDiagnostic>>Readonly<
  Record<CacheKind, CacheDiagnostic>
>
counters#

Running totals of failures, drops, retries, waits and reconnects since creation, including work the logs summarized or suppressed

ClientCounters
events#

Current event sources, collectors and running callbacks owned by this client, not process memory or a shared quota

Counts exclude other clients and application tasks outside SDK event handlers

activeHandlers

Subscription callbacks currently executing, excluding idle subscriptions and collector filters

number
messageCollectors

Registered message collectors, including collectors waiting for matching messages

number
reactionCollectors

Registered reaction collectors, including collectors waiting for matching reactions

number
subscriptions

Open event sources, including subscriptions, event streams and single-event waits

number
gatewayLatencyMs#

Slowest current shard heartbeat round-trip time in milliseconds, or null under ClientState.gatewayLatencyMs availability rules

number | null
gatewayRequests#

Local request slots shared by fresh counts and member streams, not provider worker occupancy or a cross-process quota

activeCapacity

Maximum logical requests allowed concurrently by this client

number
activeRequests

Logical count requests and member streams currently holding shared local slots

number
rest#

HTTP requests running or waiting for a slot in this client

Active values combine the rest.concurrency REST or upload slots, four per local shard by default, with the separate rest.mediaConcurrency media-download slots, four by default. Queued JSON bytes exclude attachment transfers and do not measure heap or process memory

activeCapacity

Combined active-request capacity of those two pools

number
activeRequests

Requests currently using either the REST/upload pool or the media-download pool

number
queuedCapacity

Maximum queued requests shared by both pools

number
queuedJsonByteCapacity

Maximum accounted JSON-body bytes allowed in the shared queue

number
queuedJsonBytes

Accounted JSON-body bytes of queued requests, excluding attachment transfer bytes

number
queuedRequests

Requests waiting for a local request slot

number
shards#

Current locally owned shard state only, in configured local order

Empty for an automatically sized client until its first connect has chosen the plan

readonly ShardState[]
state#

Current aggregate client lifecycle state, not an event history or a readiness promise

ConnectionState
uploads#

Attachment transfer reservations across queued and active uploads, not caller buffers or remote temporary storage

byteCapacity

Configured maximum transfer-byte reservation for this client

number
reservedBytes

Attachment transfer bytes currently reserved by queued and active work

number

ClientLogging#

Change what this client logs while it runs

Creation settings other than level, categories and debug, such as sink and format, stay fixed for the client's lifetime

interface ClientLogging

configure#

Replace the client's log level and per-category levels, and optionally its Debug categories, effective for the next record

The settings are validated like level, categories and debug in the logging option of createClient. Omitted level and categories return to their defaults, level info without category levels, as at creation. An omitted debug keeps the current Debug categories, which start as the debug creation setting plus FLUXERLY_DEBUG. A debug value replaces them, including those from FLUXERLY_DEBUG. Pass true for every category, a list for only those categories, or false or an empty list for none. Debug categories lower their threshold to Debug, never raise it. It works before, during and after a connection, and changes nothing else about the client

configure(settings: LogLevelSettings): voidconfigure(
  settings: LogLevelSettings
): void

Parameters

Returns synchronously. Invalid settings, including keys other than level, categories and debug, throw ConfigurationError and leave the previous settings in place. A throwing settings getter throws SdkDefect with code application.defect

export function traceRequests(client) {
    client.logging.configure({ categories: { rest: "debug" } })
}
export function stopDebugOutput(client) {
    client.logging.configure({ debug: false })
}
import type { Client } from "@neontechspace/fluxerly"
export function traceRequests(client: Client) {
    client.logging.configure({ categories: { rest: "debug" } })
}
export function stopDebugOutput(client: Client) {
    client.logging.configure({ debug: false })
}

ErrorInfo#

Readable facts about an error attached to a log record or failure report

Application errors keep their name, string code, message, stack and cause chain with credentials masked. SDK errors add their fixed code and hint

interface ErrorInfo
cause optional#

The next error in the cause chain, limited to a few levels

ErrorInfo
code optional#

Fixed SDK error code, or a string code property of an application error with credentials masked

string
details optional#

Safe structured facts from an SDK error

Readonly<Record<string, unknown>>
hint optional#

Suggested next step from an SDK error

string
message#

Error message, or a text form of a thrown non-Error value

string
name#

Error name, such as TypeError or GuildOperationError, or Non-Error value (string) for a thrown value that is not an Error

string
origin#

Where the failure came from

The value application marks values thrown by application callbacks, provider marks Fluxer rejections and sdk marks SDK failures

"sdk" | "application" | "provider"
stack optional#

Stack trace, when the value had one

string

FailureMessageReference#

IDs of the message involved in a failure, without its content

interface FailureMessageReference
channelId#

Channel ID

string
guildId optional#

Guild ID when the message belongs to a community

string
id#

Message ID

string

FailureReport#

A failure outside any returned result, delivered to an onError hook or logged at Error with its full error

Reports delivered to a hook log at Debug without repeating the error. A handler failure caused by an HTTP 401 or 403 rejection replaces that rejection's Warn only when reported within one second, otherwise both records appear. The error is the real value that the application callback threw or rejected with, or the SDK error that stopped the work. The message reference contains IDs only. The original error can contain message content or other application data

interface FailureReport
command optional#

Prefix command name, when a command callback failed

string
error#

The original thrown, rejected or failed value

unknown
event optional#

Event whose delivery failed, when the failure belongs to an event subscription

keyof EventMap<Message>
kind#

What failed

FailureKind
message optional#

IDs of the message being handled, when there was one

FailureMessageReference
subscriptionId optional#

Identifier of the subscription that owns the failed work, matching Subscription.id and log records

string

describe#

Readable multi-line summary with the error's name, application code, message, stack and cause chain

Credential patterns and the client's configured credentials are masked, without changing the original error

describe(): string
Returns
string

HandlerObservation#

One finished event handler or prefix command router invocation, including event and command middleware

A router emits one observation for every handled message, even when it matches no command

interface HandlerObservation
command optional#

Canonical prefix command name when the router matched one, including denied or middleware-stopped commands

Absent when no command matched

string
durationMs#

Milliseconds from the start of the invocation until it finished

number
errorCode optional#

Stable code of the failure's error, when it has one

string
errorName optional#

Name of the failure's error, such as TypeError, for a failed invocation

string
event#

Event the handler received, such as messageCreate

keyof EventMap<Message>
outcome#

How the invocation ended

The value success means it finished without a reported failure, including a command denial or no command match. The value failure means a handler, command or middleware failure was reported to onError or the log, even when middleware recovered from it. The value cancelled means interruption stopped the invocation, such as shutdown or closing the subscription, and takes precedence over an earlier reported failure

"success" | "failure" | "cancelled"
shardId#

Local shard that received the event

number
subscriptionId#

Identifier of the subscription that ran the handler, such as messageCreate#3

string
type#

Discriminator for a finished handler invocation

"handler"

LogRecord#

One structured SDK log record, delivered frozen to sinks and printed by the built-in console output

Records never contain tokens, Authorization headers, client secrets, invite codes or the user information of a URL, such as user:password in https://user:password@host/path. Message payload bodies appear only in explicit unsafe payload mode

interface LogRecord
attempt optional#

One-based attempt number for retried work

number
category#

SDK area that produced the record

LogCategory
closeCode optional#

WebSocket close code

number
code#

Stable dotted identifier, such as lifecycle.ready, ratelimit.wait or events.dropped

Match on this rather than message

string
command optional#

Prefix command name that the record concerns

string
delayMs optional#

Milliseconds until the next attempt or the end of a wait

number
durationMs optional#

Elapsed milliseconds for the described work

number
error optional#

The error that the record describes

ErrorInfo
event optional#

Event name that the record concerns, such as messageCreate

string
fields optional#

Other safe facts, such as counts, opcodes and dispatch types

Readonly<Record<string, string | number | boolean | null>>Readonly<
  Record<
    string,
    string | number | boolean | null
  >
>
level#

Record severity

LogLevel
message#

Readable sentence describing what happened, which can change between releases

string
route optional#

REST route template with IDs replaced by placeholders, such as /channels/:id/messages

string
shardId optional#

Local shard that the record concerns

number
status optional#

HTTP status

number
subscriptionId optional#

Identifier of the event subscription or cache observer that the record concerns

string
time#

ISO 8601 wall-clock time when the SDK created the record

string

LoggingOptions#

Configure what the SDK logs and where the output goes

Both entry points accept the same settings. With no settings, the SDK prints Info and higher records, including startup, readiness, connection loss, rate-limit waits of at least one second, shutdown and full application errors. The FLUXERLY_DEBUG environment variable, read when the client is created, enables Debug records: 1, true or * for every category, or a comma-separated list such as gateway,rest. A debug value passed to client.logging.configure replaces those categories while the client runs. HTTP 401 and 403 rejections log a rest.rejected Warn even when handled. An unhandled handler failure with that same rejection, directly or in its cause chain, replaces its Warn if it happens within one second. A later handler failure also logs its own record, because the Warn has already been emitted. Logging never changes operation results, and records never contain credentials

interface LoggingOptions
categories optional#

Per-category minimum severity that replaces level for that category, such as { rest: "debug", cache: "warn" }

Readonly<Partial<Record<LogCategory, LogThreshold>>>Readonly<
  Partial<
    Record<LogCategory, LogThreshold>
  >
>
debug optional#

Enable Debug records for every category with true, or for the listed categories

At creation it adds to FLUXERLY_DEBUG. In client.logging.configure it replaces the current Debug categories, including those from FLUXERLY_DEBUG, and false or an empty list turns them all off. It lowers, never raises, the configured threshold

boolean | readonly LogCategory[]
dedupe optional#

Collapse repeated identical Warn, Error and Fatal records within a window

Records about different shards or subscriptions are not identical, so each one's first occurrence is shown. The next identical record after the window reports how many were suppressed in fields.repeated and as "(repeated N× since last shown)" in its message, and shutdown reports any remainder the same way. When more than 512 distinct records are tracked, the oldest one's window ends early and its count is reported then. Default { windowMs: 60000 }. A false value or a windowMs of 0 disables collapsing

false | { readonly windowMs?: number }
format optional#

Built-in console output format

The value pretty prints readable single lines with indented stacks, and json prints one LogRecord per line. Info and lower records go to standard output and Warn and higher to standard error, and each stream decides its own default. The default is pretty when that stream is a terminal and json otherwise. Without this setting, the FLUXERLY_LOG_FORMAT environment variable, pretty or json, read when the client is created, chooses the format for both streams, and FLUXERLY_LOG_COLOR forces color on with 1, true, yes or on, and off with 0, false, no or off, for pretty output. Another nonempty value of either variable is ignored with one sdk.unknownEnvironmentValue Warn at startup. NO_COLOR still disables color. A supervisor makes its default-API children log JSON and prints their records in the format of its own streams. Native clients without sink or format send records to the Effect logger instead, and the environment variables do not change that

"json" | "pretty"
level optional#

Minimum severity to emit, default info

The value silent emits nothing, including application error reports without a hook and unsafe payload records

LogThreshold
sink optional#

Receive records instead of the built-in console output

Pass one function or an array of them. Each sink is called synchronously in order for every emitted record

LogSink | readonly LogSink[]
unsafe optional#

Print received and sent payload bodies at Trace level for debugging, for all categories or the listed ones

Payload records bypass the level setting, except that a category set to silent prints no payloads. Payloads can contain private message content, so the SDK prints a Warn banner once, at startup or before the first payload record, whichever comes first, even when the level would hide Warn records. Received REST bodies show at most their first 65,536 bytes. Tokens, Authorization headers, client secrets, passwords, cookies, invite codes and the user information of a URL stay masked even in this mode, including credential-key values in a truncated JSON response

categories optional

Print payloads only for these categories, such as gateway or rest

Omit for every category

readonly LogCategory[]
payloads

Must be true to acknowledge that payload bodies can contain private content

true

RateLimitObservation#

A REST request that waits before retrying because Fluxer rate-limited it with HTTP 429

The optional members repeat the rate-limit headers and body members of that response, so the limiter that answered can be identified. Each is absent when the response did not send it or sent it in another form. The scope and bucket headers must be at most 64 letters, digits, underscores, periods, colons or hyphens, a count header at most 15 digits, and a seconds header at most 32 characters of digits with one optional decimal point. The body members must be a finite non-negative number for retry_after and a boolean for global. Credentials in scope and bucket are masked as in log records

interface RateLimitObservation
bodyGlobal optional#

The body's global member, unlike global, which combines it with the headers

boolean
bucket optional#

The X-RateLimit-Bucket header, an opaque identifier of the route's rate-limit bucket

string
global#

Whether the limit pauses every API route of this client rather than one rate-limit group

It is true when the body's global member is true, the X-RateLimit-Global header is true or the X-RateLimit-Scope header is global

boolean
limit optional#

The X-RateLimit-Limit header, the number of requests the route allowance admits at once

number
method#

HTTP method of the waiting request

string
remaining optional#

The X-RateLimit-Remaining header, the number of requests the route allowance still admits

number
resetAfterSeconds optional#

The X-RateLimit-Reset-After header, seconds until the whole route allowance is available again

number
retryAfterHeaderSeconds optional#

The Retry-After header in seconds

An HTTP date in this header is not reported

number
retryAfterSeconds optional#

The body's retry_after member, seconds until Fluxer admits another request

number
route#

Route template of the waiting request, with IDs replaced by placeholders

string
scope optional#

The X-RateLimit-Scope header, such as user, shared or global

string
type#

Discriminator for a rate-limit wait

"rateLimit"
waitMs#

Milliseconds the request waits before its retry

number

ReconnectObservation#

A shard begins a reconnection attempt after its established connection was lost

interface ReconnectObservation
shardId#

Local shard that reconnects

number
type#

Discriminator for a reconnection attempt

"reconnect"

RestObservation#

One finished REST request attempt

A retried request reports each attempt separately

interface RestObservation
attempt#

One-based attempt number

Values above 1 are automatic retries of the same request

number
durationMs#

Milliseconds from sending the request until its response headers arrived or it failed

number
method#

HTTP method, such as GET or POST

string
route#

Route template with IDs replaced by placeholders, such as /channels/:id/messages

string
status#

HTTP status of the response, or null when no response arrived, such as after a network failure or timeout

number | null
type#

Discriminator for a finished REST request attempt

"rest"

ResumeObservation#

A shard resumed its session, so Fluxer replays the events it missed

interface ResumeObservation
outageMs optional#

Milliseconds the shard was offline, when it was connected before in this process

number
shardId#

Local shard that resumed

number
type#

Discriminator for a resumed session

"resume"

Type Aliases#

FailureKind#

What failed

The kind handler is an event or command callback, and overflow is a subscription stopped by a full queue. The kind collector is a message or reaction collector callback, and filter is a collector filter. The kind progress is a message cleanup onProgress callback, cache is a cache maxAgeMs duration callback or a cache.onChange listener, observer is a state observer and task is one run of a client.schedule task. A failing onError hook is never reported to a hook again: It is logged with the original failure and counted in diagnostics().counters.hookFailures

type FailureKind =
    | "handler" | "overflow" | "collector" | "filter" | "progress"
    | "cache" | "observer" | "task"type FailureKind =
    | "handler" | "overflow"
    | "collector" | "filter"
    | "progress" | "cache"
    | "observer" | "task"

LogCategory#

The SDK area that produced a log record

Use it with categories and debug to adjust output for one area. The lifecycle category covers startup, readiness, connection loss and shutdown, gateway covers protocol traffic, rest covers HTTP requests and retries, ratelimit covers rate-limit waits, and cache covers cache policy and expiry. The events category covers subscriptions, handlers and dropped events, commands covers prefix commands, collectors covers message and reaction collectors, supervisor covers child processes, and sdk covers the logger itself

type LogCategory =
    | "lifecycle" | "gateway" | "rest" | "ratelimit" | "cache"
    | "events" | "commands" | "collectors" | "supervisor" | "sdk"type LogCategory =
    | "lifecycle" | "gateway"
    | "rest" | "ratelimit"
    | "cache" | "events"
    | "commands" | "collectors"
    | "supervisor" | "sdk"

LogLevel#

Severity of an SDK log record, from most to least verbose

type LogLevel =
    "trace" | "debug" | "info" | "warn" | "error" | "fatal"type LogLevel =
    | "trace" | "debug" | "info"
    | "warn" | "error" | "fatal"

LogSink#

A synchronous callback that receives each emitted SDK record

Return values are ignored and promises are not awaited. A thrown error or rejected promise is counted in diagnostics().counters.sinkFailures and reported once on standard error, without stopping SDK work or other sinks

type LogSink = (record: LogRecord) => voidtype LogSink =
    (record: LogRecord) => void

LogThreshold#

A minimum severity for SDK log output, or silent to emit nothing

type LogThreshold = LogLevel | "silent"type LogThreshold =
    LogLevel | "silent"

Observer#

Receive structured measurements of this client's work, such as REST request durations, rate-limit waits, reconnection attempts, resumed sessions and handler durations, to export as metrics or traces to any monitoring system

Each observation is a frozen object with plain values. Route templates replace IDs with placeholders, and observations never contain tokens, payloads or message content. The SDK calls the observer synchronously when the measured work finishes, so keep it short and move slow work, such as network export, elsewhere. Return values are ignored and promises are not awaited. A thrown error or rejected promise is counted in diagnostics().counters.sinkFailures and reported once on standard error, without changing SDK work

type Observer = (observation: Observation) => voidtype Observer =
    (observation: Observation)
      => void