本文介绍了限制来自 TypeORM 的日志记录而不是禁用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 TypeORMcreateConnection() 时设置了 logging: true,这在大多数情况下都可以正常工作.

但是有一种情况,我的特定query/mutation 中的一个数据字段可能包含一个长字符串(50000 - 300000 个字符取决于输入,可能更多).当typeORM尝试在VScode终端中记录内容时,它可以粉碎VScode,我想知道TypeORM是否可以隐藏这么长的字符串而不是完全禁用所有查询日志记录.

我的理想方法是类似于 longstring===(基于字符串和文本省略号的修改)===>长....或者,如有必要,只需为特定查询应用自定义记录器.

因此它仍然可以记录以指示代码位正在以最少的信息运行.

从文档来看,我似乎只能添加附加信息而不是修改.

解决方案

在 TypeOrm 日志记录页面上更改默认记录器.

您需要实现自己的记录器.这很简单,因为您可以对 TypeOrm 提供的标准记录器之一进行子类化,检查日志查询字符串是否太长,并调用继承的日志方法.

例如,子类化高级控制台"logger,这是 TypeOrm 使用的默认记录器.

import { Logger, QueryRunner, AdvancedConsoleLogger, LoggerOptions } from "typeorm";导出类 MyCustomLogger 扩展了 AdvancedConsoleLogger 实现了 Logger {构造函数(选项?:LoggerOptions){超级(选项);}logQuery(query: string, parameters?: any[], queryRunner?: QueryRunner) {让 logText = 查询;如果 (logText.length > 100)//如果太长,截断日志文本:logText = logText.substring(0, 10) + "...";super.logQuery(logText, 参数, queryRunner);}}

您可以覆盖更多的 4 种方法,但您可以从实现中省略这些方法,它将使用继承的方法:

logQueryError(error: string, query: string, parameters?: any[], queryRunner?: QueryRunner)logQuerySlow(time: number, query: string, parameters?: any[], queryRunner?: QueryRunner)logSchemaBuild(消息:字符串,queryRunner?:QueryRunner)logMigration(消息:字符串,queryRunner?:QueryRunner)日志(级别:日志"|信息"|警告",消息:任何,queryRunner?:QueryRunner)

现在您已经创建了自定义记录器,如何使用在 使用自定义记录器.

您需要稍微更改页面上的示例以添加所需的日志记录选项;日志选项在日志选项下进行了解释,例如:(true)(All")([query", error"])

从typeorm"导入{createConnection};从./logger/MyCustomLogger"导入{MyCustomLogger};创建连接({名称:mysql",类型:mysql",主机:本地主机",端口:3306,用户名:测试",密码:测试",数据库:测试",logger: new MyCustomLogger(true)//记录选项true";= 启用日志记录});

或者当使用 ormconfig.json 配置文件时:

import {createConnection, getConnectionOptions} from "typeorm";从./logger/MyCustomLogger"导入{MyCustomLogger};//getConnectionOptions 将从您的 ormconfig 文件中读取选项//并在 connectionOptions 对象中返回它//然后你可以简单地向它附加额外的属性getConnectionOptions().then(connectionOptions => {返回 createConnection(Object.assign(connectionOptions, {logger: new MyCustomLogger(connectionOptions.logging)//传入 ormconfig.json 文件中指定的日志选项}))});

如果你使用 async/await 而不是 promises,你可以更清楚地重写后面的代码:

//getConnectionOptions 从你的 ormconfig 文件中读取选项const 选项 = 等待 getConnectionOptions();//将 MyCustomLogger 附加到连接选项await createConnection({ ...options, logger: new MyCustomLogger(options.logging) });

I had set logging: true when createConnection() from TypeORM, which works fine for most of times.

But there is a situation where one of my data field from a specific query/mutation may contains a long string (50000 - 300000 char depends on the input, it could be more). When typeORM try to log the content in VScode terminal, it can crush VScode, I wonder if there is anything that TypeORM can hide such a long string instead of completely disable all the query loggings.

My ideal approach would be something like longstring=== (modification based on the string and text ellipsis) ===> long.... Or just apply a custom logger for specific query if necessary.

So it can still log to indicate the bit of code is running with minimal info.

From the doc, it seems like I can only add additional information instead of modifying.https://github.com/typeorm/typeorm/blob/master/docs/logging.md

=============== Update ==============

Based on the accepted solution, it seems like I did not understand the doc properly. We can custom the logger based on our needs. Since I want to cut off the parameter. So I can do the following.

import { AdvancedConsoleLogger, Logger, LoggerOptions, QueryRunner } from "typeorm";

export class CustomLogger extends AdvancedConsoleLogger implements Logger {
    constructor(options?: LoggerOptions) {
        super(options);
    }
    //override logquery
    logQuery(query: string, paramters?: any[], queryRunner?: QueryRunner) {
        const limit = 100;
        const paramTextEllipsis = paramters?.map((param) => {
            //only cut off string and length longer than 100
            if(typeof param === "string" && param.length > limit){
                return param.substring(0, limit) + "...";
            }
            return param;
        });
        super.logQuery(query, paramTextEllipsis, queryRunner);
    }
};

The result from terminal. Note that the json string originally has more than 100k which can easily crush editor.

解决方案

It is explained under changing default logger on the TypeOrm logging page.

You need to implement your own logger. This is simple as you can subclass one of the standard loggers provided by TypeOrm, check if log query string if it is too long, and call the inherited log method.

For example, to subclass the "advanced-console" logger, which is the default logger TypeOrm uses.

import { Logger, QueryRunner, AdvancedConsoleLogger, LoggerOptions } from "typeorm";

export class MyCustomLogger extends AdvancedConsoleLogger implements Logger {

    constructor(options?: LoggerOptions) {
        super(options);
    }    

    logQuery(query: string, parameters?: any[], queryRunner?: QueryRunner) {
        let logText = query;
        if (logText.length > 100)
            // Truncate the log text if it's too long:
            logText = logText.substring(0, 10) + "...";
        super.logQuery(logText, parameters, queryRunner);
    }
}

There are more 4 methods you can override, but you can omit these from your implementation and it will use the inherited methods:

logQueryError(error: string, query: string, parameters?: any[], queryRunner?: QueryRunner)
logQuerySlow(time: number, query: string, parameters?: any[], queryRunner?: QueryRunner)
logSchemaBuild(message: string, queryRunner?: QueryRunner) 
logMigration(message: string, queryRunner?: QueryRunner)
log(level: "log" | "info" | "warn", message: any, queryRunner?: QueryRunner)

Now you have created your custom logger, how to use is is explained under using custom logger.

You need to change the examples on the page slightly to add the logging option(s) you want; logging options are explained under logging options, e.g: (true) or ("All") or (["query", "error"])

import {createConnection} from "typeorm";
import {MyCustomLogger} from "./logger/MyCustomLogger";

createConnection({
    name: "mysql",
    type: "mysql",
    host: "localhost",
    port: 3306,
    username: "test",
    password: "test",
    database: "test",
    logger: new MyCustomLogger(true) // Logging option "true" = enable logging
});

Or when using the ormconfig.json configuration file:

import {createConnection, getConnectionOptions} from "typeorm";
import {MyCustomLogger} from "./logger/MyCustomLogger";

// getConnectionOptions will read options from your ormconfig file
// and return it in connectionOptions object
// then you can simply append additional properties to it
getConnectionOptions().then(connectionOptions => {
    return createConnection(Object.assign(connectionOptions, {
        logger: new MyCustomLogger(connectionOptions.logging) // pass in logging options specified in the ormconfig.json file
    }))
});

If you are using async/await instead of promises, you can rewrite the latter code more clearly:

// getConnectionOptions reads options from your ormconfig file
const options = await getConnectionOptions();
// append MyCustomLogger to the connection options
await createConnection({ ...options, logger: new MyCustomLogger(options.logging) });

这篇关于限制来自 TypeORM 的日志记录而不是禁用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 07:51