go中log日志库

callers.go

package log

import (
   "path/filepath"
   "runtime"
   "strconv"
   "strings"

   "github.com/sirupsen/logrus"
)

const (
   depth = 9
)

// CallerHook represents a caller hook of logrus
type CallerHook struct {
}

// Fire adds a callers field in logger instance
func (hook *CallerHook) Fire(entry *logrus.Entry) error {
   entry.Data["caller"] = hook.caller()
   return nil
}

// Levels returns support levels
func (hook *CallerHook) Levels() []logrus.Level {
   return []logrus.Level{
      logrus.PanicLevel,
      logrus.FatalLevel,
      logrus.ErrorLevel,
      logrus.WarnLevel,
      logrus.InfoLevel,
      logrus.DebugLevel,
   }
}

func (hook *CallerHook) caller() string {
   if _, file, line, ok := runtime.Caller(depth); ok {
      return strings.Join([]string{filepath.Base(file), strconv.Itoa(line)}, ":")
   }
   // not sure what the convention should be here
   return ""
}

log.go

package log

import (
   "data-merge-rule/util"
   "io"
   "os"

   "github.com/sirupsen/logrus"
)

var (
   defaultFormatter = &logrus.TextFormatter{
      TimestampFormat: "2006-01-02 15:04:05.000",
      FullTimestamp:   true,
   }
   defaultLevel  = "debug"
   defaultOutput = os.Stderr
)

func init() {
   SetFormatter(defaultFormatter)
   SetLevel(defaultLevel)
   SetOutput(defaultOutput)
}

// Logger wrappers access to logger instance
type Logger interface {
   Debug(args ...interface{})
   Print(args ...interface{})
   Info(args ...interface{})
   Warn(args ...interface{})
   Warning(args ...interface{})
   Error(args ...interface{})
   Panic(args ...interface{})
   Fatal(args ...interface{})

   Debugf(format string, args ...interface{})
   Printf(format string, args ...interface{})
   Infof(format string, args ...interface{})
   Warnf(format string, args ...interface{})
   Warningf(format string, args ...interface{})
   Errorf(format string, args ...interface{})
   Panicf(format string, args ...interface{})
   Fatalf(format string, args ...interface{})

   Debugln(args ...interface{})
   Println(args ...interface{})
   Infoln(args ...interface{})
   Warnln(args ...interface{})
   Warningln(args ...interface{})
   Errorln(args ...interface{})
   Panicln(args ...interface{})
   Fatalln(args ...interface{})
}

func StandardLogger() *logrus.Logger {
   return logrus.StandardLogger()
}

// New returns an standard logger or a file system logger according the filename
func New(args ...interface{}) (Logger, error) {
   if len(args) == 1 {
      if name, ok := args[0].(string); ok {
         f, err := util.OpenFile(name)
         if err != nil {
            return nil, err
         }
         SetOutput(f)
      }

   }
   return logrus.StandardLogger(), nil
}

// SetFormatter sets the standard logger formatter.
func SetFormatter(formatter logrus.Formatter) {
   logrus.SetFormatter(formatter)
}

// SetLevel sets the standard logger level.
func SetLevel(lvl string) {
   level, err := logrus.ParseLevel(lvl)
   if err != nil {
      return
   }

   if level >= logrus.DebugLevel {
      AddHook(&CallerHook{})
   }

   logrus.SetLevel(level)
}

// SetOutput sets the standard logger output.
func SetOutput(out io.Writer) {
   logrus.SetOutput(out)
}
// AddHook adds a hook to the standard logger hooks.
func AddHook(hook logrus.Hook) {
   logrus.AddHook(hook)
}
// Print logs a message at level Info on the standard logger.
func Print(args ...interface{}) {
   logrus.Print(args...)
}

// Info logs a message at level Info on the standard logger.
func Info(args ...interface{}) {
   logrus.Info(args...)
}
// Warning logs a message at level Warn on the standard logger.
func Warning(args ...interface{}) {
   logrus.Warning(args...)
}

// Error logs a message at level Error on the standard logger.
func Error(args ...interface{}) {
   logrus.Error(args...)
}

// Panic logs a message at level Panic on the standard logger.
func Panic(args ...interface{}) {
   logrus.Panic(args...)
}

// Fatal logs a message at level Fatal on the standard logger.
func Fatal(args ...interface{}) {
   logrus.Fatal(args...)
}

