Go語言標準庫之log和三方庫zap

一、Log

1.1 logger基本使用

Go語言內置的log包實現了簡單的日志服務。本包也提供了一個預定義的“標準”logger,可以通過調用函數Print系列(Print|Printf|Println)、Fatal系列(Fatal|Fatalf|Fatalln)、和Panic系列(Panic|Panicf|Panicln)來使用,比自行創建一個logger對象更容易使用。

Fatal系列用于輸出一條致命錯誤信息,并調用 os.Exit(1) 終止程序運行。這個函數會在打印完錯誤信息之后立即調用 os.Exit 退出程序。

package mainimport ("log"
)func main() {log.Println("卡卡西的日志")x := "鳴人"log.Printf("%s的日志\n", x)log.Fatalln("會觸發fatal的日志")// 這里的代碼不會被執行,因為程序已經在 log.Fatalln 后退出了log.Panicln("會觸發panic的日志")
}
2024/05/16 23:03:24 卡卡西的日志
2024/05/16 23:03:24 鳴人的日志       
2024/05/16 23:03:24 會觸發fatal的日志
exit status 1 

1.2 logger配置

基礎的logger只提供日志的時間信息,如果需要獲取更多的信息或者輸出方式,可以通過進一步配置實現。

1.2.1 標準配置 log.SetFlags.SetFlags

  • log.SetFlags() 函數用于設置日志的輸出格式
  • log.Flags() 函數來獲取當前日志包的配置標志,并將其打印輸出。

以下是 log 包中定義的一些常用選項:

  • log.Ldate:日期:2009/01/23
  • log.Ltime:時間:01:23:23
  • log.Lmicroseconds:微秒級時間:01:23:23.123123
  • log.Llongfile:文件名和行號:/a/b/c/d.go:23
  • log.Lshortfile:文件名和行號:d.go:23
  • log.LUTC:使用 UTC 時間

下面在記錄日志之前先設置一下logger的輸出選項:

package mainimport ("fmt""log"
)func main() {log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)log.Println("卡卡西的日志")flags := log.Flags()fmt.Println("Flags:", flags)
}

輸出結果

2024/05/16 23:25:39.519510 d:/go/練習/main.go:10: 卡卡西的日志
Flags: 13

1.2.2 前綴配置 log.SetPrefix 和 log.Prefix

  • log.SetPrefix 用于設置日志輸出的前綴,它接受一個字符串作為參數,這個字符串將會作為日志信息的前綴顯示在每條日志的最前面。
  • log.Prefix 則是一個屬性,用于獲取當前日志輸出的前綴。
func main() {log.SetPrefix("復制忍者:")log.Println("卡卡西")prefix := log.Prefix()fmt.Println(prefix)
}

輸出結果是

復制忍者:2024/05/18 10:06:56 卡卡西
復制忍者:  

1.2.3 輸出位置 log.SetOutput

log.SetOutput 用于設置日志輸出的目標。這個函數接受一個 io.Writer 類型的參數,將日志輸出到指定的 io.Writer 實現。

