Logging
This API is available since Fedify 0.7.0.
TIP
We highly recommend enabling logging in your federated server app to debug your app easily.
Fedify uses the LogTape package to log messages. You can enable logging in your federated server app by installing the @logtape/logtape package and configuring it in the entry point of your app.
Setting up LogTape
To enable logging in your federated server app, you need to install the @logtape/logtape package (available on both JSR and npm):
deno add jsr:@logtape/logtapenpm add @logtape/logtapepnpm add @logtape/logtapeyarn add @logtape/logtapebun add @logtape/logtapeThen, you can configure() the logger in the entry point of your app:
import { AsyncLocalStorage } from "node:async_hooks";
import { configure, getConsoleSink } from "@logtape/logtape";
await configure({
sinks: { console: getConsoleSink() },
loggers: [
{ category: "your-app", sinks: ["console"], lowestLevel: "debug" },
{ category: "fedify", sinks: ["console"], lowestLevel: "error" },
],
contextLocalStorage: new AsyncLocalStorage(),
});The configure() function takes an object with three properties:
sinks(mandatory)An object that maps sink names to sink instances. In this example, we use the
getConsoleSink()function to get a console sink instance.filters(mandatory)An object that maps logger categories to filter functions. In this example, we use an empty object to disable filtering.
loggers(mandatory)An array of logger configurations. Each configuration is an object with four properties:
loggers.category(mandatory)The
categoryproperty is an array of string or a string that specifies the logger category. If a string is given, it is treated as an array with a single element.loggers.sinks(optional)The
sinksproperty is an array of string that specifies the sink names that the logger should use.loggers.filters(optional)The
filtersproperty is an array of string that specifies the filter names that the logger should use.loggers.lowestLevel(optional)The
lowestLevelproperty is a string that specifies the log level. The log level can be one of the following:"debug","info","warning","error", or"fatal".NOTE
The
lowestLevelproperty was introduced in LogTape 0.8.0. Prior to LogTape 0.8.0, please use thelevelproperty instead oflowestLevel.contextLocalStorage(recommended)This property is available since LogTape 0.7.0.
An instance of
AsyncLocalStoragethat is used to store implicit contexts of the log messages. This is useful when you want to trace the log messages in a specific context.
Categories
TIP
A logger category is an array of strings that specifies the logger category. The logger category is used to filter log messages, or to configure the specific sink for the logger. Since it's hierarchical, you can filter out log messages by specifying a prefix of the logger category while seeing log messages of a specific subcategory.
Note that the logger category is case-sensitive. A bare string is treated as an array with a single element.
Fedify uses the following logger categories:
"fedify"
The "fedify" category is used for everything related to the Fedify library.
["fedify", "compat", "transformers"]
This category is available since Fedify 1.4.0.
The ["fedify", "compat", "transformers"] category is used for logging ActivityTransformer-related messages.
["fedify", "federation"]
The ["fedify", "federation"] category is used for logging federation-related messages.
["fedify", "federation", "actor"]
This category is available since Fedify 0.9.0.
The ["fedify", "federation", "actor"] category is used for logging messages related to actor dispatcher.
["fedify", "federation", "collection"]
This category is available since Fedify 0.8.0.
The ["fedify", "federation", "collection"] category is used for logging messages related to collections (e.g., outbox, followers, following).
["fedify", "federation", "fanout"]
This category is available since Fedify 1.5.0.
The ["fedify", "federation", "fanout"] category is used for logging messages related to fanning out outgoing activities.
["fedify", "federation", "http"]
This category is available since Fedify 0.9.0.
The ["fedify", "federation", "http"] category is used for logging messages related to HTTP requests and responses. When you are curious about the HTTP requests and responses, you can check the log messages in this category with the "info" level.
["fedify", "federation", "inbox"]
The ["fedify", "federation", "inbox"] category is used for logging messages related to incoming activities. When you cannot receive an activity, you can check the log messages in this category with the "debug" level.
["fedify", "federation", "object"]
The ["fedify", "federation", "object"] category is used for logging messages related to object dispatchers.
["fedify", "federation", "outbox"]
The ["fedify", "federation", "outbox"] category is used for logging messages related to outgoing activities. When you cannot send an activity, you can check the log messages in this category with the "debug" level.
["fedify", "federation", "queue"]
This category is available since Fedify 0.12.0.
The ["fedify", "federation", "queue"] category is used for logging messages related to the task queue. When you are curious about the task queue, you can check the log messages in this category with the "debug" level.
["fedify", "nodeinfo", "client"]
This category is available since Fedify 1.2.0.
The ["fedify", "nodeinfo", "client"] category is used for logging messages related to the NodeInfo client. When you are curious about the NodeInfo client, you can check the log messages in this category with the "error" level.
["fedify", "runtime", "docloader"]
This category is available since Fedify 0.8.0.
The ["fedify", "runtime", "docloader"] category is used for logging messages related to the document loader. When you are curious about what specific requests are made by the document loader, you can check the log messages in this category with the "debug" level.
["fedify", "sig", "http"]
This category is available since Fedify 0.9.0.
The ["fedify", "sig", "ld"] category is used for logging messages related to HTTP Signatures. When you are curious about the signature verification process, you can check the log messages in this category with the "debug" level.
["fedify", "sig", "ld"]
This category is available since Fedify 1.0.0.
The ["fedify", "sig", "ld"] category is used for logging messages related to Linked Data Signatures. When you are curious about the signature verification process, you can check the log messages in this category with the "debug" level.
["fedify", "sig", "proof"]
This category is available since Fedify 0.10.0.
The ["fedify", "sig", "proof"] category is used for logging messages related to Object Integrity Proofs. When you are curious about the proof verification process, you can check the log messages in this category with the "debug" level.
["fedify", "sig", "key"]
This category is available since Fedify 0.10.0.
The ["fedify", "sig", "key"] category is used for logging messages related to key generation and key retrieval. When you are curious about these processes, you can check the log messages in this category with the "debug" level.
["fedify", "vocab", "lookup"]
This category is available since Fedify 0.10.0.
The ["fedify", "vocab", "lookup"] category is used for logging messages related to looking up ActivityPub objects. When you are curious about the lookup process, you can check the log messages in this category with the "debug" level.
["fedify", "webfinger", "server"]
This category is available since Fedify 0.13.0.
The ["fedify", "webfinger", "server"] category is used for logging messages related to the WebFinger server. When you are curious about the WebFinger server, you can check the log messages in this category with the "debug" level.
["fedify", "webfinger", "lookup"]
This category is available since Fedify 0.10.0.
The ["fedify", "webfinger", "lookup"] category is used for logging messages related to looking up WebFinger resources. When you are curious about the lookup process, you can check the log messages in this category with the "debug" level.
Sinks
A sink is a destination where log messages are sent. LogTape provides few built-in sinks:
However, you can create your own sink by implementing the Sink interface, e.g., to send log messages to a database or a cloud service.
For more information about sinks, see the Sinks section in the LogTape docs.
Deprecation warnings
When you are using deprecated APIs, you can see deprecation warnings in the log messages. The deprecation warnings are logged with the "warning" level in each category where the deprecated API is used. If you want to see all deprecation warnings, you can set the log level to "warning" for the "fedify" category.
Tracing
This feature is available since Fedify 1.2.0.
CAUTION
Traceable log messages rely on implicit contexts which was introduced in LogTape 0.7.0. If you don't configure contextLocalStorage in configure(), you cannot trace log messages.
The most of log messages made by Fedify can be traced by either below two properties:
requestIdIf the log message is made in the context of an HTTP request, the
requestIdproperty is included in it. TherequestIdis a unique identifier for the HTTP request, which is derived from one of the following headers:X-Request-IdX-Correlation-IdTraceparent- Otherwise, the
requestIdis a unique string derived from the current timestamp and the random number.
messageIdIf the log message is made in the context of a background task, the
messageIdproperty is included in it. ThemessageIdis a unique identifier for the background task, which is a UUID.
When you want to trace log messages, first of all you need to use a sink that writes log messages as structured data. For example, you can use a file sink with a JSON Lines formatter. Oh, and don't forget to set contextLocalStorage in configure()! To sum up, you can configure loggers like this:
import { AsyncLocalStorage } from "node:async_hooks";
import { getFileSink } from "@logtape/file";
import { type LogRecord, configure } from "@logtape/logtape";
await configure({
sinks: {
file: getFileSink("fedify-logs.jsonld", {
formatter(record: LogRecord): string {
return JSON.stringify(record) + "\n";
}
})
},
loggers: [
{ category: "fedify", sinks: ["file"], lowestLevel: "info" },
],
contextLocalStorage: new AsyncLocalStorage(),
});If your loggers are configured like this, you can filter log messages by requestId or messageId in the log file. For example, you can filter log messages by requestId using jq:
jq -r 'select(.properties.requestId == "your-request-id")' fedify-logs.jsonl