教你用Golang寫一個 color 日志庫

BelleAlmeid 7年前發布 | 18K 次閱讀 Go語言 Google Go/Golang開發

前言

在計算機里面,ansi轉義碼是使用帶內信號去控制格式化,顏色,或者其他的輸出選項在視頻流或者文本終端中的一種辦法。編碼這些格式化信息,就是在確定的字節序列中,把上述所說的ansi碼嵌入到這個文本中。終端會去尋找命令去解釋這些字符,而不是把它看作簡單的字符碼(ascii)。

1970年提出的ansi碼,但是直到1980年的早期才普及在了迷你主機和大型機房中。它被使用在早期的電子公告板上,對比之前缺乏光標移動的系統,它改善了顯示的效果,這導致了它被廣泛的使用。

盡管硬件文本終端,在21世紀已經日益稀少。但是不動搖ansi標準的影響。因為大部分的文本模擬器的解釋工作,至少還有相當一部分的文本存在ansi轉義序列。唯一的例外就是微軟的win32 console。不過這些在微軟升級到window10之后已經被解決了。

所以這個古老的協議對我們現在的文本輸出依然是有很重要的影響。

一條小命令

echo-e"\033[1;31mI ? You \e[0m"

output:

不上圖我寫什么文檔,對吧。這條命令可以用來簡單的告白用。送給大家了。從這里我們引出了ansi對文本顏色的輸出影響,看,就是圖中字符的顏色發生了變化。利用這樣的性質我們今天就要分享一下如何寫一個彩色的日子庫(color log)

CSI

轉義序列使用ESC控制字符開始,對于2個字符序列,第二個字符是ASCII的64到95。(@到_,還有所有大寫英文字母和[]\^),然而,序列中大多數是超過2個字符的,并以ESC控制字符和左中括號開始。序列被稱作CSI,即控制序列引導器或者控制序列啟動器的簡稱。這個序列的最后一個字符是在ASCII范圍64到126。也還有一個單字符的CSI (155/0x9B/0233)ESC[,這兩個字符序列比單個字符形式用的更多,細節參看C0和C1控制編碼。(下文會添加文檔的鏈接),使用UTF-8編碼的終端上,兩種形式都使用2字節(CSI in UTF-8 is 0xC2, 0x9B),但ESC[序列更加明了。

文本顏色

文本顏色(和SGR (Select Graphic Rendition)參數)使用CSI n1 [;n2 [; ...]] m 序列來處理,如上所示,序列中每一個n1, n2, ...就是一個SGR參數。因此,例如,你使用30~37表示前景色,40~47表示背景色。下圖是一張顏色過渡圖。

開始編碼

packageutil

import ( "fmt" "time" )

const ( color_red=uint8(iota+ 91) color_green color_yellow color_blue color_magenta//洋紅

info= "[INFO]" trac= "[TRAC]" erro= "[ERRO]" warn= "[WARN]" succ= "[SUCC]" )

// see complete color rules in document in https://en.wikipedia.org/wiki/ANSI_escape_code#cite_note-ecma48-13 funcTrace(formatstring,a...interface{}) { prefix:=yellow(trac) fmt.Println(formatLog(prefix),fmt.Sprintf(format,a...)) }

funcInfo(formatstring,a...interface{}) { prefix:=blue(info) fmt.Println(formatLog(prefix),fmt.Sprintf(format,a...)) }

funcSuccess(formatstring,a...interface{}) { prefix:=green(succ) fmt.Println(formatLog(prefix),fmt.Sprintf(format,a...)) }

funcWarning(formatstring,a...interface{}) { prefix:=magenta(warn) fmt.Println(formatLog(prefix),fmt.Sprintf(format,a...)) }

funcError(formatstring,a...interface{}) { prefix:=red(erro) fmt.Println(formatLog(prefix),fmt.Sprintf(format,a...)) }

func red(sstring) string { returnfmt.Sprintf("\x1b[%dm%s\x1b[0m",color_red,s) }

func green(sstring) string { returnfmt.Sprintf("\x1b[%dm%s\x1b[0m",color_green,s) }

func yellow(sstring) string { returnfmt.Sprintf("\x1b[%dm%s\x1b[0m",color_yellow,s) }

func blue(sstring) string { returnfmt.Sprintf("\x1b[%dm%s\x1b[0m",color_blue,s) }

func magenta(sstring) string { returnfmt.Sprintf("\x1b[%dm%s\x1b[0m",color_magenta,s) }

func formatLog(prefixstring) string { returntime.Now().Format("2006/01/02 15:04:05") + " " +prefix+ " " } </code></pre>

上面就是一個完整的彩色log的代碼

輸出的效果:

完整代碼

完整的colorlog代碼 測試代碼 如果你需要在本地測試,請確保你搭建了正確的go開發環境,并且down下 https://github.com/liyu4/chill 這個項目。找到util單元

yourpath指的是你的項目路徑。
cd yourpath/chill/util
go test-v

后記

在其中 \x1b[ 實現CSI:

轉換前景色為黑色,使用\x1b[30m

轉換為紅色,使用\x1b[31m

如果使用加粗參數,灰色寫作\x1b[30;1m

獲取紅色加粗,使用\x1b[31;1m

重置顏色為缺省值,使用\x1b[39;49m (或者使用 \x1b[0m 重置所有屬性)

\033[0m 重置為正常

\033[1m 設置高亮度或加粗

\033[4m 下劃線

\033[5m 閃爍

\033[7m 反顯

\033[8m 消隱

\033[30m -- /33[37m 設置前景色

\033[40m -- /33[47m 設置背景色

控制符ESC的常用表示方法\e、\x1b(\x1B)、\033都可以

\e 指代Escape,對應八進制\033,對應十六進制\x1b

參考文檔

ansi轉義序列 中文文檔

 

來自:https://www.zybuluo.com/aliasliyu4/note/612147

 

 本文由用戶 BelleAlmeid 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!