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ファイル、ログクリアを行う