func main() {file, err := os.OpenFile("logfile.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)if err != nil {log.Fatal("Failed to open logfile.log", err)}defer file.Close()log.SetOutput(file)log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)log.Println("卡卡西")log.SetPrefix("復制忍者:")
}

1.3 logger對象創建

log.New 用于創建一個新的 Logger 對象。這個函數接受三個參數:一個實現了 io.Writer 接口的目標輸出流、一個用于添加前綴的字符串、以及一個用于指定日志屬性的標志選項。

func main() {// 創建一個新的 Logger 對象,將日志輸出到標準錯誤輸出,并添加前綴 "ERROR: "logger := log.New(os.Stderr, "ERROR: ", log.LstdFlags)// 使用新創建的 Logger 對象輸出日志logger.Println("This is an error message.")
}

輸出結果

ERROR: 2024/05/18 10:27:40 This is an error message.

二、第三方日志庫 Zap

注意:Zap并不是Go的標準庫,而是為了解決Go內置log庫功能有限的問題,所引入的第三方日志庫。在此處介紹Zap是為了方便與log庫進行對比學習。

  • Zap的優點:快、結構化,分日志級別。

Zap 日志庫提供了兩種類型的日志記錄器:Sugared LoggerLogger。它們分別適用于不同的日志記錄場景。

  1. Sugared Logger:

    • Sugared Logger 提供了結構化和格式化的日志記錄功能,支持使用類似 Printf 風格的方法記錄日志。
    • 它使用了結構化的上下文字段,可以方便地記錄關鍵-值對形式的日志信息。
    • Sugared Logger 適合用于一般的日志記錄需求,提供了更直觀、易用的 API。
  2. Logger:

    • Logger 提供了更底層的、零分配(zero-allocation)的日志記錄功能,適用于高性能、高吞吐量的日志記錄需求。
    • 它的 API 相對更加簡潔,不支持結構化的上下文字段,但在性能方面有優勢。
    • Logger 適合用于需要盡量減少內存分配和提升性能的場景。

根據具體的需求和場景,可以選擇使用 Zap 提供的 Sugared Logger 或 Logger 來實現相應的日志記錄功能。

2.1 Logger

  1. 調用zap.NewProduction()或者zap.NewDevelopment()或者zap.Example()創建了一個 Zap 日志記錄器
  2. 通過Logger調用Info/Error等
  3. 程序結束前調用 logger.Sync() 來確保所有日志都被輸出

zap.NewProduction():會配置 Logger 以適應生產環境的需求,例如默認會將日志輸出到標準錯誤輸出,并且會禁用堆棧跟蹤等詳細的調試信息,以減少對性能的影響。適合用于生產環境中記錄穩定運行日志的場景。
zap.NewDevelopment():會配置 Logger 以便于開發過程中更好地跟蹤和調試日志,例如會輸出更詳細的調試信息和堆棧跟蹤。適合用于開發和調試過程中輔助定位問題、跟蹤日志的場景。
zap.Example():是一個示例方法,提供了一個簡單的例子,演示了如何創建 Logger 實例、記錄不同級別的日志、以及如何添加結構化的上下文字段等操作。

下面通過簡單的http get介紹logger的用法

package mainimport ("net/http""go.uber.org/zap"
)var logger *zap.Logger// 初始化日志記錄器
func InitLogger() {logger, _ = zap.NewProduction()
}// 發送 HTTP GET 請求
func httpGet(url string){resp, err := http.Get(url)if err != nil {// 如果請求中出現錯誤,記錄錯誤日志logger.Error("Error fetching url: ",zap.String("url",url),zap.Error(err))} else {// 如果請求成功,記錄成功日志logger.Info("Success: ",zap.String("statusCode", resp.Status),zap.String("url", url))resp.Body.Close()}
}func main() {InitLogger()// 使用了 defer 關鍵字來延遲執行 logger.Sync(),以確保在程序退出前執行同步操作defer logger.Sync()httpGet("https://blog.csdn.net/Ricardo2/article/details/134253323")httpGet("www.google.com")
}

輸出結果

{"level":"info","ts":1716001211.442937,"caller":"練習/main.go:26","msg":"Success: ","statusCode":"403 Forbidden","url":"https://blog.csdn.net/Ricardo2/article/details/134253323"}
{"level":"error","ts":1716001211.443463,"caller":"練習/main.go:20","msg":"Error fetching url: ","url":"www.google.com","error":"Get \"www.google.com\": unsupported protocol scheme \"\"","stacktrace":"main.httpGet\n\td:/go/練習/main.go:20\nmain.main\n\td:/go/練習/main.go:41\nruntime.main\n\tE:/goland/src/runtime/proc.go:250"}

2.2 SugaredLogger

大部分的實現基本都相同。
惟一的區別是,我們通過logger.Sugar()方法來獲取一個SugaredLogger。

package mainimport ("net/http""go.uber.org/zap"
)var sugarLogger *zap.SugaredLogger// 初始化日志記錄器
func InitLogger() {logger, _ := zap.NewProduction()sugarLogger = logger.Sugar()
}// 發送 HTTP GET 請求
func httpGet(url string){sugarLogger.Debugf("Trying to grt request for %s", url)resp, err := http.Get(url)if err != nil {// 如果請求中出現錯誤,記錄錯誤日志sugarLogger.Error("Error fetching url: ",zap.String("url",url),zap.Error(err))} else {// 如果請求成功,記錄成功日志sugarLogger.Info("Success: ",zap.String("statusCode", resp.Status),zap.String("url", url))resp.Body.Close()}
}func main() {InitLogger()// 使用了 defer 關鍵字來延遲執行 logger.Sync(),以確保在程序退出前執行同步操作defer sugarLogger.Sync()httpGet("https://blog.csdn.net/Ricardo2/article/details/134253323")httpGet("www.google.com")
}

輸出結果

{"level":"info","ts":1716001865.691326,"caller":"練習/main.go:28","msg":"Success: {statusCode 15 0 403 Forbidden <nil>} {url 15 0 https://blog.csdn.net/Ricardo2/article/details/134253323 <nil>}"}
{"level":"error","ts":1716001865.6924412,"caller":"練習/main.go:22","msg":"Error fetching url: {url 15 0 www.google.com <nil>} {error 26 0  Get \"www.google.com\": unsupported protocol scheme \"\"}","stacktrace":"main.httpGet\n\td:/go/練習/main.go:22\nmain.main\n\td:/go/練習/main.go:43\nruntime.main\n\tE:/goland/src/runtime/proc.go:250"}

2.3 日志級別

Zap 日志庫支持以下幾種日志級別,可以根據不同的需求來選擇合適的級別記錄日志:

  • Debug:
    用于記錄調試過程中的詳細信息,通常在開發和調試階段使用。
    使用 logger.Debug() 方法記錄 Debug 級別的日志。
  • Info:
    用于記錄程序運行過程中的一般信息,例如啟動信息、關鍵事件等。
    使用 logger.Info() 方法記錄 Info 級別的日志。
  • Warn:
    用于記錄可能出現問題但不會影響程序正常運行的警告信息,例如參數使用不當、潛在的問題等。
    使用 logger.Warn() 方法記錄 Warn 級別的日志。
  • Error:
    用于記錄程序中的錯誤信息,例如異常、錯誤狀態等。
    使用 logger.Error() 方法記錄 Error 級別的日志。
  • DPanic:
    用于記錄嚴重的錯誤,會導致程序進入恐慌狀態的錯誤。
    使用 logger.DPanic() 方法記錄 DPanic 級別的日志。
  • Panic:
    用于記錄導致程序無法繼續正常運行的錯誤,記錄后會觸發程序 panic。
    使用 logger.Panic() 方法記錄 Panic 級別的日志。
  • Fatal:
    用于記錄導致程序無法繼續運行的嚴重錯誤,記錄后會觸發程序退出。
    使用 logger.Fatal() 方法記錄 Fatal 級別的日志。

2.4 Zap配置

2.4.1 標準配置

下面介紹如何對Zap的日志做詳細的配置:

  • 如何寫入日志
  • 日志寫入到哪里
  • 寫入什么級別的日志

具體來說,將使用zap.New(…)方法來手動傳遞所有配置

func New(core zapcore.Core, options ...Option) *Logger

zapcore.Core 接口類型的實例,定義了日志記錄的核心功能,包括日志級別的判斷LogLevel、格式化日志消息Encoder、輸出日志的目的地WriteSyncer等。

(1)Encoder:編碼器(如何寫入日志)。我們將使用開箱即用的NewJSONEncoder(),并使用預先設置的ProductionEncoderConfig()

zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())

(2)WriterSyncer :指定日志將寫到哪里去。我們使用zapcore.AddSync()函數并且將打開的文件句柄傳進去。通過使用 AddSync 函數,可以將一個標準的 Go io.Writer 實例(比如文件、標準輸出等)包裝成一個符合 Zap 日志庫要求的 WriteSyncer 實例

file, _ := os.Create("./test.log")
writeSyncer := zapcore.AddSync(file)

(3)Log Level:哪種級別的日志將被寫入。

下面將修改上述部分中的Logger代碼,主要是重寫InitLogger()方法。

package mainimport ("net/http""os""go.uber.org/zap""go.uber.org/zap/zapcore"
)var sugarLogger *zap.SugaredLoggerfunc getEncoder() zapcore.Encoder {return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
}func getLogWriter() zapcore.WriteSyncer {file, _ := os.Create("./test.log")return zapcore.AddSync(file)
}// 初始化日志記錄器
func InitLogger() {writeSyncer := getLogWriter()encoder := getEncoder()core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)logger := zap.New(core)sugarLogger = logger.Sugar()
}// 發送 HTTP GET 請求
func httpGet(url string) {sugarLogger.Debugf("Trying to grt request for %s", url)resp, err := http.Get(url)if err != nil {// 如果請求中出現錯誤,記錄錯誤日志sugarLogger.Error("Error fetching url: ",zap.String("url", url),zap.Error(err))} else {// 如果請求成功,記錄成功日志sugarLogger.Info("Success: ",zap.String("statusCode", resp.Status),zap.String("url", url))resp.Body.Close()}
}func main() {InitLogger()// 使用了 defer 關鍵字來延遲執行 logger.Sync(),以確保在程序退出前執行同步操作defer sugarLogger.Sync()httpGet("https://blog.csdn.net/Ricardo2/article/details/134253323")httpGet("www.google.com")
}

結果是

{"level":"debug","ts":1716607412.904807,"msg":"Trying to grt request for https://blog.csdn.net/Ricardo2/article/details/134253323"}
{"level":"info","ts":1716607415.0869148,"msg":"Success: {statusCode 15 0 200 OK <nil>} {url 15 0 https://blog.csdn.net/Ricardo2/article/details/134253323 <nil>}"}
{"level":"debug","ts":1716607415.0869148,"msg":"Trying to grt request for www.google.com"}
{"level":"error","ts":1716607415.0869148,"msg":"Error fetching url: {url 15 0 www.google.com <nil>} {error 26 0  Get \"www.google.com\": unsupported protocol scheme \"\"}"}

2.4.2 修改輸出格式

NewJSONEncoder() 創建的編碼器將日志事件格式化為 JSON 格式的字符串。這種格式在日志收集系統、日志分析工具等場景中通常更易于處理和解析。
NewConsoleEncoder() 創建的編碼器將日志事件格式化為人類可讀的文本格式,通常采用一種類似于控制臺輸出的格式。這種格式適合在終端中查看日志。

func getEncoder() zapcore.Encoder {return zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig())
}

結果是

1.7166081613816104e+09	debug	Trying to grt request for https://blog.csdn.net/Ricardo2/article/details/134253323
1.7166081620810077e+09	info	Success: {statusCode 15 0 200 OK <nil>} {url 15 0 https://blog.csdn.net/Ricardo2/article/details/134253323 <nil>}
1.7166081620810077e+09	debug	Trying to grt request for www.google.com
1.7166081620815365e+09	error	Error fetching url: {url 15 0 www.google.com <nil>} {error 26 0  Get "www.google.com": unsupported protocol scheme ""}

2.4.3 修改時間展示方式

首先要覆蓋Encoder終默認的ProductionConfig(),進行手動配置:

  • 修改時間編碼器
  • 在日志文件中使用大寫字母記錄日志級別
func getEncoder() zapcore.Encoder {encoderConfig := zap.NewProductionEncoderConfig()encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoderencoderConfig.EncodeLevel = zapcore.CapitalLevelEncoderreturn zapcore.NewConsoleEncoder(encoderConfig)
}

2.4.4 增加調用者函數的信息

將在zap.New(..)函數中添加一個Option。

logger := zap.New(core, zap.AddCaller())

最后,結果是

2024-05-25T11:41:42.283+0800	DEBUG	練習/main.go:37	Trying to grt request for https://blog.csdn.net/Ricardo2/article/details/134253323
2024-05-25T11:41:43.196+0800	INFO	練習/main.go:47	Success: {statusCode 15 0 200 OK <nil>} {url 15 0 https://blog.csdn.net/Ricardo2/article/details/134253323 <nil>}
2024-05-25T11:41:43.199+0800	DEBUG	練習/main.go:37	Trying to grt request for www.google.com
2024-05-25T11:41:43.199+0800	ERROR	練習/main.go:41	Error fetching url: {url 15 0 www.google.com <nil>} {error 26 0  Get "www.google.com": unsupported protocol scheme ""}

2.4.5 將日志同時輸出到文件和終端

func getLogWriter() zapcore.WriteSyncer {file, _ := os.Create("./test.log")// 利用io.MultiWriter支持文件和終端兩個輸出目標ws := io.MultiWriter(file, os.Stdout)return zapcore.AddSync(ws)
}

2.4.6 將err日志單獨輸出到文件

將ERROR級別的日志單獨輸出到一個名為xx.err.log的日志文件中。

func InitLogger() {encoder := getEncoder()// test.log記錄全量日志logF, _ := os.Create("./test.log")c1 := zapcore.NewCore(encoder, zapcore.AddSync(logF), zapcore.DebugLevel)// test.err.log記錄ERROR級別的日志errF, _ := os.Create("./test.err.log")c2 := zapcore.NewCore(encoder, zapcore.AddSync(errF), zap.ErrorLevel)// 使用NewTee將c1和c2合并到corecore := zapcore.NewTee(c1, c2)logger = zap.New(core, zap.AddCaller())
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/15255.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/15255.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/15255.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++ 數據結構算法 學習筆記(32) -五大排序算法

C 數據結構算法 學習筆記(32) -五大排序算法 選擇算法 如下若有多個女生的身高需要做排序: 常規思維: 第一步先找出所有候選美女中身高最高的&#xff0c;與最后一個數交換 第二步再找出除最后一位美女外其它美女中的最高者&#xff0c;與倒數第二個美女交換位置 再找出除最…

k8s-pod詳解

一、Pod基本概念&#xff1a; 1.pod介紹&#xff1a; Pod是kubernetes中最小的資源管理組件&#xff0c;Pod也是最小化運行容器化應用的資源對象。一個Pod代表著集群中運行的一個進程。kubernetes中其他大多數組件都是圍繞著Pod來進行支撐和擴展Pod功能的&#xff0c;例如&am…

電賽經驗分享——賽前準備

? 大家好哇&#xff01;我是小光&#xff0c;想要成為系統架構師的嵌入式愛好者。 ?在之前的電賽中取得了省一的成績&#xff0c;本文對電賽比賽前需要準備什么做一個經驗分享。 ?感謝你的閱讀&#xff0c;不對的地方歡迎指正。 加入小光嵌入式交流群&#xff08;qq群號&…

在線人才測評在企業招聘和大學生求職中的應用場景

每年的春招秋招&#xff0c;都是畢業生們忙著找工作的季節&#xff0c;相比社招來說&#xff0c;春招秋招是每個畢業生務必重視的機會&#xff0c;大廠名企畢竟名額有限&#xff0c;如果找到自己心儀的職業崗位&#xff0c;作為畢業生就必須提前準備&#xff0c;深入了解招聘的…

五管OTA輸入極性快速判斷

做CMFB還有負反饋的時候曾經在判斷輸入輸出極性上吃了大虧&#xff0c;直接做實驗波形正確就是輸入正端&#xff0c;全差分就不用考慮這么多了 和彎折&#xff0c;形狀類似7&#xff0c;相同方向輸入正端&#xff0c;相反的就是輸入負端&#xff0c;輸出也是和輸入負端一個方向…

【NLP】人機對話

概念 機器翻譯就是用計算機把一種語言翻譯成另外一種語言的技術 機器翻譯的產生與發展 17 世紀&#xff0c;笛卡爾與萊布尼茨試圖用統一的數字代碼來編寫詞典 1930 機器腦 1933 蘇聯發明家特洛陽斯基用機械方法將一種語言翻譯為另一種語言 1946 ENIAC 誕生 1949 機器翻譯問題…

香蕉成熟度檢測YOLOV8NANO

香蕉成熟度檢測YOLOV8NANO&#xff0c;采用YOLOV8NANO訓練&#xff0c;得到PT模型&#xff0c;然后轉換成ONNX模型&#xff0c;讓OEPNCV調用&#xff0c;從而擺脫PYTORCH依賴&#xff0c;支持C。python&#xff0c;安卓開發。能檢測六種香蕉類型freshripe freshunripe overripe…

Vita-CLIP: Video and text adaptive CLIP via Multimodal Prompting

標題&#xff1a;Vita-CLIP: 通過多模態提示進行視頻和文本自適應CLIP 源文鏈接&#xff1a;https://openaccess.thecvf.com/content/CVPR2023/papers/Wasim_Vita-CLIP_Video_and_Text_Adaptive_CLIP_via_Multimodal_Prompting_CVPR_2023_paper.pdfhttps://openaccess.thecvf.…

sw布爾減

可能最有效率還是草圖邊界線,然后用草圖做分割

ue5 中ps使用記錄貼

一、快捷鍵記錄 放大圖形 ctrlalt空格 放大圖形 縮小視口 ctrl空格 ctrlD 取消選區 ctrlt縮小文字 w魔棒工具 選擇魔棒的時候把容差打開的多一點 二、案例 移動文字 在相應的圖層選擇 移動文字 修改圖片里的顏色 在通道里拷貝紅色通道&#xff0c;復制紅色通道粘貼給正常圖…

記錄Hbase出現HMaster一直初始化,日志打印hbase:meta,,1.1588230740 is NOT online問題的解決

具體錯誤 hbase:meta,,1.1588230740 is NOT online&#xff1b; state{1588230740 stateOPEN, ...... 使用 hbase 2.5.5 &#xff0c;hdfs和hbase分離兩臺服務器。 總過程 1. 問題發現 在使用HBase的程序發出無法進行插入到HBase操作日志后檢查HBase狀況。發現master節點和r…

大模型應用商業化落地關鍵:給企業帶來真實的業務價值

2024 年被很多人稱為大模型應用的元年&#xff0c;毫無疑問&#xff0c;大模型已經成為共識&#xff0c;下一步更急迫的問題也擺在了大家的面前——大模型到底能夠用在哪&#xff1f;有哪些場景能落地&#xff1f;怎么做才能創造真正的價值&#xff1f; 在剛剛過去的 AICon 全…

【排序算法】快速排序(四個版本以及兩種優化)含動圖)

制作不易&#xff0c;三連支持一下吧&#xff01;&#xff01;&#xff01; 文章目錄 前言一.快速排序Hoare版本實現二.快速排序挖坑法版本實現三.快速排序前后指針版本實現四.快速排序的非遞歸版本實現五.兩種優化總結 前言 前兩篇博客介紹了插入和選擇排序&#xff0c;這篇博…

halcon配合yolov8導出onnx模型檢測物體

1.工業上多數視覺開發都是用halcon開發的&#xff0c;halcon本身也有自己的深度學習網絡&#xff0c;至于halcon如果不使用本身的深度學習&#xff0c;使用其他網絡導出的onnx模型怎樣配合使用&#xff1f;本文基于yolov8寫一個列子。 2。創建輸入數據的轉換代碼 #region 創建輸…

Nginx高可用性架構:實現負載均衡與故障轉移的探索

隨著網絡應用的不斷發展和用戶訪問量的增長&#xff0c;如何確保系統的高可用性、實現負載均衡以及快速響應故障轉移成為了每個運維和開發團隊必須面對的挑戰。Nginx作為一款高性能的HTTP和反向代理服務器&#xff0c;憑借其強大的功能和靈活的配置&#xff0c;成為了實現這些目…

題目:填空練習(指向指針的指針)

題目&#xff1a;填空練習&#xff08;指向指針的指針&#xff09; There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about …

【bugfix】/usr/local/bin/docker-compose:行1: html: 沒有那個文件或目錄

前言 在使用 docker-compose 管理容器化應用時&#xff0c;偶爾會遇到一些意想不到的錯誤&#xff0c;比如當嘗試運行 docker-compose 命令時&#xff0c;終端非但沒有展示預期的輸出&#xff0c;反而出現類似網頁錯誤的信息。這類問題通常與 docker-compose 的安裝或配置有關…

首都師范大學聘請旅美經濟學家向凌云為客座教授

2024年4月17日&#xff0c;首都師范大學客座教授聘任儀式在首都師范大學資源環境與旅游學院舉行。首都師范大學資源環境與旅游學院院長呂拉昌主持了儀式&#xff0c;并為旅美經濟學家向凌云教授頒發了聘書。 呂拉昌院長指出&#xff0c;要貫徹教育部產學研一體化戰略&#xff0…

數據庫工具類

public interface DbMapper {/*** 查詢數據庫類型*/String queryDbType(); }<select id"queryDbType" resultType"java.lang.String">select<choose><when test"_databaseId mysql">mysql</when><when test"_d…

虛擬機Centos擴展磁盤空間

虛擬機空間&#xff1a;現sda大小20G&#xff0c;因課程需要擴容 在虛擬機擴容中&#xff0c; 新增一塊硬盤 和 直接在原有硬盤基礎上擴容是一樣的&#xff08;只不過在原有硬盤上擴容需要關機才可以執行&#xff09;&#xff1b; 但兩者都最好先做數據備份或快照&#xff0c…