」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > LogTape .eleased:有什麼新內容?

LogTape .eleased:有什麼新內容?

發佈於2024-11-13
瀏覽:450

LogTape .eleased: What

LogTape,一个用于 JavaScript 和 TypeScript 的零依赖结构化日志库,已发布 v0.6.0。发生了什么变化?

覆盖父记录器的接收器

LogTape 的功能之一是通过分层类别继承接收器。例如,如果您设置两个记录器,如下所示:

import { configure, getConsoleSink, getFileSink } from "@logtape/logtape";

await configure({
  sinks: {
    console: getConsoleSink(),
    file:    getFileSink("app.log"),
  },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"] },
  ],
});

写入 ["app"] 记录器的日志将仅保存到 app.log 文件,但写入 ["app", "module"] 记录器的日志将同时保存到 app.log 文件

app.log

文件并输出到控制台。这是因为 ["app", "module"] 记录器从其父类别 ["app"] 继承了接收器。 但是,有时您可能不希望出现这种行为。从 LogTape 0.6.0 开始,您现在可以
覆盖

父记录器的接收器。例如,如果您为子记录器启用parentSinks:“覆盖”选项,如下所示:
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

等待配置({ 汇:{ /* 省略;与上面相同*/ }, 记录器:[ { 类别:[“应用程序”],级别:“调试”,接收器:[“文件”] }, { 类别:[“应用程序”,“模块”],级别:“调试”,接收器:[“控制台”],parentSinks:“覆盖”}, ], }); 写入["app"]记录器的日志只会保存到

app.log

文件,写入["app","module"]记录器的日志只会输出到控制台。这是因为子记录器 ["app", "module"] 覆盖了 ["app"] 记录器的接收器。

当然,默认值是parentSinks: "inherit",所以如果你不指定该选项,它的行为会和以前一样。

如果您想了解此功能添加的背景,请参阅 GitHub Issue #15。

允许消息模板中的占位符使用前导/尾随空格

在以前的版本中,如果您这样登录:
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

logger.info("你好,{ name }!", { name: "Alice" });

与预期相反,一条日志Hello, undefined!将被创建。这是因为占位符 { name } 包含空格字符,因此它查找属性“ name ”而不是“ name ”。换句话说,您必须从占位符中删除空格,如下所示:
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

logger.info("你好,{name}!", { name: "Alice" });

或者在实际属性名称中添加相同的空格,如下所示:
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

logger.info("你好,{ name }!", { " name ": "Alice" });

虽然这并不是严格意义上的错误,但根据编码习惯,它是容易出错的行为。

但是,从LogTape 0.6.0开始,即使占位符的开头和结尾有空格,它也会寻找不带空格的属性名称。例如,如果您像这样登录:
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

logger.info("你好,{ name }!", { name: "Alice" });

正如预期的那样,日志是Hello, Alice!将被创建。

但是,如果有一个属性完全匹配(包括空格字符),则该属性将被优先考虑。例如,如果您像这样登录:
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

logger.info("你好,{ name }!", { name: "Alice", " name ": "Bob" });

你好,鲍勃!将被记录而不是你好,爱丽丝!。

如果您想了解此功能添加的背景,请参阅 GitHub Issue #16。

LogRecord.rawMessage 属性

LogRecord 是一种数据类型,表示在 LogTape 输出和格式化之前的日志。

虽然 LogRecord.message 属性已经存在,但该属性包含消息模板中的占位符替换为实际属性值后的结果。这在大多数情况下已经足够了,但是当日志输出目的地(接收器)是另一个日志系统时,您可能希望分别输出原始消息模板和属性值,从而允许接收日志系统用属性替换消息模板中的占位符直接值。

LogTape 0.6.0 中添加的 LogRecord.rawMessage 正是用于此目的的属性,其中包含消息模板的原始状态以及未替换的占位符。例如,如果您像这样登录:
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

logger.info("你好,{name}!", { name: "Alice" });

虽然 LogRecord.message 将包含值 ["Hello, ", "Alice", "!"],但 LogRecord.rawMessage 将包含值 "Hello, {name}!"。

如果您想了解此功能添加的背景,请参阅 GitHub Issue #17。

