自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

普通程序員怎么理解日志系統(tǒng)

開發(fā) 后端
當我們在做系統(tǒng)開發(fā)時,日志系統(tǒng)是繞不開的話題。作為日志系統(tǒng)的最終使用者,我們會接觸不同的日志系統(tǒng),比如 log4j、 logback 和 slf4j 等等,還會接觸到日志系統(tǒng)的各種概念,比如 Formatter、Appender 和 Priority 等。這些日志系統(tǒng)有什么區(qū)別,這些概念又該怎么理解呢?

當我們在做系統(tǒng)開發(fā)時,日志系統(tǒng)是繞不開的話題。作為日志系統(tǒng)的最終使用者,我們會接觸不同的日志系統(tǒng),比如 log4j、 logback 和 slf4j 等等,還會接觸到日志系統(tǒng)的各種概念,比如 Formatter、Appender 和 Priority 等。這些日志系統(tǒng)有什么區(qū)別,這些概念又該怎么理解呢?

普通程序員怎么理解日志系統(tǒng)

 

今天我們就聊下:我們普通程序員,也就是日志系統(tǒng)最終使用者,可以怎么理解日志系統(tǒng)。

Logging 系統(tǒng)的雛型

讓我們回到計算機世界的遠古時期或者我們剛剛接觸計算機世界的時期,那個時候我們有兩種調試程序的辦法:1)單步調試,一步步地跟蹤,查看代碼中變量的值。2) 是 printf 大法 —— 在特定的地方打印日志, 通過日志的輸出,幫助快速定位。

單步調試方法費時費力,但能準確定位問題。printf 大法簡單粗暴,需要嘗試,大部分情況能快速找到問題。單步調試和 printf 方法搭配使用,相得益彰。但是單步調試止步于 gdb 等調試工具,而 printf 大法最終發(fā)展出了一系列的日志系統(tǒng)。原因就在于單步調試在程序員調試才能用,而 printf 大法可以在調試和生產線上都能用,并且輸出的日志被各方面的人利用和解讀。

什么時候打印日志是個問題 —— Level

printf 大法是很簡陋的。在調試過程中,有可能日志打到很細粒度,比如每條數據的第三個字段是什么都打印出來了,但是真正運行又要把這些細粒度的日志刪除。等到下次調試,我們又要知道每條數據的第三個字段是什么了。為此,我們希望日志打印是智能:調試或者線上出問題的時候,各種細粒度的日志全部打印出來,正常運行的時候輸出一些最簡單的信息就可以了。

針對這個問題,日志系統(tǒng)引入日志級別(Level)的辦法解決。引入日志級別的概念之后,我們編程時打印日志,需要指明這條日志的級別。由于日志級別是最重要的參數,現(xiàn)在的日志系統(tǒng)都是直接通過使用不同的函數來指明級別的,包括 logger.TRACE、logger.DEGUB、logger.INFO、logger.WARN、logger.ERROR、logger.FATAL。其中級別的對比是 TRACE < DEBUG < INFO <WARN < ERROR < FATAL。同時系統(tǒng)運行行,我們將設定 log level設置在某一個級別上,那么級別優(yōu)先級高的 log 都能打印出來,低的都不能打印出。例如,如果設置優(yōu)先級為WARN,那么FATAL、ERROR、WARN 級別的log能正常輸出,而INFO、DEBUG、TRACE 級別的log則會被忽略。

我們編程時 DEBUG 或者 TRACE 級別打出細粒度的信息,比如每條數據的樣子。當我們調試時或者線上有問題時,我們將程序的當前日志級別設置成 TRACE 或者 DEBUG,從而將細粒度的信息打出來。而正常運行時,我們將當前日志級別設置成 INFO 或者 WARN 級別,從而忽略細粒度的信息,降低 IO 操作和提升系統(tǒng)性能。

普通程序員怎么理解日志系統(tǒng)

 

打印日志到哪里是還是一個問題 —— Appender

有了 Level,我們可以隨心意寫點 log 了,只要控制好日志級別就行。默認情況下,我們的日志是打印到 Console 里,我們直接人眼看。隨著時間的推移,情況變得復雜起來。比如我們需要將日志打入文件里,方便以后查看。即使日志打到文件,我們也需要登錄到機器才能查看,我們需要在發(fā)生錯誤時收到郵件或者短信。為了滿足這些需求,我們在日志系統(tǒng)中加入 Appender 部件。Appender 部件負責將日志寫的不同的目的。

普通程序員怎么理解日志系統(tǒng)

 

比如下圖就是 Log4j 的日志配置示例。這個示例會打印出所有的信息,每次大小超過size,則這size大小的日志會自動存入按年份-月份建立的文件夾下面并進行壓縮,作為存檔。

普通程序員怎么理解日志系統(tǒng)

 

