feat:add zlog console

#210
This commit is contained in:
samwaf
2025-03-20 08:48:27 +08:00
parent 060c27b641
commit ee2ca70f09
9 changed files with 172 additions and 87 deletions
+13 -7
View File
@@ -19,13 +19,19 @@ import (
// zlog.Warn("hello", zap.String("name", "Kevin"), zap.Any("arbitraryObj", dummyObject))
var logger *zap.Logger
func InitZLog(releaseFlag string) {
// InitZLog 初始化zlog
func InitZLog(releaseFlag string, outputFormat string) {
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoder := zapcore.NewJSONEncoder(encoderConfig)
//file, _ := os.OpenFile("/tmp/test.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 644)
//fileWriteSyncer = zapcore.AddSync(file)
var encoder zapcore.Encoder
if outputFormat == "json" {
encoder = zapcore.NewJSONEncoder(encoderConfig)
} else { // 默认使用控制台格式
consoleConfig := zap.NewDevelopmentEncoderConfig()
consoleConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
consoleConfig.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000")
encoder = zapcore.NewConsoleEncoder(consoleConfig)
}
fileWriteSyncer := getFileLogWriter()
if releaseFlag == "false" {
@@ -51,8 +57,8 @@ func getFileLogWriter() (writeSyncer zapcore.WriteSyncer) {
exeDir := ""
// 检测环境变量是否存在
envVar := "SamWafIDE"
if value, exists := os.LookupEnv(envVar); exists {
fmt.Println("当前在IDE,环境变量" + value)
if _, exists := os.LookupEnv(envVar); exists {
//fmt.Println("当前在IDE,环境变量" + value)
exeDir = "."
} else {
exePath, err := os.Executable()
+2
View File
@@ -5,3 +5,5 @@ notice:
isenable: false
soft_id: SamWafCom
user_code: 8ad2bca0-4fd0-46aa-afe6-833132a05eee
zlog:
outputformat: console
+23 -20
View File
@@ -52,26 +52,29 @@ var (
*/
GWAF_MEASURE_PROCESS_DEQUEENGINE cache.WafOnlyLockWriteData //遥测数据-队列处理时间
GWAF_GLOBAL_HOST_NAME string = "全局网站:0" //全局网站
GWAF_GLOBAL_HOST_CODE string = "0" //全局网站代码
GWAF_LOCAL_DB *gorm.DB //通用本地数据库,尊重用户隐私
GWAF_LOCAL_LOG_DB *gorm.DB //通用本地数据库存日志数据,尊重用户隐私
GWAF_LOCAL_STATS_DB *gorm.DB //通用本地数据库存放统计数据,尊重用户隐私
GWAF_REMOTE_DB *gorm.DB //仅当用户使用云数据库
GWAF_LOCAL_SERVER_PORT int = 26666 // 本地local端口
GWAF_LOCAL_INDEX_HTML string //本地首页HTML信息
GWAF_USER_CODE string // 当前识别号
GWAF_CUSTOM_SERVER_NAME string // 当前服务器自定义名称
GWAF_TENANT_ID string = "SamWafCom" // 当前租户ID
GWAF_RELEASE string = "false" // 当前是否为发行版
GWAF_RELEASE_VERSION_NAME string = "20241028" // 发行版的版本号名称
GWAF_RELEASE_VERSION string = "v1.0.0" // 发行版的版本号
GWAF_LAST_UPDATE_TIME time.Time // 上次时间
GWAF_LAST_TIME_UNIX int64 = 0 // 上次时间戳
GWAF_NOTICE_ENABLE bool = false // 是否开启通知
GWAF_CAN_EXPORT_DOWNLOAD_LOG bool = false //是否可以导出下载日志
GWAF_DLP dlpheader.EngineAPI // 脱敏引擎
GWAF_DLP_CONFIG string // 脱敏引擎配置数据
GWAF_GLOBAL_HOST_NAME string = "全局网站:0" //全局网站
GWAF_GLOBAL_HOST_CODE string = "0" //全局网站代码
GWAF_LOCAL_DB *gorm.DB //通用本地数据库,尊重用户隐私
GWAF_LOCAL_LOG_DB *gorm.DB //通用本地数据库存日志数据,尊重用户隐私
GWAF_LOCAL_STATS_DB *gorm.DB //通用本地数据库存放统计数据,尊重用户隐私
GWAF_REMOTE_DB *gorm.DB //仅当用户使用云数据库
GWAF_LOCAL_SERVER_PORT int = 26666 // 本地local端口
GWAF_LOCAL_INDEX_HTML string //本地首页HTML信息
GWAF_USER_CODE string // 当前识别号
GWAF_CUSTOM_SERVER_NAME string // 当前服务器自定义名称
GWAF_TENANT_ID string = "SamWafCom" // 当前租户ID
//zlog 日志相关信息
GWAF_LOG_OUTPUT_FORMAT string = "console" //zlog输出格式 控制台格式console,json格式
GWAF_RELEASE string = "false" // 当前是否为发行版
GWAF_RELEASE_VERSION_NAME string = "20241028" // 发行版的版本号名称
GWAF_RELEASE_VERSION string = "v1.0.0" // 发行版的版本号
GWAF_LAST_UPDATE_TIME time.Time // 上次时间
GWAF_LAST_TIME_UNIX int64 = 0 // 上次时间戳
GWAF_NOTICE_ENABLE bool = false // 是否开启通知
GWAF_CAN_EXPORT_DOWNLOAD_LOG bool = false //是否可以导出下载日志
GWAF_DLP dlpheader.EngineAPI // 脱敏引擎
GWAF_DLP_CONFIG string // 脱敏引擎配置数据
GWAF_OWASP *wafowasp.WafOWASP //owasp引擎
/**链聚合**/
+11 -45
View File
@@ -107,8 +107,6 @@ func NeverExit(name string, f func()) {
// run 是服务的主要逻辑
func (m *wafSystenService) run() {
//加载配置
wafconfig.LoadAndInitConfig()
// 获取当前执行文件的路径
executablePath, err := os.Executable()
if err != nil {
@@ -167,29 +165,6 @@ func (m *wafSystenService) run() {
//TODO 准备释放最新spider bot
/*// 启动一个 goroutine 来处理信号
go func() {
// 创建一个通道来接收信号
signalCh := make(chan os.Signal, 1)
// 根据操作系统设置不同的信号监听
if runtime.GOOS == "windows" {
signal.Notify(signalCh, syscall.SIGINT,os.Interrupt, syscall.SIGTERM,os.Kill)
} else { // Linux 系统
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)
}
for {
select {
case sig := <-signalCh:
fmt.Println("接收到信号:", sig)
wafsafeclear.SafeClear()
// 在这里执行你的清理操作或退出应用程序的代码
os.Exit(0)
}
}
}()*/
// 在这里编写你的服务逻辑代码
//初始化cache
global.GCACHE_WAFCACHE = cache.InitWafCache()
//初始化锁写不锁度
@@ -336,13 +311,6 @@ func (m *wafSystenService) run() {
})
}
/*withEncrypt, err :=wafreg.GenClientMachineInfoWithEncrypt()
if err != nil {
fmt.Println("获取机器码失败")
} else {
fmt.Println("机器码: ", withEncrypt)
}*/
//加载授权信息
verifyResult, info, err := wafreg.VerifyServerRegByDefaultFile()
if verifyResult {
@@ -621,10 +589,18 @@ func (m *wafSystenService) Graceful() {
}
func main() {
fmt.Println(`
==========================================
SamWaf Web Application Firewall ` + global.GWAF_RELEASE_VERSION + `
Version Name: ` + global.GWAF_RELEASE_VERSION_NAME + `
==========================================
`)
//加载配置
wafconfig.LoadAndInitConfig()
//初始化日志
zlog.InitZLog(global.GWAF_RELEASE)
if v := recover(); v != nil { // 侦测到一个恐慌
zlog.Info("主流程上被异常了")
zlog.InitZLog(global.GWAF_RELEASE, global.GWAF_LOG_OUTPUT_FORMAT)
if v := recover(); v != nil {
zlog.Error("主流程上被异常了")
}
pid := os.Getpid()
zlog.Debug("SamWaf Current PID:" + strconv.Itoa(pid))
@@ -659,11 +635,6 @@ func main() {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, os.Kill, syscall.SIGTERM)
/*_, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()*/
//doWork(ctx)
if len(os.Args) > 1 {
command := os.Args[1]
switch command {
@@ -676,13 +647,9 @@ func main() {
fmt.Printf("Samwaf has successfully executed the '%s' command.\n", command)
break
case "resetpwd": //重制密码
//加载配置
wafconfig.LoadAndInitConfig()
wafdb.InitCoreDb("")
wafdb.ResetAdminPwd()
case "resetotp": //重置安全码
//加载配置
wafconfig.LoadAndInitConfig()
wafdb.InitCoreDb("")
wafdb.ResetAdminOTP()
default:
@@ -698,7 +665,6 @@ func main() {
zlog.Info("main server not under service manager")
global.GWAF_RUNTIME_SERVER_TYPE = service.Interactive()
}
//defer wafsafeclear.SafeClear()
// 以常规方式运行
err = s.Run()
if err != nil {
+2 -4
View File
@@ -35,17 +35,15 @@ func GetExternalIp() string {
func GetCurrentDir() string {
// 检测环境变量是否存在
envVar := "SamWafIDE"
if value, exists := os.LookupEnv(envVar); exists {
zlog.Info("当前在IDE,环境变量", value)
if _, exists := os.LookupEnv(envVar); exists {
return "."
}
exePath, err := os.Executable()
if err != nil {
zlog.Error("Failed to get executable path:", err)
fmt.Println(fmt.Sprintf("Failed to get executable path:%v", err))
return ""
}
zlog.Debug("当前程序所在文件位置", exePath)
exeDir := filepath.Dir(exePath)
return exeDir
}
+19 -8
View File
@@ -1,18 +1,21 @@
package wafconfig
import (
"SamWaf/common/zlog"
"SamWaf/global"
"SamWaf/utils"
"fmt"
"github.com/denisbrodbeck/machineid"
uuid "github.com/satori/go.uuid"
"github.com/spf13/viper"
"os"
"time"
)
// 加载配置并初始化
func LoadAndInitConfig() {
zlog.Info("load config")
// 格式化当前时间为指定格式
currentTime := time.Now().Format("2006-01-02 15:04:05.000")
fmt.Printf("%s\tINFO\tload config\n", currentTime)
/**
1.如果user_code存在就使用本地的user_code
2.
@@ -21,7 +24,7 @@ func LoadAndInitConfig() {
configDir := utils.GetCurrentDir() + "/conf/"
if _, err := os.Stat(configDir); os.IsNotExist(err) {
if err := os.MkdirAll(configDir, os.ModePerm); err != nil {
zlog.Error("创建config目录失败:", err)
fmt.Printf("%s\tERROR\t创建config目录失败:%v\n", currentTime, err)
return
}
}
@@ -32,11 +35,11 @@ func LoadAndInitConfig() {
if err := config.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
zlog.Error("找不到配置文件..")
fmt.Printf("%s\tWARN\t找不到配置文件..\n", currentTime)
config.Set("local_port", global.GWAF_LOCAL_SERVER_PORT)
err = config.SafeWriteConfig()
} else {
zlog.Error("配置文件出错..")
fmt.Printf("%s\tERROR\t配置文件出错..\n", currentTime)
}
}
if config.IsSet("user_code") == false {
@@ -84,10 +87,18 @@ func LoadAndInitConfig() {
global.GWAF_CAN_EXPORT_DOWNLOAD_LOG = config.GetBool("export_download")
}
if config.IsSet("zlog.outputformat") {
global.GWAF_LOG_OUTPUT_FORMAT = config.GetString("zlog.outputformat")
} else {
config.Set("zlog.outputformat", global.GWAF_LOG_OUTPUT_FORMAT)
}
err := config.WriteConfig()
if err != nil {
zlog.Error("write config failed: ", err)
fmt.Printf("%s\tERROR\twrite config failed:%v\n", currentTime, err)
return
}
zlog.Info("user_code:", global.GWAF_USER_CODE)
zlog.Info("sof_id:", global.GWAF_TENANT_ID)
fmt.Printf("%s\tINFO\tuser_code:%s ,soft_id:%s\n",
currentTime, global.GWAF_USER_CODE, global.GWAF_TENANT_ID)
}
+86
View File
@@ -0,0 +1,86 @@
package wafdb
import (
"SamWaf/common/zlog"
"context"
"fmt"
"time"
"gorm.io/gorm/logger"
)
// GormZLogger 是一个实现了 gorm.Logger 接口的自定义日志记录器
type GormZLogger struct {
SlowThreshold time.Duration
IgnoreRecordNotFound bool
LogLevel logger.LogLevel
ParameterizedQueries bool
}
// NewGormZLogger 创建一个新的 GormZLogger 实例
func NewGormZLogger() *GormZLogger {
return &GormZLogger{
SlowThreshold: time.Second, // 慢查询阈值
LogLevel: logger.Info, // 默认日志级别
IgnoreRecordNotFound: true, // 忽略记录未找到错误
}
}
// LogMode 设置日志级别
func (l *GormZLogger) LogMode(level logger.LogLevel) logger.Interface {
newLogger := *l
newLogger.LogLevel = level
return &newLogger
}
// Info 打印信息日志
func (l *GormZLogger) Info(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= logger.Info {
zlog.Info(fmt.Sprintf(msg, data...))
}
}
// Warn 打印警告日志
func (l *GormZLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= logger.Warn {
zlog.Warn(fmt.Sprintf(msg, data...))
}
}
// Error 打印错误日志
func (l *GormZLogger) Error(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= logger.Error {
zlog.Error(fmt.Sprintf(msg, data...))
}
}
// Trace 记录 SQL 执行情况
func (l *GormZLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
if l.LogLevel <= logger.Silent {
return
}
elapsed := time.Since(begin)
sql, rows := fc()
// 构建日志消息,简化格式使其更加整洁
logMsg := fmt.Sprintf("SQL执行 [%.3fms] [rows:%v] %s", float64(elapsed.Nanoseconds())/1e6, rows, sql)
// 根据不同情况记录不同级别的日志
switch {
case err != nil && l.LogLevel >= logger.Error && (!l.IgnoreRecordNotFound || !isRecordNotFoundError(err)):
zlog.Error(fmt.Sprintf("SQL错误 %v %s", err, logMsg))
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= logger.Warn:
zlog.Warn(fmt.Sprintf("慢SQL %s", logMsg))
case l.LogLevel >= logger.Info:
zlog.Debug(logMsg)
}
}
// isRecordNotFoundError 检查错误是否为记录未找到错误
func isRecordNotFoundError(err error) bool {
if err == nil {
return false
}
return err.Error() == "record not found"
}
+14 -2
View File
@@ -85,10 +85,13 @@ func InitCoreDb(currentDir string) {
// 启用 WAL 模式
_ = db.Exec("PRAGMA journal_mode=WAL;")
// 创建自定义日志记录器
gormLogger := NewGormZLogger()
if global.GWAF_RELEASE == "false" && utils.CheckDebugEnvInfo() {
gormLogger = gormLogger.LogMode(logger.Info).(*GormZLogger)
// 启用调试模式
db = db.Session(&gorm.Session{
Logger: logger.Default.LogMode(logger.Info), // 设置为Info表示启用调试模式
Logger: gormLogger,
})
}
global.GWAF_LOCAL_DB = db
@@ -188,7 +191,10 @@ func InitLogDb(currentDir string) {
}
// 启用 WAL 模式
_ = db.Exec("PRAGMA journal_mode=WAL;")
// 创建自定义日志记录器
gormLogger := NewGormZLogger()
if global.GWAF_RELEASE == "false" && utils.CheckDebugEnvInfo() {
gormLogger = gormLogger.LogMode(logger.Info).(*GormZLogger)
// 启用调试模式
db = db.Session(&gorm.Session{
Logger: logger.Default.LogMode(logger.Info), // 设置为Info表示启用调试模式
@@ -250,7 +256,10 @@ func InitManaulLogDb(currentDir string, custFileName string) {
}
// 启用 WAL 模式
_ = db.Exec("PRAGMA journal_mode=WAL;")
if global.GWAF_RELEASE == "false" {
// 创建自定义日志记录器
gormLogger := NewGormZLogger()
if global.GWAF_RELEASE == "false" && utils.CheckDebugEnvInfo() {
gormLogger = gormLogger.LogMode(logger.Info).(*GormZLogger)
// 启用调试模式
db = db.Session(&gorm.Session{
Logger: logger.Default.LogMode(logger.Info), // 设置为Info表示启用调试模式
@@ -289,7 +298,10 @@ func InitStatsDb(currentDir string) {
}
// 启用 WAL 模式
_ = db.Exec("PRAGMA journal_mode=WAL;")
// 创建自定义日志记录器
gormLogger := NewGormZLogger()
if global.GWAF_RELEASE == "false" && utils.CheckDebugEnvInfo() {
gormLogger = gormLogger.LogMode(logger.Info).(*GormZLogger)
// 启用调试模式
db = db.Session(&gorm.Session{
Logger: logger.Default.LogMode(logger.Info), // 设置为Info表示启用调试模式
+2 -1
View File
@@ -10,6 +10,7 @@ import (
"errors"
"github.com/gin-contrib/pprof"
"github.com/gin-gonic/gin"
"io"
"log"
"net/http"
"strconv"
@@ -119,10 +120,10 @@ func (web *WafWebManager) cors() gin.HandlerFunc {
func (web *WafWebManager) StartLocalServer() {
if global.GWAF_RELEASE == "true" {
gin.SetMode(gin.ReleaseMode)
gin.DefaultWriter = io.Discard
}
r := gin.Default()
r.Use(web.cors()) //解决跨域
web.initRouter(r)
web.R = r