首頁 web前端 js教程 使用 Lambda 的 Powertools 緩衝日誌並在發生錯誤時自動刷新

使用 Lambda 的 Powertools 緩衝日誌並在發生錯誤時自動刷新

Dec 19, 2024 pm 08:23 PM

Buffer Logs and Flush Automatically on Error with Powertools for Lambda

最新版本的 AWS Powertools for Lambda 讓使用自訂功能擴充 Logger 變得更輕鬆:

Logger 類別現在更具可擴充性
現在您可以覆寫 Logger 方法 createAndPopulateLogItem、printLog 和 processLogItem,這些方法以前是私有的。這允許您擴展記錄器並添加新功能,例如實現您自己的訊息緩衝區。
發布 v2.12.0

我正在使用這個新的擴充性來實現一個有用的功能:日誌緩衝和刷新。這個想法很簡單:在生產環境中,我們通常只記錄重要訊息,例如警告和錯誤,因為日誌空間可能會變得昂貴並且會產生噪音。但是,當發生錯誤時,我們希望獲得所有可能的資訊:分散在函數中的所有偵錯和資訊日誌都應該可用。但它們並不是因為我們將日誌等級設定得太低。

緩衝和沖洗

如果我們在內部收集所有這些偵錯和資訊日誌,如果發生錯誤等重要事件,我們將它們列印到控制台怎麼辦?我把日誌分為兩類:低階日誌和進階日誌。如果我們配置的日誌等級是 WARN,則 DEBUG 或 INFO 日誌將是低階日誌,而 ERROR 將是進階日誌。

現在,當我們列印低階日誌時,我們不會像現在這樣丟棄它,而是將日誌緩衝在內部列表中。一旦我們有了高級日誌,我們就會將所有緩衝的日誌刷新到控制台。

執行

為了新增此功能,我們建立一個新類,該類別從 Powertools 擴展 Logger 類別並重寫 processLogItem()。這是由不同的日誌方法(如 logger.debug())呼叫的中心方法。如果日誌項目處於正確的級別,原始實作會將日誌項目列印到控制台。透過重寫此方法,我們可以根據日誌等級新增緩衝和刷新日誌的特殊邏輯。

import { LogItem, Logger as PowertoolsLogger } from '@aws-lambda-powertools/logger';
import type { LogItemExtraInput, LogItemMessage } from '@aws-lambda-powertools/logger/types';

export class Logger extends PowertoolsLogger {
  #buffer: Record<string, Array<[number, string]>> = {};

  get buffer(): Record<string, Array<[number, string]>> {
    return this.#buffer;
  }

  protected override processLogItem(logLevel: number, input: LogItemMessage, extraInput: LogItemExtraInput): void {
    const xRayTraceId = this['envVarsService'].getXrayTraceId() as string;

    // Flush buffer when log level is higher than the configured log level
    if (logLevel > this.level && xRayTraceId) {
      const buffer = this.#buffer[xRayTraceId] ?? [];

      // Print all log items in the buffer
      if (buffer.length) this.info(`Flushing buffer with ${buffer.length} log items`);

      for (const [bufferLogLevel, bufferLogItem] of buffer) {
        // Create a new LogItem from the stringified log item
        this.printLog(bufferLogLevel, new LogItem(JSON.parse(bufferLogItem)));
      }

      // Clear the buffer after flushing
      // This also removes entries from other X-Ray trace IDs
      this.#buffer = {};
    }

    // Buffer the log item when log level is lower than the configured log level
    if (logLevel < this.level && xRayTraceId) {
      const buffer = this.#buffer[xRayTraceId] ?? [];
      // Add the stringified log item to the buffer
      // Serializing the log item ensures it is not mutated after being added to the buffer
      buffer.push([logLevel, JSON.stringify(this.createAndPopulateLogItem(logLevel, input, extraInput))]);

      // Update the buffer with the new log item
      // This also removes other X-Ray trace IDs from the buffer
      this.#buffer = {
        [xRayTraceId]: buffer,
      };
    }

    // Call the parent method to ensure the log item is processed
    super.processLogItem(logLevel, input, extraInput);
  }
}
登入後複製
登入後複製

您可能會問為什麼我們在這裡使用 X 光追蹤 ID。在處理程序函數之外實例化 Logger 是很常見的。但是,由於 Lambda 執行環境可能會重複用於多次調用,因此緩衝區可能包含先前調用的日誌項目。這就是緩衝區被實現為物件而不是簡單數組的原因。我們使用 X-Ray Trace ID 作為標識符,僅緩衝來自相同呼叫的日誌項。
緩衝區被實作為一個物件而不是一個簡單的陣列。當緩衝區被刷新時,我們可以簡單地重置對象,從而從其他呼叫中清除項目。