日志系統(tǒng)可以自定多種 Appender,人們基于這套邏輯發(fā)明了一套日志收集和實時檢索的系統(tǒng),也稱之為日志系統(tǒng)。在這里為了區(qū)別,我們將日志收集和檢索系統(tǒng)稱之為日志收集檢索系統(tǒng)。日志收集檢索系統(tǒng)一般有 Kafka 流、實時處理組件 Spark Streaming 或者 Storm、實時檢索系統(tǒng) ElasticSearch 組成。后臺系統(tǒng)通過日志系統(tǒng)的 Appender 組件將日志打到 Kafka 流,然后 Spark Streaming 或者 Storm 處理流數據并將之寫入 ElasticSearch 檢索系統(tǒng)。這樣開發(fā)和運維就可以在 ElasticSearch 提供的 Web 查看可視化的日志了。日志收集檢索系統(tǒng)的主要好處是,1) 日志集中管理,不需要登錄到不同機器;2) 提供可視化的日志查看;3) 提供基于日志的監(jiān)控、監(jiān)測服務等。

普通程序員怎么理解日志系統(tǒng)

 

目前最有名的日志收集檢索系統(tǒng)應該是上圖的 Splunk 了。

日志什么樣也是個問題 —— Formatter

有了日志的 Level 和 Appender,我們還需要解決日志樣式的問題。一般情況,我們希望的日志格式包括:Level,函數名,文件名和打日志的代碼行數。這可以通過日志系統(tǒng)的 Formatter 組件來實現(xiàn)的。下圖是一個 Python 自定義的Formatter。

 

  1. import logging  
  2. def AltCustomFormatter(logging.Formatter):  
  3. def __init__(self, fmt=None, datefmt=None):  
  4. super(AltCustomFormatter, self).__init__(fmt, datefmt)  
  5. def format(self, record):  
  6. # 如果你添加了多個handler,你會發(fā)現(xiàn)我們的定制消息被重復了多次,  
  7. # 我們在record里設置一個marker來避免  
  8. if record.levelno > logging.INFO and not hasattr(record, 'is_custom'):  
  9. record.msg = "[%s, %s, %s] %s" % (record.filename, record.lineno, record.funcName, record.msg)  
  10. record.is_custom = True  
  11. return super(AltCustomFormatter, self).format(record) 

 

在引入 Level、Formater 和 Appender 概念之后,整個日志系統(tǒng)的架子算是搭起來了,如下圖所示。作為一個普通程序員,可以安心使用這個日志系統(tǒng)了。

普通程序員怎么理解日志系統(tǒng)

 

高效地打印日志是另外一個問題 —— Efficient

但是作為一個有追求的普通程序,我們想知道大規(guī)模系統(tǒng)的極限環(huán)境中,日志系統(tǒng)能不能撐得住。答案嘛,是按照上面設計的日志系統(tǒng)是撐不住的。因為大規(guī)模系統(tǒng)的極限環(huán)境,實時要求高,不能忍受寫文件或者寫網絡的延遲。怎么辦呢?有請對付 IO 延遲利器 —— Buffer。基于 Buffer,并考慮到 Buffer 所帶來的線程同步的問題, 人們設計了下面的方案。在這個方案中,每個線程生成一個 Buffer,然后寫線程輪詢從 Buffer 讀入信息,并寫目的地。在這套方案中,寫日志并不會導致服務延遲。

普通程序員怎么理解日志系統(tǒng)

 

除了架構上的設計,還有一些小 trick 提高性能。比如我們在 log4j 官方 API 查到丑陋的 INFO 函數們。Java 語言不支持不定長參數的情況下,log4j 強行搞一個支持不定長的 INFO 函數,就只能靠著寫不同的函數重載,最終也只支持 9 個參數。

普通程序員怎么理解日志系統(tǒng)

 

但這些丑陋的 INFO 是有意義的。這些丑陋的 INFO 是為了能夠實現(xiàn)下表中不定長參數的方式。這種不定長參數方式相比字符串拼接方式的區(qū)別在哪里呢? 當前級別是 ERROR 時,INFO 級別的信息是不用輸出的,字符串拼接方式還是要拼字符串,而不定長參數方式就可以不用拼接字符串了。

普通程序員怎么理解日志系統(tǒng)

 

總結

上面就是日志系統(tǒng)基本概念的介紹了。從遠古時期的 printf 大法到現(xiàn)代化的日志系統(tǒng),為了讓我們普通程序員也能直觀地了解系統(tǒng)運行狀態(tài),大神們引入了 Level, Appender, Formatter 等日志系統(tǒng)核心概念,開發(fā)了 log4j, logback 和 tinylog 等著名日志系統(tǒng)。 

責任編輯:龐桂玉 來源: 今日頭條
相關推薦

2020-10-05 21:13:37

程序員技能開發(fā)者

2017-04-05 11:28:53

2017-08-11 16:40:21

2011-05-30 14:50:56

程序員

2011-03-22 10:16:48

程序員

2022-10-25 08:23:09

Reactor模式I/O

2021-02-03 13:18:02

程序員財富自由

2019-09-17 10:19:56

程序員裁員團隊

2018-01-09 20:29:15

程序員日本程序員中國程序員

2009-03-20 10:19:12

程序員編程職場

2012-09-19 09:21:59

2012-09-20 09:19:30

程序員非程序西方程序員

2014-03-27 11:10:46

程序員老程序員

2013-08-20 09:33:59

程序員

2012-03-06 09:22:46

程序員

2013-04-01 15:51:09

程序員管理

2015-03-30 15:51:29

程序員程序員面試

2012-06-08 09:57:25

2012-07-05 09:37:04

Java程序員

2009-03-13 09:10:17

點贊
收藏

51CTO技術棧公眾號