Winston: 可以在前端(即浏览器)上使用winston 进行日志记录吗?

创建于 2013-07-29  ·  60评论  ·  资料来源: winstonjs/winston

可以在前端使用winston进行日志记录吗? 我想使用 Winston 来获得更大的前端日志记录能力。 这可以做到吗?

feature request

最有用的评论

伙计,当我看到包然后发现没有浏览器支持时,我的希望真的很高。
这对我来说在浏览器中替换一些本土的东西真的很棒。

所有60条评论

我还没有尝试过,但这可能会有所帮助https://github.com/farpoint/meteor-winston-client

这与: https ://github.com/flatiron/winston/issues/180有关

该链接上有 404 @joshacheson

你在这个问题上有什么进展吗?

根据 #582 的反馈,似乎任何未来的 PR 都需要专注于分离核心逻辑和传输,而不是使用诸如brfs之类的垫片。 这将是一个巨大的结构性变化,几乎肯定需要核心开发人员在风格和方法方面的指导,因为他们最终将成为维持这一点的人。

好消息是代码大多是干净且结构良好的,但需要核心开发人员对风格和方法的一些指导。 @indexzero / @pose可以分享你的想法吗?

这个问题有什么进展吗?

伙计,当我看到包然后发现没有浏览器支持时,我的希望真的很高。
这对我来说在浏览器中替换一些本土的东西真的很棒。

+1

和我一样。 前后使用相同的日志库也有帮助。

我只是在浏览这个,即使它有一个 http 传输,似乎也没有任何标准的浏览器/其他客户端。

很遗憾我将不得不使用 bunyan

有这方面的消息吗?

如果你真的想使用它,你可以为它编写一个自定义传输,例如:

const Transport = require('winston-transport');

export default class BrowserConsole extends Transport {
  constructor(opts) {
    super(opts);

    this.name = 'BrowserConsole';
    this.levels = {
        error: 0,
        warn: 1,
        info: 2,
        debug: 4,
    };

    this.methods = {
        error: 'error',
        warn: 'warn',
        info: 'info',
        debug: 'log',
    };

    this.level = opts.level && this.levels.hasOwnProperty(opts.level)
                  ? opts.level : 'info';
  }

  log(method, message) {
    setImmediate(() => {
      this.emit('logged', method);
    });

    const val = this.levels[method];
    const mappedMethod = this.methods[method];

    if (val <= this.levels[this.level]) {
      // eslint-disable-next-line
      console[mappedMethod](message);
    }
  }
}

然后你可以这样使用它:

import BrowserConsole from './BrowserConsole';

const { createLogger, transports } = require('winston');

const log = createLogger({
  level: 'info',
});

if (process.env.NODE_ENV !== 'production') {
  log.add(new BrowserConsole({
    level: 'info',
  }));
}

使用此传输,您会收到无用的警告,因为它被视为遗留代码。 添加使用其他控制台方法( tabledirtrace ,...)的可能性也会很漂亮,但为了简单起见,它就像它一样。

谢谢@chrisvoo ,我已经尝试过这个解决方案但出现错误:

ReferenceError: Buffer is not defined
    replacer 
    json.js/module.exports< 
    _transform 
    _stream_transform.js/Transform.prototype._read
    _stream_transform.js/Transform.prototype._write
    doWrite
    writeOrBuffer
    _stream_writable.js/Writable.prototype.write
    log

@dmitry-salnikov 我不知道,顺便说一句,我不明白为什么这段代码使用流。 也许我的用例太简单了。 尝试分享你是如何使用它的。

@chrisvoo我已将BrowserConsole实现复制粘贴到一个单独的文件中,然后在另一个文件中粘贴了代码的第二部分,并在添加BrowserConsole传输代码(代码段的最后一行)之后我'只是尝试过:

log.info('hello world');

然后我得到错误,并尝试:

