Ir al proyecto de registro de idioma (catorce)

Entrada del diario

Análisis de requisitos de la biblioteca de registro

  • Fondo generado por la biblioteca de registro

    • El programa en ejecución es una caja negra
    • El registro es una manifestación fuera del programa.
    • A través del registro, puede conocer el estado de salud del programa.
  • Nivel de impresión de registro

    • Depuración: el registro es el más detallado y tiene un mayor impacto en el programa
    • Rastreo: usado para rastrear el problema
    • Información: información más importante, como registros de acceso
    • Advertir: registro de advertencia que indica que hay un problema con el programa
    • Error: registro de errores, errores que ocurrieron al ejecutar el programa
    • Fatal: registro de errores fatales
  • Ubicación de almacenamiento de registro

    • Salida directa a la consola.
    • Imprimir en archivo
    • Imprima directamente a la red, como kafka
  • Por qué usar interfaces

    • Definir los estándares o especificaciones de la biblioteca de registros.
    • Fácil de expandir
    • Facilita el mantenimiento del programa.
  • Diseño de biblioteca de registro.
    • Imprimir registros de varios niveles
    • Establecer nivel
    • Constructor

Diseño de interfaz de biblioteca de registro

clase base log_base.go

package xlog

import (
   "fmt"
   "os"
   "path/filepath"
   "time"
)

type LogData struct {
   timeStr  string
   levelStr string
   module   string
   filename string
   funcName string
   lineNo   int
   data     string
}

type XLogBase struct {
   level   int
   module  string
}

func (l *XLogBase) writeLog(file *os.File,logData *LogData) {
   fmt.Fprintf(file,"%s %s %s (%s:%s:%d) %s\n",
      logData.timeStr, logData.levelStr, logData.module,
      logData.filename, logData.funcName, logData.lineNo, logData.data)
}

func (l *XLogBase) formatLogger(level int, module, format string, args ...interface{}) *LogData {
   now := time.Now()
   timeStr := now.Format("2006-01-02 15:04:05.000")
   levelStr := getLevelStr(level)
   filename, funcName, lineNo := GetLineInfo(3)
   filename = filepath.Base(filename)
   data := fmt.Sprintf(format, args...)
   //fmt.Printf("%s %s %s (%s:%s:%d) %s\n",timeStr,leveStr,module,filename,funcName,lineNo,data)
   return &LogData{
      timeStr:  timeStr,
      levelStr: levelStr,
      module:   module,
      filename: filename,
      funcName: funcName,
      lineNo:   lineNo,
      data:     data,
   }
}

log.go

package xlog

type XLog interface {
   Init() error   //文件初始化
   LogDebug(format string, args ...interface{})
   LogTrace(format string, args ...interface{})
   LogInfo(format string, args ...interface{})
   LogWarn(format string, args ...interface{})
   LogError(format string, args ...interface{})
   LogFatal(format string, args ...interface{})
   Close()
   SetLevel(level int)
}

func NewXLog(logType, level int, filename, module string) XLog {
   //定义接口
   var logger XLog
   switch logType {
   case XLogTypeFile:
      logger = NewXFile(level,filename, module)
   case XLogTypeConsole:
      logger = NewXConsole(level, module)
   default:
      logger = NewXFile(level,filename, module)
   }
   return logger
}

level.go

package xlog

const (
   XLogLevelDebug = iota
   XLogLevelTrace
   XLogLevelInfo
   XLogLevelWarn
   XLogLevelError
   XLogLevelFatal
)

const (
   XLogTypeFile = iota
   XLogTypeConsole
)

func getLevelStr(level int) string {
   switch level {
   case XLogLevelDebug:
      return "DEBUG"
   case XLogLevelTrace:
      return "TRACE"
   case XLogLevelInfo:
      return "INFO"
   case XLogLevelWarn:
      return "WARN"
   case XLogLevelError:
      return "ERROR"
   case XLogLevelFatal:
      return "FATAL"
   default:
      return "UNKNOWN"
   }
}

tool.go: Obtenga la línea donde se ejecuta el programa y el nombre de la función

package xlog

import "runtime"

func GetLineInfo(skip int) (filename, funcName string, lineNo int) {
   pc, file, line, ok := runtime.Caller(skip)
   if ok {
      fun := runtime.FuncForPC(pc)
      funcName = fun.Name()
   }
   filename = file
   lineNo = line
   return
}

Desarrollo de biblioteca de registro de archivos

package xlog

import (
   "os"
)

type XFile struct {
   *XLogBase
   filename string
   file     *os.File
}

func (c *XFile) Init() (err error) {
   c.file,err = os.OpenFile(c.filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY,0755)
   if err != nil {
      return
   }
   return
}

func NewXFile(level int, filename, module string) XLog {
   logger := &XFile{
      filename: filename,
   }
   logger.XLogBase = &XLogBase{
      module: module,
      level: level,
   }
   return logger
}

