dockerのログローテーションrotateの具体的な実装
3045 ワード
type JSONFileLogger struct {
buf *bytes.Buffer //buffer
f *os.File //
mu sync.Mutex // buffer
capacity int64 //
n int //
ctx logger.Context
}
ログを書くときは、コンカレントロックで書き込みの競合を防止します
func (l *JSONFileLogger) Log(msg *logger.Message) error {
l.mu.Lock()
defer l.mu.Unlock()
timestamp, err := timeutils.FastMarshalJSON(msg.Timestamp)
if err != nil {
return err
}
err = (&jsonlog.JSONLogBytes{Log: append(msg.Line, '
'), Stream: msg.Source, Created: timestamp}).MarshalJSONBuf(l.buf)
if err != nil {
return err
}
l.buf.WriteByte('
')
_, err = writeLog(l)
return err
}
書き込みログがcapacityを超えると、ログが回転します.
func rotate(name string, n int) error {
if n < 2 {
return nil
}
for i := n - 1; i > 1; i-- {
oldFile := name + "." + strconv.Itoa(i)
replacingFile := name + "." + strconv.Itoa(i-1)
if err := backup(oldFile, replacingFile); err != nil {
return err
}
}
if err := backup(name+".1", name); err != nil {
return err
}
return nil
}
func backup(old, curr string) error {
if _, err := os.Stat(old); !os.IsNotExist(err) {
err := os.Remove(old)
if err != nil {
return err
}
}
if _, err := os.Stat(curr); os.IsNotExist(err) {
if f, err := os.Create(curr); err != nil {
return err
} else {
f.Close()
}
}
return os.Rename(curr, old)
}
ファイル名の変更によるログバックアップ
-----------------------------------------------------------------------------
自分のテストプログラム:
package main
import (
"fmt"
"math"
"os"
"strconv"
_ "syscall"
"time"
)
func main() {
rotate("./yang.txt", 5)
}
func rotate(name string, n int) error {
if n < 2 {
return nil
}
for i := n - 1; i > 1; i-- {
oldFile := name + "." + strconv.Itoa(i)
replacingFile := name + "." + strconv.Itoa(i-1)
fmt.Println(i)
fmt.Println("oldfile name:" + oldFile)
fmt.Println("replacingFile name:" + replacingFile)
if err := backup(oldFile, replacingFile); err != nil {
return err
}
}
fmt.Println("hello")
if err := backup(name+".1", name); err != nil {
return err
}
return nil
}
func backup(old, curr string) error {
if _, err := os.Stat(old); !os.IsNotExist(err) {
fmt.Println("remove old:" + old)
err := os.Remove(old)
if err != nil {
return err
}
}
if _, err := os.Stat(curr); os.IsNotExist(err) {
fmt.Println("create curee:" + curr)
if f, err := os.Create(curr); err != nil {
return err
} else {
f.Close()
}
}
fmt.Printf("change %s to %s
", curr, old)
return os.Rename(curr, old)
}
実行結果
yang.txtコンテンツは->yang.txt.1 yang.txt 1の内容はyangに移行する.txt.2 yang.txt.2コンテンツはyangに移行する.txt.3 yang.txt.3コンテンツはyangに移行する.txt.4
dockerログの回転xxx-json.logファイルはyangに相当します.txtファイル
次にyangを再作成します.txtファイルは、クリアyangに相当する.txtファイル、ログクリアを行う