Skip to content
当前有符合你浏览器所设置语言的版本,是否前往zh-CN版本的网站?
There is a version suitable for your browser's language settings. Would you like to go to the zh-CN language of the site?
HomeDocument

Logger

H1

Logs play an important role in troubleshooting issues in an application. While we can use console to print logs, our logging requirements may be more diverse. For example, we may need to log not only to the console but also to a file or a dedicated logging platform. Additionally, we may need to differentiate logs printed between different requests to facilitate troubleshooting, especially in cases with a high number of concurrent accesses.

Wherever you can use context, you can directly use a logger. The usage of the logger is almost the same as the console.

// Print a regular log
context.logger.log("Hello, Milkio!");
// Additional parameters after the second parameter can be used to carry data, and the log will record these data as well
context.logger.log("Hello, Milkio!", { foo: "bar " });
// Like console, you can also use debug, warn, or error to log different levels of logs
context.logger.error("There's an error here UwU");

Alternatively, you can use the useLogger method to create a logger, in which case you need to provide an executeId parameter. This parameter comes from the context object of your API and is unique. For each request, the executeId is different. Milkio’s loggers differentiate between different requests using them.

const logger = useLogger(context.executeId);

In certain special cases, you may not be able to obtain the executeId. In such cases, you can pass global, and the logger will write to the log for all concurrent requests simultaneously.

const logger = useLogger("global");

Log Tags

In addition to printing logs, you can also tag a request with log tags. You can add custom tags to a specific request using the loggerPushTags method.

import { loggerPushTags } from "Milkio";
loggerPushTags(executeId, { userInfo: ..., permissions: ... });

In previous logs, we often directly output user information, permissions, and other data of the request to the logs, which can obscure critical information. Using tags appropriately helps make your logs clearer and easier to read, keeping only the key information.

Built-in Log Tags

Milkio automatically adds some log tags to each of your requests. The following tags are used:

KeyValues
fromSource: “http-server” | “execute”
executeIdUnique ID for executing this request
methodRequest method
ipIP address of the requester
urlRequest URL
paramsRequest parameters (Object)
bodyResponse body (Raw String)
timeinTime the request was received (Number)
timeoutTime the request was responded to (Number)
requestHeadersRequest headers (Object)
responseHeadersResponse headers (Object)

Note that you cannot assume that these log tags will always exist. For example, in certain extreme cases where the request is terminated directly, contents such as body, params, and responseHeaders may not be added. Additionally, when calling through execute code instead of sending an HTTP request, data like ip will not exist, and you may receive other values.

Custom Loggers

You can freely modify /src/logger.ts to customize the behavior of the logger according to your needs. By default, your logger will display logs directly in the console based on the code written.

/src/logger.ts
import { type LoggerOptions, type ExecuteId } from "Milkio";
export const loggerOptions = {
onSubmit: (tags, logs) => {
console.log(`🥛 Milkio Response! From:`, tags.url);
console.log(JSON.stringify(tags));
},
onInsert: (options) => {
console[options.loggerLevel](options.description, ...options.params);
return true;
},
} satisfies LoggerOptions;

onSubmit

The onSubmit method is called when a request is about to end. It can be an asynchronous method or return a Promise. You can use this stage to persistently store logs associated with the request.

In this method, you can not only access all the historical logs recorded in the request but also access all the tags added to the request.

onInsert

The onInsert method is called each time a log is recorded and must be a synchronous method. You need to return true or false. When you return false, the log will be discarded. For example, you can return false to prevent debug level logs from being recorded in the production environment.

Please do not persistently store logs (such as writing logs to files or sending them to various logging systems) in this method. This will result in frequent IO operations for each request, which will degrade performance.