zap: تمام پتانسیل ورود به سیستم را باز کنید

چکیده
ZAP یک کتابخانه ورود به سیستم بسیار سریع ، ساختار یافته و سطح ورود به سیستم است که توسط Uber ساخته شده است. مطابق با مستندات Uber – Go Zap ، این عملکرد بهتر از بسته های شبیه سازی ساختاری مشابه است و همچنین سریعتر از کتابخانه استاندارد است. تست های عملکرد خاص را می توان در GitHub یافت.
آدرس github: https://github.com/uber – go/zap
ایجاد یک نمونه
با فراخوانی zap.newproduction ()/zap.newdevelopment () یا zap.example () یک لاج ایجاد کنید. تفاوت بین این سه روش در اطلاعاتی که آنها ثبت می کنند نهفته است و پارامترها فقط می توانند از نوع رشته باشند.
// Code
var log *zap.Logger
log = zap.NewExample()
log, _ := zap.NewDevelopment()
log, _ := zap.NewProduction()
log.Debug("This is a DEBUG message")
log.Info("This is an INFO message")
// Example Output
{"level":"debug","msg":"This is a DEBUG message"}
{"level":"info","msg":"This is an INFO message"}
// Development Output
2025-01-28T00:00:00.000+0800 DEBUG development/main.go:7 This is a DEBUG message
2025-01-28T00:00:00.000+0800 INFO development/main.go:8 This is an INFO message
// Production Output
{"level":"info","ts":1737907200.0000000,"caller":"production/main.go:8","msg":"This is an INFO message"}
{"level":"info","ts":1737907200.0000000,"caller":"production/main.go:9","msg":"This is an INFO message with fields","region":["us-west"],"id":2}
مقایسه سه روش ایجاد:
- هر دو مثال و تولید از فرمت JSON برای خروجی استفاده می کنند ، در حالی که توسعه از فرم خروجی خط خط استفاده می کند.
-
توسعه
- چاپ از سطح هشدار دهنده به سمت بالا به پشته برای ردیابی.
- همیشه بسته/پرونده/خط (روش) را چاپ می کند.
- هر قسمت اضافی را در انتهای خط به عنوان یک رشته JSON اضافه می کند.
- نام سطح را در حروف بزرگ چاپ می کند.
- چاپ زمان سنج در قالب ISO8601 در میلی ثانیه را چاپ می کند.
-
تولید
- اشکال زدایی – پیام های سطح وارد نمی شوند.
- برای سوابق خطا و dpanic – سطح ، پرونده در پشته ردیابی می شود ، اما هشدار نمی دهد.
- همیشه تماس گیرنده را به پرونده اضافه می کند.
- تاریخ را با فرمت Timestamp چاپ می کند.
- نام سطح را در حروف کوچک چاپ می کند.
خروجی فرمت شده
Zap دارای دو نوع ، *zap.logger و *zap.sugaredlogger است. تنها تفاوت بین آنها این است که ما می توانیم با فراخوانی روش .sugar () از چوب اصلی ، یک SugaredLogger را بدست آوریم و سپس از SugaredLogger برای ضبط بیانیه ها در قالب PrintF استفاده کنیم ، به عنوان مثال:
var sugarLogger *zap.SugaredLogger
func InitLogger() {
logger, _ := zap.NewProduction()
sugarLogger = logger.Sugar()
}
func main() {
InitLogger()
defer sugarLogger.Sync()
sugarLogger.Errorf("Error fetching URL %s : Error = %s", url, err)
}
نوشتن به یک پرونده
به طور پیش فرض ، سیاههها به رابط کنسول برنامه چاپ می شوند. با این حال ، برای پرس و جو آسان ، سیاههها را می توان به یک پرونده نوشت. اما ما دیگر نمی توانیم از سه روش برای ایجاد موارد ذکر شده در گذشته استفاده کنیم. در عوض ، ما از zap.new () استفاده می کنیم.
package main
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
)
var log *zap.Logger
func main() {
writeSyncer, _ := os.Create("./info.log") // Log file storage directory
encoderConfig := zap.NewProductionEncoderConfig() // Specify time format
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
encoder := zapcore.NewConsoleEncoder(encoderConfig) // Get the encoder, NewJSONEncoder() outputs in JSON format, NewConsoleEncoder() outputs in plain text format
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel) // The third and subsequent parameters are the log levels for writing to the file. In ErrorLevel mode, only error - level logs are recorded.
log = zap.New(core,zap.AddCaller()) // AddCaller() is used to display the file name and line number.
log.Info("hello world")
log.Error("hello world")
}
// Log file output result:
2025-01-28T00:00:00.000+0800 INFO geth/main.go:18 hello world
2025-01-28T00:00:00.000+0800 ERROR geth/main.go:19 hello world
خروجی به کنسول و پرونده
اگر نیاز به خروجی به کنسول و پرونده دارید ، فقط باید zapcore.newcore را اصلاح کنید. مثال:
package main
import (
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
)
var log *zap.Logger
func main() {
// Get the encoder, NewJSONEncoder() outputs in JSON format, NewConsoleEncoder() outputs in plain text format
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // Specify time format
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
encoder := zapcore.NewConsoleEncoder(encoderConfig)
// File writeSyncer
fileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
Filename: "./info.log", // Log file storage directory
MaxSize: 1, // File size limit, unit MB
MaxBackups: 5, // Maximum number of retained log files
MaxAge: 30, // Number of days to retain log files
Compress: false, // Whether to compress
})
fileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(fileWriteSyncer,zapcore.AddSync(os.Stdout)), zapcore.DebugLevel) // The third and subsequent parameters are the log levels for writing to the file. In ErrorLevel mode, only error - level logs are recorded.
log = zap.New(fileCore, zap.AddCaller()) // AddCaller() is used to display the file name and line number.
log.Info("hello world")
log.Error("hello world")
}
تقسیم پرونده
پرونده های ورود به سیستم با گذشت زمان بزرگتر می شوند. برای جلوگیری از پر کردن فضای دیسک سخت ، پرونده های ورود به سیستم با توجه به شرایط خاص باید تقسیم شوند. بسته ZAP به خودی خود عملکردی را ارائه نمی دهد ، اما می توان با استفاده از بسته Lumberjack که توسط ZAP توصیه می شود ، انجام شود.
// File writeSyncer
fileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
Filename: "./info.log", // Log file storage directory. If the folder does not exist, it will be created automatically.
MaxSize: 1, // File size limit, unit MB
MaxBackups: 5, // Maximum number of retained log files
MaxAge: 30, // Number of days to retain log files
Compress: false, // Whether to compress
})
نوشتن به پرونده ها بر اساس سطح
برای راحتی پرس و جو پرسنل مدیریت ، به طور کلی ، ما باید سیاهههای مربوط به زیر سطح خطا را در info.log قرار دهیم و در سطح خطا و در بالا به پرونده error.log وارد شوید. ما فقط باید پارامتر سوم روش zapcore.newcore را اصلاح کنیم و سپس پرونده Writesyncer را به اطلاعات و خطا تقسیم کنیم. مثال:
package main
import (
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
)
var log *zap.Logger
func main() {
var coreArr []zapcore.Core
// Get the encoder
encoderConfig := zap.NewProductionEncoderConfig() // NewJSONEncoder() outputs in JSON format, NewConsoleEncoder() outputs in plain text format
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // Specify time format
encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder // Display different colors according to levels. If not needed, use zapcore.CapitalLevelEncoder.
//encoderConfig.EncodeCaller = zapcore.FullCallerEncoder // Display the full file path
encoder := zapcore.NewConsoleEncoder(encoderConfig)
// Log levels
highPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool{ // Error level
return lev >= zap.ErrorLevel
})
lowPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { // Info and debug levels, debug level is the lowest
return lev < zap.ErrorLevel && lev >= zap.DebugLevel
})
// Info file writeSyncer
infoFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
Filename: "./log/info.log", // Log file storage directory. If the folder does not exist, it will be created automatically.
MaxSize: 1, // File size limit, unit MB
MaxBackups: 5, // Maximum number of retained log files
MaxAge: 30, // Number of days to retain log files
Compress: false, // Whether to compress
})
infoFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(infoFileWriteSyncer,zapcore.AddSync(os.Stdout)), lowPriority) // The third and subsequent parameters are the log levels for writing to the file. In ErrorLevel mode, only error - level logs are recorded.
// Error file writeSyncer
errorFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
Filename: "./log/error.log", // Log file storage directory
MaxSize: 1, // File size limit, unit MB
MaxBackups: 5, // Maximum number of retained log files
MaxAge: 30, // Number of days to retain log files
Compress: false, // Whether to compress
})
errorFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(errorFileWriteSyncer,zapcore.AddSync(os.Stdout)), highPriority) // The third and subsequent parameters are the log levels for writing to the file. In ErrorLevel mode, only error - level logs are recorded.
coreArr = append(coreArr, infoFileCore)
coreArr = append(coreArr, errorFileCore)
log = zap.New(zapcore.NewTee(coreArr...), zap.AddCaller()) // zap.AddCaller() is used to display the file name and line number and can be omitted.
log.Info("hello info")
log.Debug("hello debug")
log.Error("hello error")
}
پس از چنین اصلاح ، اطلاعات و اشکال زدایی – گزارش های سطح در info.log ذخیره می شوند ، و خطا – گزارش های سطح به طور جداگانه در پرونده error.log ذخیره می شوند.
نمایش رنگ در کنسول براساس سطح
فقط رمزگذاری رمزگذار را مشخص کنید.
// Get the encoder
encoderConfig := zap.NewProductionEncoderConfig() // NewJSONEncoder() outputs in JSON format, NewConsoleEncoder() outputs in plain text format
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // Specify time format
encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder // Display different colors according to levels. If not needed, use zapcore.CapitalLevelEncoder.
encoder := zapcore.NewConsoleEncoder(encoderConfig)
نمایش مسیر فایل و شماره خط
همانطور که قبلاً ذکر شد ، برای نمایش مسیر فایل و شماره خط ، کافی است پارامتر zap.addcaller () را به روش zap.new اضافه کنید. اگر می خواهید مسیر کامل را نمایش دهید ، باید آن را در پیکربندی رمزگذار مشخص کنید.
// Get the encoder
encoderConfig := zap.NewProductionEncoderConfig() // NewJSONEncoder() outputs in JSON format, NewConsoleEncoder() outputs in plain text format
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // Specify time format
encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder // Display different colors according to levels. If not needed, use zapcore.CapitalLevelEncoder.
encoderConfig.EncodeCaller = zapcore.FullCallerEncoder // Display the full file path
encoder := zapcore.NewConsoleEncoder(encoderConfig)
رمز کامل
package main
import (
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
)
var log *zap.Logger
func main() {
var coreArr []zapcore.Core
// Get the encoder
encoderConfig := zap.NewProductionEncoderConfig() // NewJSONEncoder() outputs in JSON format, NewConsoleEncoder() outputs in plain text format
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // Specify time format
encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder // Display different colors according to levels. If not needed, use zapcore.CapitalLevelEncoder.
//encoderConfig.EncodeCaller = zapcore.FullCallerEncoder // Display the full file path
encoder := zapcore.NewConsoleEncoder(encoderConfig)
// Log levels
highPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool{ // Error level
return lev >= zap.ErrorLevel
})
lowPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { // Info and debug levels, debug level is the lowest
return lev < zap.ErrorLevel && lev >= zap.DebugLevel
})
// Info file writeSyncer
infoFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
Filename: "./log/info.log", // Log file storage directory. If the folder does not exist, it will be created automatically.
MaxSize: 2, // File size limit, unit MB
MaxBackups: 100, // Maximum number of retained log files
MaxAge: 30, // Number of days to retain log files
Compress: false, // Whether to compress
})
infoFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(infoFileWriteSyncer,zapcore.AddSync(os.Stdout)), lowPriority) // The third and subsequent parameters are the log levels for writing to the file. In ErrorLevel mode, only error - level logs are recorded.
// Error file writeSyncer
errorFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{
Filename: "./log/error.log", // Log file storage directory
MaxSize: 1, // File size limit, unit MB
MaxBackups: 5, // Maximum number of retained log files
MaxAge: 30, // Number of days to retain log files
Compress: false, // Whether to compress
})
errorFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(errorFileWriteSyncer,zapcore.AddSync(os.Stdout)), highPriority) // The third and subsequent parameters are the log levels for writing to the file. In ErrorLevel mode, only error - level logs are recorded.
coreArr = append(coreArr, infoFileCore)
coreArr = append(coreArr, errorFileCore)
log = zap.New(zapcore.NewTee(coreArr...), zap.AddCaller()) // zap.AddCaller() is used to display the file name and line number and can be omitted.
log.Info("hello info")
log.Debug("hello debug")
log.Error("hello error")
}
سرانجام ، من می خواهم بهترین بستر را برای استقرار خدمات Golang: Leapcell توصیه کنم
1. پشتیبانی چند – زبان
- با JavaScript ، Python ، Go یا Rust توسعه دهید.
5. پروژه های نامحدود را به صورت رایگان مستقر کنید
- فقط برای استفاده پرداخت کنید – بدون درخواست ، بدون هزینه.
3. راندمان هزینه بی نظیر
- پرداخت – به عنوان – شما – بدون هزینه بیکار بروید.
- مثال: 25 دلار از درخواست های 6.94M در زمان پاسخ متوسط 60ms پشتیبانی می کند.
4. تجربه توسعه دهنده ساده
- UI بصری برای راه اندازی بی دردسر.
- خطوط لوله CI/CD کاملاً خودکار و ادغام GITOPS.
- معیارهای واقعی – زمان و ورود به سیستم برای بینش های عملی.
5. مقیاس پذیری بی دردسر و عملکرد بالا
- خودکار – مقیاس گذاری برای رسیدگی به همزمانی بالا با سهولت.
- صفر سربار عملیاتی – فقط روی ساختمان تمرکز کنید.
در اسناد بیشتر کاوش کنید!
توییتر Leapcell: https://x.com/leapcellhq