本地測試

讓我們快速在本地驗證一下實作:

// set X-Ray Trace ID manually if running locally
process.env._X_AMZN_TRACE_ID = '1-abcdef12-3456abcdef123456abcdef12';

// log level = WARN
const logger = new Logger({ logLevel: 'WARN' });

logger.debug('debug'); // < log level
logger.info('info');   // < log level
logger.warn('warn');   // = log level
logger.error('error'); // > log level
登入後複製

這是我們得到的輸出:

import { LogItem, Logger as PowertoolsLogger } from '@aws-lambda-powertools/logger';
import type { LogItemExtraInput, LogItemMessage } from '@aws-lambda-powertools/logger/types';

export class Logger extends PowertoolsLogger {
  #buffer: Record<string, Array<[number, string]>> = {};

  get buffer(): Record<string, Array<[number, string]>> {
    return this.#buffer;
  }

  protected override processLogItem(logLevel: number, input: LogItemMessage, extraInput: LogItemExtraInput): void {
    const xRayTraceId = this['envVarsService'].getXrayTraceId() as string;

    // Flush buffer when log level is higher than the configured log level
    if (logLevel > this.level && xRayTraceId) {
      const buffer = this.#buffer[xRayTraceId] ?? [];

      // Print all log items in the buffer
      if (buffer.length) this.info(`Flushing buffer with ${buffer.length} log items`);

      for (const [bufferLogLevel, bufferLogItem] of buffer) {
        // Create a new LogItem from the stringified log item
        this.printLog(bufferLogLevel, new LogItem(JSON.parse(bufferLogItem)));
      }

      // Clear the buffer after flushing
      // This also removes entries from other X-Ray trace IDs
      this.#buffer = {};
    }

    // Buffer the log item when log level is lower than the configured log level
    if (logLevel < this.level && xRayTraceId) {
      const buffer = this.#buffer[xRayTraceId] ?? [];
      // Add the stringified log item to the buffer
      // Serializing the log item ensures it is not mutated after being added to the buffer
      buffer.push([logLevel, JSON.stringify(this.createAndPopulateLogItem(logLevel, input, extraInput))]);

      // Update the buffer with the new log item
      // This also removes other X-Ray trace IDs from the buffer
      this.#buffer = {
        [xRayTraceId]: buffer,
      };
    }

    // Call the parent method to ensure the log item is processed
    super.processLogItem(logLevel, input, extraInput);
  }
}
登入後複製
登入後複製

警告是第一個訊息,因為偵錯和資訊日誌已被緩衝。當錯誤被記錄時,我們在實際列印錯誤之前刷新了緩衝的日誌(並列印了資訊)。

徵求意見

我的幼稚實現有一些警告。最重要的是,緩衝區大小不受限制,這意味著如果緩衝區增長太大,可能會導致記憶體問題。有幾種方法可以緩解此問題,例如,將緩衝區實作為滑動窗口,僅保留最新日誌或限制總緩衝區大小。

此外,緩衝日誌僅在受控情況下刷新,例如在 logger.error() 上,但在未處理的錯誤上不會刷新。如果我們將緩衝區公開並使用像 Middy.js 這樣的中間件,則可以輕鬆實現此行為。 Middy 公開了一個 onError 事件,我們可以利用該事件來刷新緩衝區。

我在官方 AWS Powertools for Lambda 儲存庫的評論請求中更詳細地介紹了這一點。

如果您希望看到此功能成為 Powertools for Lambda 的一部分,請在那裡分享您的想法和回饋?

以上是使用 Lambda 的 Powertools 緩衝日誌並在發生錯誤時自動刷新的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1655
14
CakePHP 教程
1414
52
Laravel 教程
1307
25
PHP教程
1255
29
C# 教程
1228
24
神秘的JavaScript:它的作用以及為什麼重要 神秘的JavaScript:它的作用以及為什麼重要 Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的演變:當前的趨勢和未來前景 JavaScript的演變:當前的趨勢和未來前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

JavaScript引擎:比較實施 JavaScript引擎:比較實施 Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript:探索網絡語言的多功能性 JavaScript:探索網絡語言的多功能性 Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

如何使用Next.js(前端集成)構建多租戶SaaS應用程序 如何使用Next.js(前端集成)構建多租戶SaaS應用程序 Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

從C/C到JavaScript:所有工作方式 從C/C到JavaScript:所有工作方式 Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

如何安裝JavaScript? 如何安裝JavaScript? Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

See all articles