可定制的内置文本格式化程序

文本格式化程序是一个接口,它确定每个日志如何在流接收器、文件接收器等中格式化为文本。实际的类型定义非常简单:
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

导出类型TextFormatter = (记录: LogRecord) => string;

但是,每次直接定义文本格式化程序可能会很麻烦,因此 LogTape 内置了 defaultTextFormatter 和 ansiColorFormatter 可供您使用。到目前为止,由于无法进行其他配置,因此您必须按原样接受预定格式。例如,如果您不喜欢像“警告”这样的日志级别输出为像 WRN 这样的三个字母缩写,则必须从头开始实现 TextFormatter。

但是,从 LogTape 0.6.0 开始,您可以通过 getDefaultTextFormatter() 和 getAnsiColorFormatter() 函数根据自己的喜好自定义各种格式设置,而无需从头开始实现 TextFormatter。

例如,如果要将“警告”这样的日志级别表示为单个大写字母W,可以这样配置:
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

const myFormatter = getDefaultTextFormatter({ level: "L" });

或者如果你想省略时间戳中的日期和时区,只显示时间,你可以这样配置:
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

const myFormatter = getDefaultTextFormatter({ 时间戳: "时间" });

更多格式化选项的说明,请参考相关文档。

如果您想了解此功能添加的背景,请参阅 GitHub Issue #13。

从 JSR 和 npm 获取

LogTape 0.6.0 已在 JSR 和 npm 上可用,所以立即获取!
await configure({
  sinks: { /* omitted; same as above */ },
  loggers: [
    { category: ["app"],           level: "debug", sinks: ["file"] },
    { category: ["app", "module"], level: "debug", sinks: ["console"], parentSinks: "override" },
  ],
});

deno 添加 @logtape/[email protected] # Deno npm 添加@logtape/[email protected] # npm pnpm 添加@logtape/[email protected] # pnpm 纱线添加 @logtape/[email protected] # 纱线 包子添加@logtape/[email protected] # 包子

祝您登录愉快!

LogTape .eleased: What

