[eggjs/egg][Feature Request] 非请求上下文中如何优雅的使用logger、config等对象

2025-11-04 692 views
1
Background

由于egg的logger、config等对象都是绑定在app或者ctx上的, 在某些非请求上下文环境中的代码,如果想使用logger、config等对象,有没有什么比较优雅的方式。 例如:

某些utils类中需要打日志 在封装的request方法中,需要获得config中配置的一些url Proposal

目前的方式是通过在app启动时候,获得app中的对象,存到到某个类静态对象的方式。感觉怪怪的。例如:

import { Logger } from 'egg-logger';
class ContextHelper {
  // logger
  private static logger: Logger;
  // ... other context obj

  public static setLogger(logger: Logger) {
    this.logger = logger;
  }
  public static getLogger() {
    return this.logger;
  }
}
export default ContextHelper;
configDidLoad() {
    // Config, plugin files have loaded.
    ContextHelper.setLogger(this.app.logger);
  }

使用:

import ContextHelper from '../utils/contextHelper';
...
ContextHelper.getLogger().info('')
...
Additional context

egg官方有计划提供类似的插件嘛。可以实现类似于这种的使用方式,可以在任何地方获得对象。

import { Logger, Config } from 'egg-xxx';

回答

7

app.logger 不就是非请求上下文的么,如果是公共方法封装到 extend/application 上就好了,为啥会有这样的需求。

2

这样得层层传入app对象呀。。 有些工具类里层层传入的话太麻烦了。 目前是直接在启动时候存了app对象,总感觉不太好。

9

工具类,我一般都是入口参数为 options 包含 options.loggeroptions.xx 配置的方式。

如果是独立的工具类,那它不应该感知 egg,因此如上 options 方式。 如果是专门针对 egg 的工具类,那入参 options.app 没问题。

层层嵌套的问题要评估你的工具类的设计,如果确实是都要配置,那肯定要层层传递,不管是 options 还是 app

1

import { Logger, Config } from 'egg-xxx';

这种方式不会支持,如果你了解 egg 的 loader 过程的话,就会理解的,能拿到最终的 Config,就已经相当于实例化完一个 app 了,这中间包括远程配置加载,插件配置合并等等。

2

如果是第三方的模块的话,包一层 egg-plugin,直接可以在使用前传入 app.logger,如果工具类本身就是层层传递 logger 的,这样本身设计我觉得不太合理

8

这种方式不会支持,如果你了解 egg 的 loader 过程的话,就会理解的,能拿到最终的 Config,就已经相当于实例化完一个 app 了,这中间包括远程配置加载,插件配置合并等等。

嗯,了解了。 我理解无法在app实例化之前获得具体的config,是因为config具体值是在实例化过程中动态加载的。只有实例化完了才知道。那确实支持不了。

4

工具类,我一般都是入口参数为 options 包含 options.loggeroptions.xx 配置的方式。

如果是独立的工具类,那它不应该感知 egg,因此如上 options 方式。 如果是专门针对 egg 的工具类,那入参 options.app 没问题。

层层嵌套的问题要评估你的工具类的设计,如果确实是都要配置,那肯定要层层传递,不管是 options 还是 app

那每个工具类或函数都得加一个options参数了呀,就是不想加逻辑无关的参数嘛。 感觉还是app实例化完之后,直接吧app存起来简单方便。。想用时候就取就好了。

3

因为本来你工具类的设计就是如此啊,不想加逻辑无关的参数嘛 那就只有从全局唯一的第一个地方获取,工具类去依赖一个全局的变量,这样更不合理了。

所谓 工具类 就应该是一个独立的模块,它不应该依赖任何全局的东西,它只能通过 options 来给外部暴露配置项。

3

如果是业务工具类的话也可以放 extend 上,app.utils 来取,第三方工具类本来就是需要传输指定参数的,传一个 all-in-one 的对象不太合理。

7

因为本来你工具类的设计就是如此啊,不想加逻辑无关的参数嘛 那就只有从全局唯一的第一个地方获取,工具类去依赖一个全局的变量,这样更不合理了。

所谓 工具类 就应该是一个独立的模块,它不应该依赖任何全局的东西,它只能通过 options 来给外部暴露配置项。

确实我也觉得不合理。。 所以才来问问说有啥好的方式。 我试试options的方式看看。thx

8

所谓 工具类 就应该是一个独立的模块,它不应该依赖任何全局的东西,它只能通过 options 来给外部暴露配置项。

工具类,就应该老老实实的。