代码拉取完成,页面将自动刷新
//Copyright 2017 Huawei Technologies Co., Ltd
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
// Package lager is the package for lager
package log
import (
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"time"
)
var pathReplacer *strings.Replacer
// EscapPath escape path
func EscapPath(msg string) string {
if pathReplacer == nil {
return msg
}
return pathReplacer.Replace(msg)
}
func removeFile(path string) error {
fileInfo, err := os.Stat(path)
if err != nil {
return err
}
if fileInfo.IsDir() {
return nil
}
err = os.Remove(path)
if err != nil {
return err
}
return nil
}
func removeExceededFiles(path string, baseFileName string,
maxKeptCount int, rotateStage string) {
if maxKeptCount < 0 {
return
}
var pat string
switch rotateStage {
case "rollover":
//rotated file, svc.log.20060102150405000
pat = fmt.Sprintf(`%s\.[0-9]{1,17}$`, regexp.QuoteMeta(baseFileName))
case "backup":
//backup compressed file, svc.log.20060102150405000.zip
pat = fmt.Sprintf(`%s\.[0-9]{17}\.zip$`, regexp.QuoteMeta(baseFileName))
default:
return
}
fileRegexp, err := regexp.Compile(pat)
if err != nil {
Logger.Errorf(err, "regexp.Compile: %s failed.", pat)
return
}
fileList, err := FilterFileList(path, fileRegexp)
if err != nil {
Logger.Errorf(err, "filepath.Walk() path: %s failed.", EscapPath(path))
return
}
if len(fileList) <= maxKeptCount {
return
}
sort.Strings(fileList)
//remove exceeded files, keep file count below maxBackupCount
for len(fileList) > maxKeptCount {
filePath := fileList[0]
err := removeFile(filePath)
if err != nil {
Logger.Errorf(err, "remove filePath: %s failed.", EscapPath(filePath))
break
}
//remove the first element of a list
fileList = append(fileList[:0], fileList[1:]...)
}
}
//filePath: file full path, like ${_APP_LOG_DIR}/svc.log.1
//fileBaseName: rollover file base name, like svc.log
//replaceTimestamp: whether or not to replace the num. of a rolled file
func compressFile(filePath, fileBaseName string, replaceTimestamp bool) error {
ifp, err := os.Open(filePath)
if err != nil {
return err
}
defer ifp.Close()
var zipFilePath string
if replaceTimestamp {
//svc.log.1 -> svc.log.20060102150405000.zip
zipFileBase := fileBaseName + "." + getTimeStamp() + "." + "zip"
zipFilePath = filepath.Dir(filePath) + "/" + zipFileBase
} else {
zipFilePath = filePath + ".zip"
}
zipFile, err := os.OpenFile(zipFilePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0440)
if err != nil {
return err
}
defer zipFile.Close()
zipWriter := zip.NewWriter(zipFile)
defer zipWriter.Close()
ofp, err := zipWriter.Create(filepath.Base(filePath))
if err != nil {
return err
}
_, err = io.Copy(ofp, ifp)
if err != nil {
return err
}
return nil
}
func shouldRollover(fPath string, MaxFileSize int) bool {
if MaxFileSize < 0 {
return false
}
fileInfo, err := os.Stat(fPath)
if err != nil {
Logger.Errorf(err, "state path: %s failed.", EscapPath(fPath))
return false
}
if fileInfo.Size() > int64(MaxFileSize*1024*1024) {
return true
}
return false
}
func doRollover(fPath string, MaxFileSize int, MaxBackupCount int) {
if !shouldRollover(fPath, MaxFileSize) {
return
}
timeStamp := getTimeStamp()
//absolute path
rotateFile := fPath + "." + timeStamp
err := CopyFile(fPath, rotateFile)
if err != nil {
Logger.Errorf(err, "copy path: %s failed.", EscapPath(fPath))
}
//truncate the file
f, err := os.OpenFile(fPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
if err != nil {
Logger.Errorf(err, "truncate path: %s failed.", EscapPath(fPath))
return
}
f.Close()
//remove exceeded rotate files
removeExceededFiles(filepath.Dir(fPath), filepath.Base(fPath), MaxBackupCount, "rollover")
}
func doBackup(fPath string, MaxBackupCount int) {
if MaxBackupCount <= 0 {
return
}
baseName := filepath.Base(fPath)
quoted := regexp.QuoteMeta(baseName)
pat := fmt.Sprintf(`%s\.[0-9]{1,17}$`, quoted)
fileRegexp, err := regexp.Compile(pat)
if err != nil {
Logger.Errorf(err, "regexp.Compile: %s failed.", pat)
return
}
p := fmt.Sprintf(`%s\.[0-9]{17}$`, quoted)
stampedfileRegexp, err := regexp.Compile(p)
if err != nil {
Logger.Errorf(err, "regexp.Compile: %s failed.", p)
return
}
fDir := filepath.Dir(fPath)
err = WalkFile(fDir, fileRegexp, func(file string) error {
var err error
if stampedfileRegexp.MatchString(file) {
//svc.log.20060102150405000, not replace Timestamp
err = compressFile(file, filepath.Base(fPath), false)
} else {
//svc.log.1, replace Timestamp
err = compressFile(file, filepath.Base(fPath), true)
}
if err != nil {
Logger.Errorf(err, "compress path: %s failed.", EscapPath(file))
return err
}
err = removeFile(file)
if err != nil {
Logger.Errorf(err, "remove path %s failed.", EscapPath(file))
}
return nil
}, nil)
if err != nil {
Logger.Errorf(err, "walk path: %s failed.", EscapPath(fDir))
return
}
//remove exceeded backup files
removeExceededFiles(fDir, baseName, MaxBackupCount, "backup")
}
func logRotateFile(file string, MaxFileSize int, MaxBackupCount int) {
defer func() {
if e := recover(); e != nil {
Logger.Errorf(nil, "LogRotate file path: %s catch an exception.", EscapPath(file))
}
}()
doRollover(file, MaxFileSize, MaxBackupCount)
doBackup(file, MaxBackupCount)
}
var logExtRegexp = regexp.MustCompile(`.(\.log|\.trace|\.out)$`)
// LogRotate function for log rotate
// path: where log files need rollover
// MaxFileSize: MaxSize of a file before rotate. By M Bytes.
// MaxBackupCount: Max counts to keep of a log's backup files.
func LogRotate(path string, MaxFileSize int, MaxBackupCount int) {
//filter .log .trace files
defer func() {
if e := recover(); e != nil {
err, _ := e.(error)
Logger.Errorf(err, "LogRotate catch an exception")
}
}()
err := WalkFile(path, logExtRegexp, func(file string) error {
logRotateFile(file, MaxFileSize, MaxBackupCount)
return nil
}, nil)
if err != nil {
Logger.Errorf(err, "filepath.Walk() path: %s failed.", path)
return
}
}
// FilterFileList function for filter file list
//path : where the file will be filtered
//pat : regexp pattern to filter the matched file
func FilterFileList(path string, fileRegexp *regexp.Regexp) ([]string, error) {
capacity := 10
//initialize a fileName slice, len=0, cap=10
fileList := make([]string, 0, capacity)
err := filepath.Walk(path,
func(pathName string, f os.FileInfo, e error) error {
if e != nil {
return e
}
if f.IsDir() {
return nil
}
if fileRegexp != nil && !fileRegexp.MatchString(f.Name()) {
return nil
}
fileList = append(fileList, pathName)
return nil
})
return fileList, err
}
func WalkFile(path string, fileRegexp *regexp.Regexp, onMatched func(string) error, onUnmatched func(string) error) error {
return filepath.Walk(path,
func(pathName string, f os.FileInfo, e error) error {
if e != nil {
return e
}
if f.IsDir() {
return nil
}
if fileRegexp.MatchString(f.Name()) {
if onMatched == nil {
return nil
}
return onMatched(pathName)
}
if onUnmatched == nil {
return nil
}
return onUnmatched(pathName)
})
}
// getTimeStamp get time stamp
func getTimeStamp() string {
return strings.Replace(time.Now().Format("20060102150405.000"), `.`, ``, 1)
}
// CopyFile copy file
func CopyFile(srcFile, destFile string) error {
file, err := os.Open(srcFile)
if err != nil {
return err
}
defer file.Close()
dest, err := os.Create(destFile)
if err != nil {
return err
}
defer dest.Close()
_, err = io.Copy(dest, file)
return err
}
// initLogRotate initialize log rotate
func initLogRotate(logFilePath string, c *Lager) {
if logFilePath == "" {
return
}
if c == nil {
go func() {
for {
LogRotate(filepath.Dir(logFilePath), LogRotateSize, LogBackupCount)
time.Sleep(30 * time.Second)
}
}()
return
}
c.fixed()
if c.RollingPolicy == RollingPolicySize {
go func() {
for {
LogRotate(filepath.Dir(logFilePath), c.LogRotateSize, c.LogBackupCount)
time.Sleep(30 * time.Second)
}
}()
return
}
go func() {
for {
LogRotate(filepath.Dir(logFilePath), 0, c.LogBackupCount)
time.Sleep(24 * time.Hour * time.Duration(c.LogRotateDate))
}
}()
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。