// Printf logs a message at level Info on the standard logger.
func Printf(format string, args ...interface{}) {
   logrus.Printf(format, args...)
}

// Infof logs a message at level Info on the standard logger.
func Infof(format string, args ...interface{}) {
   logrus.Infof(format, args...)
}
// Errorf logs a message at level Error on the standard logger.
func Errorf(format string, args ...interface{}) {
   logrus.Errorf(format, args...)
}
// Fatalf logs a message at level Fatal on the standard logger.
func Fatalf(format string, args ...interface{}) {
   logrus.Fatalf(format, args...)
}

// Println logs a message at level Info on the standard logger.
func Println(args ...interface{}) {
   logrus.Println(args...)
}

// Fatalln logs a message at level Fatal on the standard logger.
func Fatalln(args ...interface{}) {
   logrus.Fatalln(args...)
}
// Debug logs a message at level Debug on the standard logger.
func Debug(args ...interface{}) {
   logrus.Debug(args...)
}

log_store.go

package log

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

   rotatelogs "github.com/lestrrat-go/file-rotatelogs"
   "github.com/rifflock/lfshook"
   "github.com/sirupsen/logrus"
)

// InitDaysJSONRotationLogger init rotation log config with maxAgeDays and json format.
func InitDaysJSONRotationLogger(filePath, fileName string, maxAgeDays uint) error {
   const day = time.Hour * 24
   return InitRotationLogger(filePath, fileName, time.Duration(maxAgeDays)*day, day, &logrus.JSONFormatter{})
}

// InitRotationLogger init rotation log config.
func InitRotationLogger(filePath, fileName string, maxAge, rotationTime time.Duration, formatter logrus.Formatter) error {
   err := os.MkdirAll(filePath, 0700)
   if err != nil {
      return err
   }

   filePath, err = filepath.Abs(filePath + fileName)
   if err != nil {
      return err
   }

   writer, err := rotatelogs.New(
      filePath+".%Y%m%d%H%M%S",
      rotatelogs.WithLinkName(filePath),
      rotatelogs.WithMaxAge(maxAge),
      rotatelogs.WithRotationTime(rotationTime),
   )
   if err != nil {
      return err
   }

   logrus.AddHook(lfshook.NewHook(
      lfshook.WriterMap{
         logrus.DebugLevel: writer,
         logrus.InfoLevel:  writer,
         logrus.WarnLevel:  writer,
         logrus.ErrorLevel: writer,
         logrus.FatalLevel: writer,
         logrus.PanicLevel: writer,
      },
      formatter,
   ))
   return nil
}

type LogWriter struct {
   logFunc func(...interface{})
}

func (l *LogWriter) Write(p []byte) (n int, err error) {
   if l.logFunc != nil {
      l.logFunc(string(p))
   }

   return len(p), nil
}

 

io.go

package util

import (
   "bufio"
   "bytes"
   "fmt"
   "io"
)

// ReadBytes reads n bytes from reader.
func ReadBytes(reader io.Reader, n int) ([]byte, error) {
   if reader == nil || n <= 0 {
      return nil, fmt.Errorf("invalid args (%v, %v)", reader, n)
   }

   buf := make([]byte, n)
   pos := 0
   for {
      m, err := reader.Read(buf[pos:])
      if err != nil {
         if err == io.EOF {
            pos += m
            if pos < n {
               return buf[:pos], err
            }
            return buf, nil
         }
         return nil, err
      }

      pos += m
      if pos >= n {
         return buf, nil
      }
   }
}

// ForeachLine reads string from reader line-by-line.
func ForeachLine(reader io.Reader, fun func(line string) error) error {
   scanner := bufio.NewScanner(reader)
   for scanner.Scan() {
      err := fun(scanner.Text())
      if err != nil {
         return err
      }
   }
   return scanner.Err()
}

// Transformer transforms bytes.
type Transformer interface {
   Transform([]byte) ([]byte, error)
}

// CombineTransformer combines multi transformers.
type CombineTransformer []Transformer

func (ts CombineTransformer) Transform(data []byte) ([]byte, error) {
   var err error
   for i, t := range ts {
      if t == nil {
         continue
      }

      data, err = t.Transform(data)
      if err != nil {
         return nil, fmt.Errorf("perform transformer at index %d failed, %v", i, err)
      }
   }
   return data, nil
}

// The TransformFunc type is an adapter to allow the use of
// ordinary functions as Transformer.
type TransformFunc func([]byte) ([]byte, error)

