【问题标题】:Generate logs for web application in Javascript在 Javascript 中为 Web 应用程序生成日志
【发布时间】:2021-03-15 05:35:42
【问题描述】:

我有一个用例,我想为我的 JS Web 应用程序生成日志,它可以作为文件存储在客户端(存储在用户的机器上)。

所以我想知道在JS中生成日志可以遵循什么方法?

【问题讨论】:

  • 在什么?浏览器?基于浏览器的 JavaScript 代码无法写入用户计算机上的任意文件。这将是一个巨大的安全问题。
  • “我见过 Node JS 的库,但找不到任何适用于 vanilla JS 的库。” Node.js 不是 JavaScript 的变体。这是一个主机环境。网络浏览器也是如此。两者都在不同的环境中执行“vanilla”JavaScript。

标签: javascript logging web-applications client


【解决方案1】:

如果您想通过浏览器托管的 JavaScript 代码执行此操作,恐怕您做不到。基于浏览器的 JavaScript 代码无法写入用户计算机上的任意文件。这将是一个巨大的安全问题。

您可以在 web storage 中保留一个“日志”,但请注意网络存储有大小限制,因此您不希望它变得太大。

这是添加到本地存储日志的准系统日志记录功能:

function log(...msgs) {
    // Get the current log's text, or "" if there isn't any yet
    let text = localStorage.getItem("log") || "";
    // Add this "line" of log data
    text += msgs.join(" ") + "\r\n";
    // Write it back to local storage
    localStorage.setItem("log", text);
}

显然,您可以通过多种不同的方式(日志级别、日期/时间日志等)在此基础上进行构建。

【讨论】:

  • indexDB 也是个好地方吗?我的意思是它的异步并且不会像 localstorage 那样阻塞线程
  • @Ifaruki - 我有忘记 IndexedDB 的坏习惯。它不适用于所有仍然(!)使用 IE 的人,但现在 Edge 基于 Chromium,support is good。所以我会说:是的,绝对!如果您可以举出一个示例,请随时将其编辑到上面(这是社区 Wiki 帖子)或发布您自己的答案。如果你做后者,请 ping 我(所以会为前者 ping 我)——我很想看到它。 :-)
【解决方案2】:

您可以使用本地存储来模拟文件:

为“文件”的每一行创建 id 并存储最后一行的编号

function logIntoStorage (pMsg) {
    if (!pMsg) pMsg = "pMsg is not here !";
    if ((typeof pMsg) != "string") pMsg = "pMsg is Not a string:"+(typeof pMsg);        
    let logNb = "logNb";
    let padLong = 7;
    let strLg = "0";
    let lg = 0;
    let maxSize = 50; // max nb of lines in the log
    
    // Reading log num line
    strLg = localStorage.getItem(logNb);
    if(!strLg) { //logNb not stored yet
        lg = 0;
        strLg = "0";
        localStorage.setItem(logNb, lg.toString(10)); // store the number of cur line
    } else { // Read logNb from storage
        strLg = localStorage.getItem(logNb);
        lg = parseInt(strLg,10);
    } 
        
    if (lg >= maxSize) {
       lg = maxSize; // size limit nb lines.
       pMsg = "LIMIT SIZE REACHED";
    }


    // log msg into localStorage at logLine:0000#### 
    let s = ("0000000000000000"+strLg).substr(-padLong);  // padding zeros
    localStorage.setItem("logLine:"+s, pMsg);
    
    if (lg >= maxSize) return;
    lg++;  // point to the next line
    localStorage.setItem(logNb, lg.toString(10));
}

【讨论】:

    【解决方案3】:

    在现代 Chrome 中,您实际上可以在用户授予权限后将数据“流式传输”到用户的磁盘,这要归功于 File System Access API。

    为此,您必须请求要保存到的文件,调用showSaveFilePicker()

    一旦您获得用户的批准,您将收到一个句柄,您可以从中获取 WriteableStream。
    完成写作后,您只需.close()作者即可。

    onclick = async () => {
    
      if( !("showSaveFilePicker" in self) ) {
        throw new Error( "unsupported browser" );
      }
    
      const handle = await showSaveFilePicker();
      const filestream = await handle.createWritable();
      const writer = await filestream.getWriter();
      // here we have a WritableStream, with direct access to the user's disk
      // we can write to it as we wish
      writer.write( "hello" );
      writer.write( " world" );
      // when we're done writing
      await writer.ready;
      writer.close();
    
    };
    
    

    Live example.

    【讨论】:

    • 这是一个非常有趣的解决方案。我相信除了磁盘大小之外不会有任何存储大小限制。我想知道您是否还有其他缺点,比如性能等?
    • 最大的缺点是浏览器支持,目前只有 Chrome。性能方面,它与您的 HDD 一样快。关于存储限制,确实应该是磁盘大小,尽管可能存在我不知道的限制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 2020-03-10
    • 2013-05-22
    相关资源
    最近更新 更多