V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hgjian
V2EX  ›  Node.js

请问 node.js 怎么实现 console.log 同步输出到日志?不要等程序执行完再一次性写入。

  •  1
     
  •   hgjian · 2019-11-22 23:30:24 +08:00 · 10665 次点击
    这是一个创建于 1827 天前的主题,其中的信息可能已经有所发展或是发生改变。

    node.js 中将 console.log 日志内容输出到文件

    async function Get_alldata (  ) {  
    
            var fs      = require('fs')
            var util    = require('util')
            var logPath = 'upgrade.log'
            var logFile = fs.createWriteStream(logPath, { flags: 'a' })
            console.log = function() {
              logFile.write(util.format.apply(null, arguments) + '\n') // 输出 01、02、03 到文本文件;
              process.stdout.write(util.format.apply(null, arguments) + '\n')
            }
    
           console.log( ' 01' );   
           console.log( ' 02' );   
           console.log( ' 03' );  
           
           ****** other code ******
           
           return await Get_alldata() ;
    }	
    

    上面的代码,只能在 注屏蔽释掉 return await Get_alldata() ; 语句之后,在程序执行完之后,将 01、02、03 一次性的写入到到文本文件?

    如果 不注屏蔽释掉 return await Get_alldata() ; 那么 01、02、03 根本就没有写入文本文件;

    请问怎么实现 在直接使用 console.log( ) 函数的情况下,实时的将 console.log 输出的 01、02、03 写入到到文本文件?

    我实现了 await console.log( ) 的办法,可是太复杂了,使用也不方便;

    所以想请教一下这个社区的网友,有没有更好的办法?

    附上两个参考文档: Node 中 console.log 的同步实现: https://blog.csdn.net/li420520/article/details/83420994

    [Node.js 系统模块系列一] console 模块解读: https://juejin.im/post/5bf2b31f5188252e89668fe1

    如果有可以使用的插件,希望能够帮忙给个插件配置文件,谢谢!

    21 条回复    2019-12-02 21:58:26 +08:00
    des
        1
    des  
       2019-11-22 23:42:56 +08:00 via Android
    直接写 stdout
    ljpCN
        2
    ljpCN  
       2019-11-22 23:55:23 +08:00 via Android
    不介意将所有 console.log 替换一下的话,推荐使用日志模块。个人目前仅仅用过 log4js,感觉良好。
    seki
        3
    seki  
       2019-11-23 00:10:33 +08:00
    stdout
    但是为什么不用日志库呢
    hgjian
        4
    hgjian  
    OP
       2019-11-23 00:14:20 +08:00 via Android
    @seki 可以说细致点吗?因为我不是很熟悉
    hgjian
        5
    hgjian  
    OP
       2019-11-23 00:14:54 +08:00 via Android
    @des 请问怎么写?有范本吗?
    hgjian
        6
    hgjian  
    OP
       2019-11-23 00:16:14 +08:00 via Android
    @ljpCN 我不想替换的,因为太多了,会搞错。有没有不替换的配置呢?
    randyo
        7
    randyo  
       2019-11-23 00:21:13 +08:00 via Android
    可以在命令行中从标准输出转到文件吗
    ljpCN
        8
    ljpCN  
       2019-11-23 00:22:21 +08:00 via Android
    @hgjian 不替换大概就是楼上说的用 stdout,这样就可以输出到文件了。没搞过,楼主还是问谷歌吧。其实替换也不太容易出错,因为如果求快,直接所有的 console.log 替换成 logger.info 就行了
    hgjian
        9
    hgjian  
    OP
       2019-11-23 00:26:41 +08:00 via Android
    @randyo 不太明白你的意思,node test.js->log ?
    hgjian
        10
    hgjian  
    OP
       2019-11-23 00:28:02 +08:00 via Android
    @ljpCN process.stdout 模块吗?
    hgjian
        11
    hgjian  
    OP
       2019-11-23 01:03:19 +08:00 via Android
    @des 请问怎么改写才能实现同步在控制台和文本文件输出呢?
    binux
        12
    binux  
       2019-11-23 01:39:42 +08:00 via Android
    关闭行 buffer
    des
        13
    des  
       2019-11-23 08:15:14 +08:00 via Android
    @hgjian 要简单用用,可以直接用 tee 命令
    hgjian
        14
    hgjian  
    OP
       2019-11-23 08:44:17 +08:00 via Android
    @des 谢谢
    yamedie
        15
    yamedie  
       2019-11-23 09:02:59 +08:00 via Android
    pm2 可以直接记录 console.log 的输出
    ljpCN
        16
    ljpCN  
       2019-11-23 10:19:52 +08:00   ❤️ 1
    @hgjian
    1. 是这个模块没错,就是你贴的代码的写法。至于要同时输出到命令行和控制台,请使用 tee 命令,这个自行百度即可。多说一句我试过你的代码,不需要注释掉什么东西,是可以正常使用的,唯一区别是,我把模块引入和 log 定义放到了函数外面,代码如下:

    ```javascript
    var fs = require('fs')
    var util = require('util')

    var logPath = 'upgrade.log'
    var logFile = fs.createWriteStream(logPath, { flags: 'a' })

    console.log = function() {
    logFile.write(util.format.apply(null, arguments) + '\n')
    process.stdout.write(util.format.apply(null, arguments) + '\n')
    }

    console.error = function() {
    logFile.write(util.format.apply(null, arguments) + '\n')
    process.stderr.write(util.format.apply(null, arguments) + '\n')
    }

    async function Get_alldata() {
    console.log(' 01')
    console.log(' 02')
    console.log(' 03')

    return await Get_alldata()
    }

    Get_alldata()
    ```

    2. 楼上说的 pm2 的确是个更方便的用法,你直接用`pm2 start`启动脚本,会自动记录日志到文件,同时`pm2 log`可以在命令行查看日志。
    jifengg
        17
    jifengg  
       2019-11-23 11:24:55 +08:00   ❤️ 1
    log4js 有一个选项,是否替换 console 的 log 输出,替换之后,console.log 的信息也会记录到的。不用自己重写 console.log
    muzuiget
        18
    muzuiget  
       2019-11-23 11:41:18 +08:00
    buffer 问题,你真想等输出后才继续运行,不如用 fs.appendFileSync 这个接口。
    hgjian
        19
    hgjian  
    OP
       2019-11-24 09:13:42 +08:00 via Android
    @muzuiget 解决了
    var logFile = fs.createWriteStream(logPath, { flags: 'a' })
    console.log = function() {
    logFile.write(util.format.apply(null, arguments) + '\n') // 输出 01、02、03 到文本文件;

    替换为
    var fd =fs.opensyncfile(filepath)
    fs.writefilesync(fd,buffer)
    fs.closesync(fd)
    xcstream
        20
    xcstream  
       2019-12-02 20:48:33 +08:00
    node xxx.js >> log.txt 看输出用 tail -f log.txt 或者直接用 pm2
    hgjian
        21
    hgjian  
    OP
       2019-12-02 21:58:26 +08:00 via Android
    @xcstream pm2 改天试试看,感觉配置项好多
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2488 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:31 · PVG 23:31 · LAX 07:31 · JFK 10:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.