版本聲明 本文轉載於:https://dev.to/hongminhee/logtape-060-released-whats-new-17od?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 組件指南,兄弟們。
    組件指南,兄弟們。
    VuePress 1.0發布!簡單來說,它是一個基於Vue的靜態網站生成器。而Vue的核心就是組件化開發。 如今,所有主流的JavaScript框架都採用組件化模式。即使在某些細節上存在差異(例如Svelte需要編譯),它們都一致認同組件化開發模型。 React完全基於組件,Next.js是流行...
    程式設計 發佈於2025-05-02
  • 如何有效地選擇熊貓數據框中的列?
    如何有效地選擇熊貓數據框中的列?
    在處理數據操作任務時,在Pandas DataFrames 中選擇列時,選擇特定列的必要條件是必要的。在Pandas中,選擇列的各種選項。 選項1:使用列名 如果已知列索引,請使用ILOC函數選擇它們。請注意,python索引基於零。 df1 = df.iloc [:,0:2]#使用索引0和1 ...
    程式設計 發佈於2025-05-02
  • 在PHP中如何高效檢測空數組?
    在PHP中如何高效檢測空數組?
    在PHP 中檢查一個空數組可以通過各種方法在PHP中確定一個空數組。如果需要驗證任何數組元素的存在,則PHP的鬆散鍵入允許對數組本身進行直接評估:一種更嚴格的方法涉及使用count()函數: if(count(count($ playerList)=== 0){ //列表為空。 } 對...
    程式設計 發佈於2025-05-02
  • 如何在MySQL的`IN`查詢中保持值的順序?
    如何在MySQL的`IN`查詢中保持值的順序?
    在“ queries Problem:In a scenario where you have a table with an auto-incremented primary key, you may encounter situations where the results of an &q...
    程式設計 發佈於2025-05-02
  • 如何在其容器中為DIV創建平滑的左右CSS動畫?
    如何在其容器中為DIV創建平滑的左右CSS動畫?
    通用CSS動畫,用於左右運動 ,我們將探索創建一個通用的CSS動畫,以向左和右移動DIV,從而到達其容器的邊緣。該動畫可以應用於具有絕對定位的任何div,無論其未知長度如何。 問題:使用左直接導致瞬時消失 更加流暢的解決方案:混合轉換和左 [並實現平穩的,線性的運動,我們介紹了線性的轉換。...
    程式設計 發佈於2025-05-02
  • 為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,輸出...
    程式設計 發佈於2025-05-02
  • 為什麼PYTZ最初顯示出意外的時區偏移?
    為什麼PYTZ最初顯示出意外的時區偏移?
    與pytz 最初從pytz獲得特定的偏移。例如,亞洲/hong_kong最初顯示一個七個小時37分鐘的偏移: 差異源利用本地化將時區分配給日期,使用了適當的時區名稱和偏移量。但是,直接使用DateTime構造器分配時區不允許進行正確的調整。 example pytz.timezone(&#...
    程式設計 發佈於2025-05-02
  • 您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    在javascript console 中顯示顏色是可以使用chrome的控制台顯示彩色文本,例如紅色的redors,for for for for錯誤消息? 回答是的,可以使用CSS將顏色添加到Chrome和Firefox中的控制台顯示的消息(版本31或更高版本)中。要實現這一目標,請使用以下...
    程式設計 發佈於2025-05-02
  • 如何在Java字符串中有效替換多個子字符串?
    如何在Java字符串中有效替換多個子字符串?
    在java 中有效地替換多個substring,需要在需要替換一個字符串中的多個substring的情況下,很容易求助於重複應用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    程式設計 發佈於2025-05-02
  • 如何使用“ JSON”軟件包解析JSON陣列?
    如何使用“ JSON”軟件包解析JSON陣列?
    parsing JSON與JSON軟件包 QUALDALS:考慮以下go代碼:字符串 } func main(){ datajson:=`[“ 1”,“ 2”,“ 3”]`` arr:= jsontype {} 摘要:= = json.unmarshal([] byte(...
    程式設計 發佈於2025-05-02
  • Java中如何使用觀察者模式實現自定義事件?
    Java中如何使用觀察者模式實現自定義事件?
    在Java 中創建自定義事件的自定義事件在許多編程場景中都是無關緊要的,使組件能夠基於特定的觸發器相互通信。本文旨在解決以下內容:問題語句我們如何在Java中實現自定義事件以促進基於特定事件的對象之間的交互,定義了管理訂閱者的類界面。 以下代碼片段演示瞭如何使用觀察者模式創建自定義事件: args...
    程式設計 發佈於2025-05-02
  • 哪種方法更有效地用於點 - 填點檢測:射線跟踪或matplotlib \的路徑contains_points?
    哪種方法更有效地用於點 - 填點檢測:射線跟踪或matplotlib \的路徑contains_points?
    在Python Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a path object to represent the polygon.它...
    程式設計 發佈於2025-05-02
  • 哪種在JavaScript中聲明多個變量的方法更可維護?
    哪種在JavaScript中聲明多個變量的方法更可維護?
    在JavaScript中聲明多個變量:探索兩個方法在JavaScript中,開發人員經常遇到需要聲明多個變量的需要。對此的兩種常見方法是:在單獨的行上聲明每個變量: 當涉及性能時,這兩種方法本質上都是等效的。但是,可維護性可能會有所不同。 第一個方法被認為更易於維護。每個聲明都是其自己的語句,使...
    程式設計 發佈於2025-05-02
  • 如何解決由於Android的內容安全策略而拒絕加載腳本... \”錯誤?
    如何解決由於Android的內容安全策略而拒絕加載腳本... \”錯誤?
    Unveiling the Mystery: Content Security Policy Directive ErrorsEncountering the enigmatic error "Refused to load the script..." when deployi...
    程式設計 發佈於2025-05-02
  • 如何處理PHP文件系統功能中的UTF-8文件名?
    如何處理PHP文件系統功能中的UTF-8文件名?
    在PHP的Filesystem functions中處理UTF-8 FileNames 在使用PHP的MKDIR函數中含有UTF-8字符的文件很多flusf-8字符時,您可能會在Windows Explorer中遇到comploreer grounder grounder grounder gro...
    程式設計 發佈於2025-05-02

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3