func (c *XFile) LogDebug(format string, args ...interface{}) {
   if c.level > XLogLevelDebug {
      return
   }
   logData := c.formatLogger(XLogLevelDebug, c.module, format, args...)
   c.writeLog(c.file,logData)
}
func (c *XFile) LogTrace(format string, args ...interface{}) {
   if c.level > XLogLevelTrace {
      return
   }
   logData := c.formatLogger(XLogLevelTrace, c.module, format, args...)
   c.writeLog(c.file,logData)
}
func (c *XFile) LogInfo(format string, args ...interface{}) {
   if c.level > XLogLevelInfo {
      return
   }
   logData := c.formatLogger(XLogLevelInfo, c.module, format, args...)
   c.writeLog(c.file,logData)
}
func (c *XFile) LogWarn(format string, args ...interface{}) {
   if c.level > XLogLevelWarn {
      return
   }
   logData := c.formatLogger(XLogLevelWarn, c.module, format, args...)
   c.writeLog(c.file,logData)
}
func (c *XFile) LogError(format string, args ...interface{}) {
   if c.level > XLogLevelError {
      return
   }
   logData := c.formatLogger(XLogLevelError, c.module, format, args...)
   c.writeLog(c.file,logData)
}
func (c *XFile) LogFatal(format string, args ...interface{}) {
   if c.level > XLogLevelFatal {
      return
   }
   logData := c.formatLogger(XLogLevelFatal, c.module, format, args...)
   c.writeLog(c.file,logData)
}

func (c *XFile) SetLevel(level int) {
   c.level = level
}

func (c *XFile)Close()  {
   if c.file != nil {
      c.file.Close()
   }
}

Desarrollo de registro de consola

package xlog

import (
   "os"
)

type XConsole struct {
   *XLogBase   //指针实现
}

func NewXConsole(level int, module string) XLog {
   logger := &XConsole{}
   //初始化指针,防止panic
   logger.XLogBase = &XLogBase{
      level: level,
      module: module,
   }
   return logger
}

//不需要初始化文件写入
func (c *XConsole)Init() error {
   return nil
}

func (c *XConsole) LogDebug(format string, args ...interface{}) {
   if c.level > XLogLevelDebug {
      return
   }
   logData := c.formatLogger(XLogLevelDebug, c.module, format, args...)
   c.writeLog(os.Stdout,logData)
}

func (c *XConsole) LogTrace(format string, args ...interface{}) {
   if c.level > XLogLevelTrace {
      return
   }
   logData := c.formatLogger(XLogLevelTrace, c.module, format, args...)
   c.writeLog(os.Stdout,logData)
}

func (c *XConsole) LogInfo(format string, args ...interface{}) {
   if c.level > XLogLevelInfo {
      return
   }
   logData := c.formatLogger(XLogLevelInfo, c.module, format, args...)
   c.writeLog(os.Stdout,logData)
}

func (c *XConsole) LogWarn(format string, args ...interface{}) {
   if c.level > XLogLevelWarn {
      return
   }
   logData := c.formatLogger(XLogLevelWarn, c.module, format, args...)
   c.writeLog(os.Stdout,logData)
}

func (c *XConsole) LogError(format string, args ...interface{}) {
   if c.level > XLogLevelError {
      return
   }
   logData := c.formatLogger(XLogLevelError, c.module, format, args...)
   c.writeLog(os.Stdout,logData)
}

func (c *XConsole) LogFatal(format string, args ...interface{}) {
   if c.level > XLogLevelFatal {
      return
   }
   logData := c.formatLogger(XLogLevelFatal, c.module, format, args...)
   c.writeLog(os.Stdout,logData)
}
func (c *XConsole) SetLevel(level int) {
   c.level = level
}

func (c *XConsole) Close() {}

Registro de uso y pruebas

xlog_example / main.go

package main

import (
   "flag"
   "fmt"
   _"fmt"
   "oldBoy/day9/xlog"
)

func logic(logger xlog.XLog) {
   logger.LogDebug("dads1,user_id:%d,username:%s",12331,"sadsaf")
   logger.LogTrace("dads2")
   logger.LogInfo("dads3")
   logger.LogWarn("dads4")
   logger.LogError("sss")
   logger.LogFatal("sss")
}
/*
func testGetLine() {
   //skip =2 深度为2的调用位置,也就是main下的22行
   filename,funcName,lineNo := xlog.GetLineInfo(2)
   fmt.Printf("filename=%s,funcname=%s,linenum=%d\n",filename,funcName,lineNo)
}
 */
func main() {
   //testGetLine()
   var logTypeStr string
   flag.StringVar(&logTypeStr,"type","file","please input a logger type")
   flag.Parse()

   var logType int
   if (logTypeStr == "file") {
      logType = xlog.XLogTypeFile
   }else {
      logType = xlog.XLogTypeConsole
   }
   logger := xlog.NewXLog(logType,xlog.XLogLevelDebug,"./xlog.log","xlog_example")
   err := logger.Init()
   if err != nil {
      fmt.Printf("init error:%v\n",err)
      return
   }
   logic(logger)
}

Observaciones

  • Funciones faltantes:
    • Escritura asíncrona en disco
    • Segmentación de registro

Supongo que te gusta

Origin blog.51cto.com/13812615/2489258
Recomendado
Clasificación