func (f TransformFunc) Transform(data []byte) ([]byte, error) {
   return f(data)
}

// StringReplacer replaces string data.
type StringReplacer map[string]string

func (r StringReplacer) Transform(data []byte) ([]byte, error) {
   for old, new := range r {
      data = bytes.Replace(data, []byte(old), []byte(new), -1)
   }
   return data, nil
}

file.go

package util

import (
   "bufio"
   "fmt"
   "io/ioutil"
   "os"
)

// OpenFile opens or creates a file
// If the file already exists, open it . If it does not,
// It will create the file with mode 0644.
func OpenFile(path string) (*os.File, error) {
   f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0644)
   if err != nil {
      return nil, err
   }
   return f, err
}

// FileExist determines whether a file exists
func FileExist(filePath string) bool {
   _, err := os.Stat(filePath)
   if err != nil && os.IsNotExist(err) {
      return false
   }
   return true
}

// WriteToFile writes data to file.
func WriteToFile(d []byte, fileTo string) error {
   err := ioutil.WriteFile(fileTo, d, 0600)
   if err != nil {
      return err
   }

   return nil
}

// FileReader is buffed file reader.
type FileReader struct {
   fileName string
   *bufio.Reader
   f *os.File
}

func (r *FileReader) FileName() string {
   return r.fileName
}

func (r *FileReader) Open(name string, flag int, perm os.FileMode) error {
   f, err := os.OpenFile(name, flag, perm)
   if err != nil {
      return err
   }

   r.f = f
   r.Reader = bufio.NewReader(f)
   r.fileName = name
   return nil
}

func (r *FileReader) Close() error {
   if r.f == nil {
      return nil
   }

   err := r.f.Close()
   if err != nil {
      return err
   }

   r.f = nil
   r.Reader = nil
   r.fileName = ""
   return nil
}

// FileWriter is buffed file writer.
type FileWriter struct {
   fileName string
   *bufio.Writer
   f *os.File
}

func (w *FileWriter) FileName() string {
   return w.fileName
}

func (w *FileWriter) Open(name string, flag int, perm os.FileMode) error {
   f, err := os.OpenFile(name, flag, perm)
   if err != nil {
      return err
   }

   w.f = f
   w.Writer = bufio.NewWriter(f)
   w.fileName = name
   return nil
}

func (w *FileWriter) Close() error {
   if w.f == nil {
      return nil
   }

   err := w.Flush()
   if err != nil {
      return err
   }

   err = w.f.Close()
   if err != nil {
      return err
   }

   w.f = nil
   w.Writer = nil
   w.fileName = ""
   return nil
}

// WithOpenFile opens a file, do something, and close it.
func WithOpenFile(name string, flag int, perm os.FileMode, fun func(*os.File) error) error {
   f, err := os.OpenFile(name, flag, perm)
   if err != nil {
      return err
   }

   defer f.Close()

   return fun(f)
}

// WithReadFile opens a file for read, and close it.
func WithReadFile(name string, fun func(*bufio.Reader) error) error {
   return WithOpenFile(name, os.O_RDONLY, 0, func(f *os.File) error {
      reader := bufio.NewReader(f)
      return fun(reader)
   })
}

// WithReadFileLineByLine opens a file, reads string line-by-line.
func WithReadFileLineByLine(name string, fun func(string) error) error {
   return WithReadFile(name, func(reader *bufio.Reader) error {
      return ForeachLine(reader, fun)
   })
}

// WithWriteFile opens a file for write, and close it.
func WithWriteFile(name string, fun func(*bufio.Writer) error) error {
   return WithOpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666, func(f *os.File) error {
      writer := bufio.NewWriter(f)
      err := fun(writer)
      if err != nil {
         return err
      }
      return writer.Flush()
   })
}

// CopyFile copys and transform data.
func CopyFile(from, to string, transformers ...Transformer) error {
   data, err := ioutil.ReadFile(from)
   if err != nil {
      return fmt.Errorf("read file %s failed, %v", from, err)
   }

   data, err = CombineTransformer(transformers).Transform(data)
   if err != nil {
      return err
   }

   err = ioutil.WriteFile(to, data, 0666)
   if err != nil {
      return fmt.Errorf("write file %s failed, %v", to, err)
   }

   return nil
}
posted @ 2022-08-03 15:33  9912  阅读(106)  评论(0编辑  收藏  举报