log.log('info, 'hello world');

两个调用都返回相同的错误。

我可以在浏览器中使用 Node 的环境是 Meteor.js v1.6 (Node 8.8.1)。 此外,我还没有修改您的代码片段的任何行。

顺便说一句:我不久前才开始使用winston,所以可能做错了什么。

@dmitry-salnikov 你收到什么样的错误? 像“信息不是功能”? 也许由于某种原因,它进口得很糟糕。

@chrisvoo请看一下:
screenshot 2017-11-08 20 35 31

BrowserConsole.js的内容(您可以在文件树中看到它)与您的代码段中的内容完全相同。

我同意你的看法,我觉得导入有问题,但不知道为什么:(你能分享你的想法吗?

你的温斯顿版本是什么? 我的是:

"winston": "^3.0.0-rc1",
"winston-transport": "^3.0.1"

其实一样

$ npm ls | grep winston
├─┬ [email protected]
│ └── [email protected]
└── [email protected]
$ cat package.json | grep winston
    "winston": "^3.0.0-rc1",
    "winston-transport": "^3.0.1"

为了解决这个问题,我做了另一个测试:

import winston from 'winston';
import BrowserConsole from '/imports/BrowserConsole.js';

const format = winston.format;
// next line throws exception, see below
const { combine, timestamp, label, printf, colorize, prettyPrint } = format;

const logger = winston.createLogger({
...

并得到下一个错误: Cannot find module './combine'

这是堆栈跟踪和相关代码(浏览器截图):
screenshot 2017-11-10 04 01 04

好像进口的东西真的很糟糕。 @chrisvoo你能看一下吗?

在 Winston 3.0.0 中,传输是流。 但是,在 browserify-stream 中, readableStream instanceof Stream不成立。 这使得 Winston 回退到将传输包装在 Legacy 包装器中并发出警告。 我做了一个 PR 以使用不同的方法进行流式检测:#1145

@Jasu是的,我也注意到了这一点,我早些时候在winston-transport上提交了一个关于此的问题。 我还将很快提交一个拉取请求,要求控制台传输是同构的。

IGNOREME:我在这里发表评论,以便将来我可以轻松地再次找到这个问题,[因为我不能通过单独订阅来做到这一点](https://github.com/isaacs/github/issues/283)。

我遇到了同样的问题, Error: Cannot find module './combine'

+1

@chrisvoo :以下是错误,当我尝试运行您的代码段时(winston 和 winston-transport 有 3+ 个版本)
winston-transport/index.js 中的错误
未找到模块:错误:无法解析 node_modules/winston-transport 中的“流”

PR #1145(2017 年 11 月开放)今年是否有机会合并? :眨眼:

@dmitry-salnikov #1145 已合并为 master。 虽然还没有发布。

关闭 关闭 关闭。

谢谢土豆的支持

5年,至少它的结果。 Winston 仍然是 JavaScript IMO 的最佳日志记录系统

谢谢!

这将保持打开状态,直到我们的测试套件中有验证浏览器支持的测试。 然而,似乎 babel 和 webpack 周围的大多数边缘和角落案例都已解决。

在这里,我们喜欢winston,需要一个客户端日志中间件。

自从浏览器实现以来已经过去了一段时间,我们想从现在开始使用它。

在等待单元测试和完整的浏览器覆盖之前,对浏览器支持有什么粗略的了解吗?

尝试将 winston 导入我的项目,但失败并显示以下消息:
./\~/winston/lib/winston/tail-file.js 中的错误
找不到模块:错误:无法解析“/Users/me/workspaces/app/node_modules/winston/lib/winston”中的“fs”
@ ./\~/winston/lib/winston/tail-file.js 10:11-24
@ ./\~/winston/lib/winston/transports/file.js
@ ./\~/winston/lib/winston/transsports/index.js
@ ./\~/winston/lib/winston.js
@ ./src/app/app.module.ts
@ ./src/main.ts

温斯顿的 index.js 导入传输,它导入需要“fs”的“.file”。

我如何退订这个新鲜的地狱

  • 迈克尔

2018 年 8 月 7 日星期二下午 2:19 Kfir Erez [email protected]写道:

试图将winston导入我的项目,但失败了以下
信息:
.//winston/lib/winston/tail-file.js 中的错误
找不到模块:错误:无法解析“fs”
'/Users/me/workspaces/app/node_modules/winston/lib/winston'
@ .//winston/lib/winston/tail-file.js 10:11-24
@ .//winston/lib/winston/transports/file.js
@ .//winston/lib/winston/transsports/index.js
@ ./~/winston/lib/winston.js
@ ./src/app/app.module.ts
@ ./src/main.ts

温斯顿的 index.js 导入传输需要导入“.file”
'fs'。


您收到此消息是因为您发表了评论。
直接回复此邮件,在 GitHub 上查看
https://github.com/winstonjs/winston/issues/287#issuecomment-410946148
或使线程静音
https://github.com/notifications/unsubscribe-auth/AE3lcdZ3aQKEVYvYB2TXjh0dnQ1FaBS2ks5uOTFhgaJpZM4A2vjK
.

@mjcd你永远被困在这里😆(j/k,你可以使用电子邮件上的链接或通过 gh 取消订阅)

我遇到了与@Kerez使用 webpack 相同的错误

解决这个问题的一种常见方法是将node: { fs: 'empty' }放在你的 webpack 配置中——显然不要尝试使用浏览器中的File传输,它不会起作用。 如果我们可以在没有额外配置设置的情况下在 webpack 中制作 winston 捆绑包,但如果可能的话,那就太好了。 其他流行的包推荐同样的东西——尽管https://github.com/pugjs/pug-loader/issues/8#issuecomment -328331541 建议我们可以在winston的package.json中解决这个问题。 如果解决了该错误,有人想尝试并打开 PR(即不更改应用程序的 webpack 配置,只需更改 winston 的 package.json)?

我由于 setImmediate 而出现错误...我不明白为什么,因为@chrisvoo似乎成功了。 也许是因为你他使用了 polyfill?

我的相关问题: https ://github.com/winstonjs/winston/issues/1489

在这里根据@chrisvoo代码制作了一个包(非常感谢):
https://www.npmjs.com/package/winston-transport-browserconsole。

此外,那里有一个小示例,因此您可以与默认的 winston 控制台输出进行比较。

解决这个问题的常用方法是将 node: { fs: 'empty' } 放在你的 webpack 配置中

是否有计划支持 webpack 浏览器捆绑包而无需对 webpack 配置进行此更改?

如果我们可以在没有额外配置设置的情况下在 webpack 中制作 winston 捆绑包,但如果可能的话,那就太好了。 其他流行的包也推荐同样的东西——尽管pugjs/pug-loader#8(评论)建议我们可以在 winston 的 package.json 中解决这个问题。 如果解决了该错误,有人想尝试并打开 PR(即不更改应用程序的 webpack 配置,只需更改 winston 的 package.json)?

@DABH不幸的是,我认为事情没那么简单。 你们使用浏览器字段来定义不同的入口点。 我相信它可以用于定义不同的入口点或替换某些模块,如该票中所述 - 不能两者兼而有之。 但是由于您似乎已经在构建自己的浏览器版本,所以也许可以将其删除。 如果这个周末有机会,我会去顶峰。

这方面有什么进展吗? 已经 6 年了,明天就是 2020 年 :-)

也许解决方案是重新包装winston,以便运输者是他们自己的模块。 听起来像一个更好的解决方案

我们可以在角度使用温斯顿吗? 如何 ?

@ArpithaGMGowda不使用标准的角度 CLI

那么我们可以为 Angular 7 使用什么?
任何的想法

我在上一个项目中使用了 js-logger,它运行得非常好,并允许我向 elk 发送日志,尽管它看起来在去年没有太多活动: https ://github.com/jonnyreeves/js-logger
有一些不错的日志服务也可能对您有用,例如 track.js

我正在将此库重写为一个新结构,以消除对节点的依赖。 应该在下周完成

Winston 的问题是基于代码的需要在不破坏核心功能的情况下进行现代化改造。

传输层需要拆分成它自己的子模子,这反过来会导致我猜团队不想造成的破坏性变化。 除非团队愿意采用新的生态系统。 我不确定正在修复的 PR 是否会被批准。

你们有人尝试过使用 NGX-Logger“ https://www.npmjs.com/package/ngx-logger ”吗?

@ArpithaGMGowda我猜对我来说,我不喜欢编写将您与固定框架联系在一起的代码库。 从 UI 到服务调用,代码应该尽可能地不可知。 我也喜欢统一机制的想法。 为什么有一种方式用于后端而另一种方式用于前端

我正在将此库重写为一个新结构,以消除对节点的依赖。 应该在下周完成

@Jordan-Hall 想知道我们是否很快就会有rc (谢谢)。
必须修改第三方 webpack 以免在他们使用我们使用 winston 的项目/lib 时中断。

@MarcoMedrano这是一个根本性的变化,理论上我完成了一个新的图书馆时间。

@pose您对从核心包中拆分传输层有何看法? 我喜欢温斯顿,但生态系统确实需要改变

花了一些时间来写这个,但我已经想出了一个合理的解决方案。
以下将允许您在浏览器中使用错误、警告和信息级别(带有自定义前缀!),它们看起来像这样:
gHLo47GZ0bvMAsiqhxRfSV3TIWyXn9NO

为此,您需要安装winstonlogformwinston-transport作为依赖项。

这是实现此功能所需的代码。
请注意,这是用打字稿编写的,下面是 javascript 示例。

import * as winston from 'winston';
import {TransformableInfo} from 'logform';
import TransportStream = require('winston-transport');

// enumeration to assign color values to
enum LevelColors {
  INFO = 'darkturquoise',
  WARN = 'khaki',
  ERROR = 'tomato',
}

// type levels used for setting color and shutting typescript up
type Levels = 'INFO' | 'WARN' | 'ERROR';

const defaultColor = 'color: inherit';

//! Overriding winston console transporter
class Console extends TransportStream {
  constructor(options = {}) {
    super(options);

    this.setMaxListeners(30);
  }

  log(info: TransformableInfo, next: () => void) {
    // styles a console log statement accordingly to the log level
    // log level colors are taken from levelcolors enum
    console.log(
      `%c[%c${info.level.toUpperCase()}%c]:`,
      defaultColor,
      `color: ${LevelColors[info.level.toUpperCase() as Levels]};`,
      defaultColor,
      // message will be included after stylings
      // through this objects and arrays will be expandable
      info.message
    );

    // must call the next function here
    // or otherwise you'll only be able to send one message
    next();
  }
}

// creating silent loggers with according levels
// silent by default to be automatically deactivated
// in production mode
export const logger = winston.createLogger({
  transports: [
    new Console({
      silent: true,
      level: 'info',
    }),
  ],
});

// don't log anything in production mode
// probably should go further and return non
// working logger function to reduce
// execution time and improve speed results
// on application
if (process.env.NODE_ENV !== 'production') {
  logger.transports.forEach(transport => (transport.silent = false));
}

这是javascript示例

import * as winston from 'winston';

import {TransformableInfo} from 'logform';
import TransportStream = require('winston-transport');

// enumeration to assign color values to
const LevelColors = {
  INFO: 'darkturquoise',
  WARN: 'khaki',
  ERROR: 'tomato',
}

const defaultColor = 'color: inherit';

//! Overriding winston console transporter
class Console extends TransportStream {
  constructor(options = {}) {
    super(options);

    this.setMaxListeners(30);
  }

  log(info, next) {
    // styles a console log statement accordingly to the log level
    // log level colors are taken from levelcolors enum
    console.log(
      `%c[%c${info.level.toUpperCase()}%c]:`,
      defaultColor,
      `color: ${LevelColors[info.level.toUpperCase()]};`,
      defaultColor,
      // message will be included after stylings
      // through this objects and arrays will be expandable
      info.message
    );

    // must call the next function here
    // or otherwise you'll only be able to send one message
    next();
  }
}

// creating silent loggers with according levels
// silent by default to be automatically deactivated
// in production mode
export const logger = winston.createLogger({
  transports: [
    new Console({
      silent: true,
      level: 'info',
    }),
  ],
});

// don't log anything in production mode
// probably should go further and return non
// working logger function to reduce
// execution time and improve speed results
// on application
if (process.env.NODE_ENV !== 'production') {
  logger.transports.forEach(transport => (transport.silent = false));
}

您可以更改 LevelColors 枚举中的颜色。 如果要更改格式,请查看第 29 行。

添加对调试级别的支持。 将控制台选项中的level设置为'debug'
还可以添加对所有标准 winston 级别的支持,这意味着:emerg、alert、crit、error、warn、info 和 debug。 如果您也想使用这些,则需要将此对象添加到 createLogger 根目录中的levels配置

{
   emerg: 0,
   alert: 1,
   crit: 2,
   error: 3,
   warn: 4,
   info: 5,
   debug: 6,
}

然后在 LevelColors 枚举中添加颜色值。

我正在努力清楚地了解这个问题的状态。 我可以在我的 React 应用程序中使用 Winston 吗?

实际上,我对登录到浏览器控制台并不太感兴趣-老实说,当内置console用于相同目的时,我不明白覆盖winston console transporter的意义; 也许有人可以启发我。

我的情况是我的 React 应用程序在 nginx / Let's Encrypt 代理后面的 Docker 容器中运行,因此我无法访问任何 JavaScript 控制台输出; 因此,我想将任何日志输出转发到系统日志服务器。

我已经成功设置了一个syslog-ng Docker 容器,它整合了来自数据库、后端和我的项目所用​​的其他一些容器的日志输出,但我似乎找不到一个直接/规范的 syslogging 方法React 前端的输出。

在我开始破解一些愚蠢的自制解决方案之前,有人对我有更好的建议吗?
也许取上面的代码并用一些通过网络将消息发送到系统日志服务器的代码替换console.log

@z00m1n这主要取决于您的用例。 我在浏览器中使用 winston 来记录我所做的所有请求和函数调用。 如果我在生产环境中,我将输出限制为仅打印错误。

并且使用我的代码并将 console.log 语句与其他东西交换会起作用。

但是,在您编写一个 hacky 解决方案来完成这项工作之前,我建议使用 sentry。

这还取决于您是否可以控制 webpack。 可悲的是,这个惊人的包在架构上已经过时了,这使得它不可能真正解决

@Keimeno您是否注意到任何奇怪的行为或性能问题? 真的很想使用,但它必须是超级稳定的,因为我的用例会在生产中发生一些日志记录......

@gcperrin不确定您是否可以将其称为性能问题,但我一直在运行一些基准测试并得到以下结果:
开发环境:它将某些内容记录到控制台
prod 环境:它不会记录任何内容,但会调用 log 函数

_console.info(开发环境)_; 10.000 条日志需要 1.863 秒。 (每个 0,1893 毫秒)
_logger.info(开发环境)_:10.000 条日志需要 7.980 秒。 (每个 0.7980 毫秒)

_logger.info(产品环境)_; 10.000 条日志需要 3.731 秒。 (每个 0.3731 毫秒)

这意味着如果您使用我的函数来使生产中的记录器静音,您仍然可以让同步代码运行 0.3731 毫秒(可能甚至更高)。 这可能不是性能问题,但如果您有数百个在生产环境中处于静默状态的日志,则可能会导致您的 web 应用程序滞后。

有什么方法可以使用winston在浏览器端持久登录到文件系统?

我有一个 React 应用程序,想将客户端日志存储到文件系统中。 请提出一些想法。

提前致谢。

此页面是否有帮助?
0 / 5 - 0 等级