vortexrotate

package module
v0.0.0-...-9661efb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2025 License: MIT Imports: 20 Imported by: 0

README

vortexrotate

基于Go实现的文件写入、轮转库,支持多种压缩算法、过期文件管理、复杂轮转策略。

  • 压缩算法:

    • GZIP压缩:支持压缩等级设置
           GzipBestSpeed          = gzip.BestSpeed
           GzipBestCompression    = gzip.BestCompression
           GzipDefaultCompression = gzip.DefaultCompression
           GzipHuffmanOnly        = gzip.HuffmanOnly
    
    • ZSTD压缩:默认压缩等级,gozstd.DefaultCompressionLevel
    • Snappy压缩:不支持等级设置
  • 文件轮转策略 采用复杂的文件轮转策略,实现文件大小限制和定时轮转的混合轮转策略,每次Write()都会调用轮转器来 判断是否需要执行文件轮转,不需要直接写入,需要则执行轮转。轮转器内部封装定时任务,每隔固定间隔执行判 断是否轮转,如果需要轮转则以事件的方式向通知通道发送一条轮转事件,异步goroutine接收到信号执行轮转。 定时轮转判断时需要获取到上次轮转的事件以及当前文件写入的大小,当当前文件的写入数据很少时,跳过轮转, 只有当当前文件写入超过了最大大小的80%,才可以执行轮转,防止写入轮转和定时轮转间隔过短触发的频发轮转 操作。 Write触发的轮转优先级高于定时任务,定时轮转支持的时间级别:

    Hour    TimingType = "hour"
    Day     TimingType = "day"
    Week    TimingType = "week"
    Month   TimingType = "month"

用法如下:

package main

import (
	"fmt"
	"sync"
	"time"

	vr "github.com/TimeWtr/vortexrotate"
	"golang.org/x/net/context"
	"golang.org/x/sync/semaphore"
)

func main() {
	rotate, err := vr.NewRotator("./logs",
		"testlog.log",
		// 压缩配置
		vr.WithCompress(vr.CompressTypeGzip, vr.GzipBestSpeed),
		// 轮转配置:单个文件大小限制、定时任务时间级别
		vr.WithRotate(1024*1024*3, vr.Hour),
		// 保存的最大文件数量
		vr.WithMaxCount(1024))
	if err != nil {
		panic(err)
	}
	defer rotate.Close()

	sem := semaphore.NewWeighted(100)
	template := "测试数据,需要写入文件中,当前写入编号为:%d,测试内容。。。。。。。。。。\n"
	var wg sync.WaitGroup
	for i := 0; i < 300000; i++ {
		ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
		err = sem.Acquire(ctx, 1)
		cancel()

		wg.Add(1)
		go func(idx int) {
			defer wg.Done()

			defer sem.Release(1)

			c := fmt.Sprintf(template, idx)
			_, localErr := rotate.Write([]byte(c))
			if localErr != nil {
				fmt.Println("轮转写入失败,错误:", localErr)
			}
		}(i)
	}

	wg.Wait()
}

执行结果如下图所示:

文件结果

Documentation

Index

Constants

View Source
const (
	CompressTypeUnknown = iota
	CompressTypeGzip
	CompressTypeZstd
	CompressTypeSnappy
)
View Source
const (
	GzipBestSpeed          = gzip.BestSpeed
	GzipBestCompression    = gzip.BestCompression
	GzipDefaultCompression = gzip.DefaultCompression
	GzipHuffmanOnly        = gzip.HuffmanOnly
)

Gzip压缩的等级

View Source
const (
	// DefaultPeriod 默认保存的天数,30天
	DefaultPeriod = 30
	// DefaultMaxCount 默认保存的最大文件数量,100个
	DefaultMaxCount = 100
	// DefaultMaxSize 默认单个日志文件保存的最大大小,100MB
	DefaultMaxSize = 1024 * 1024 * 100
)
View Source
const (
	ReadOnlyFile  os.FileMode = 0o444 // 只读文件
	ReadWriteFile os.FileMode = 0o644 // 读写文件
)

文件系统操作权限组

View Source
const (
	RotateSizeThreshold = 0.8
	RotateInterval      = time.Millisecond * 100
)
View Source
const Layout = "20060102"

Variables

This section is empty.

Functions

func IsNil

func IsNil(i interface{}) bool

Types

type CleanUp

type CleanUp struct {
	// contains filtered or unexported fields
}

CleanUp 根据文件最大数量来确定是否执行清理

func NewFileCountCleanUp

func NewFileCountCleanUp(dir, filename string, maxCount uint64, period uint16) *CleanUp

func (*CleanUp) ResetInterval

func (c *CleanUp) ResetInterval(newInterval time.Duration)

func (*CleanUp) Start

func (c *CleanUp) Start()

func (*CleanUp) Stop

func (c *CleanUp) Stop()

type Compress

type Compress struct {
	// contains filtered or unexported fields
}

Compress 压缩相关的配置

type CompressStrategy

type CompressStrategy interface {
	// Compress 执行压缩逻辑
	Compress() error
	// Reset 重置压缩
	Reset(w io.Writer, f *os.File)
}

CompressStrategy 压缩策略,对文件执行压缩操作

func NewGzip

func NewGzip(outFile io.Writer, f *os.File, compressLevel int) (CompressStrategy, error)

func NewSnappy

func NewSnappy(outFile io.Writer, f *os.File) CompressStrategy

func NewZstd

func NewZstd(outFile io.Writer, f *os.File, compressLevel int) CompressStrategy

type Config

type Config struct {
	// 基础文件名称
	Filename string
}

type FileInfo

type FileInfo struct {
	UpDir    string    // 父目录
	Name     string    // 文件名称
	Date     time.Time // 文件时间(年月日)
	Sequence int64     // 文件序列号
}

FileInfo 文件信息

type Gzip

type Gzip struct {
	// contains filtered or unexported fields
}

func (*Gzip) Compress

func (g *Gzip) Compress() error

func (*Gzip) Reset

func (g *Gzip) Reset(w io.Writer, f *os.File)

type MixStrategy

type MixStrategy struct {
	// contains filtered or unexported fields
}

MixStrategy 混合策略包括两个触发因子:定时和当前文件大小。 文件大小的优先级高于定时,当在一个定时的时间窗口周期内,数据写入时文件 的大小超过了最大限制,比如:100M,则立即返回需要执行轮转操作,由调用方 立即执行轮转。当定时任务达到轮转时间后,发送一条轮转事件通知到通知通道, 调用方实时监听信号,收到信号信号后执行轮转操作。每次轮转都需要记录当前轮 转的时间戳,如果是文件大小超过限制而触发的轮转,则无须进行时间判断,立即 进行轮转,如果是定时任务触发的轮转,则需要比较当前时间的时间和上次轮转的 时间的差值是否超过一定的时间范围,比如10分钟,或当前文件的写入大小是否达 到了最大大小的一定比例,比如80%,如果满足其中一条才能进行轮转操作,发送 事件通知,反之则跳过本次定时轮转。

func NewMixStrategy

func NewMixStrategy(maxSize uint64, tp TimingType) (*MixStrategy, error)

func (*MixStrategy) Close

func (s *MixStrategy) Close()

func (*MixStrategy) NotifyRotate

func (s *MixStrategy) NotifyRotate() <-chan struct{}

func (*MixStrategy) ShouldRotate

func (s *MixStrategy) ShouldRotate(writeSize uint64) bool

ShouldRotate 是否需要执行轮转操作

type OnceWithError

type OnceWithError struct {
	// contains filtered or unexported fields
}

OnceWithError 用于确保一个初始化函数只执行一次,并保存其返回的错误信息。 结构体包含一个 noCopy 字段防止拷贝,一个 sync.Once 实例保证单次执行,以及一个 error 字段保存执行结果。

func (*OnceWithError) Do

func (o *OnceWithError) Do(f func() error)

Do 方法接收一个无参数、返回 error 的函数 f。 该方法确保 f 只被执行一次,并将其返回值保存在 OnceWithError 实例的 err 字段中。 参数:

f - 初始化函数,返回一个 error。

func (*OnceWithError) Err

func (o *OnceWithError) Err() error

Err 方法用于获取 OnceWithError 实例中保存的错误信息。 返回值:

error - 初始化函数执行后保存的错误信息。

type Option

type Option func(*Rotator) error

func WithCompress

func WithCompress(tp int, level ...int) Option

WithCompress 开启压缩,压缩算法提供gzip、zstd和snappy三种算法, 当压缩算法为gzip时,可以设置压缩等级/级别,如果不设置,默认压缩级别 为gzip.DefaultCompression

func WithMaxCount

func WithMaxCount(_ uint16) Option

WithMaxCount 设置保存的最大文件数量

func WithPeriod

func WithPeriod(period uint16) Option

WithPeriod 设置保存周期

func WithRotate

func WithRotate(maxSize uint64, tp TimingType) Option

WithRotate 设置轮转配置,maxSize设置单个文件写入的最大字节,默认为100MB,当超过 限制后强制立即执行轮转,后台定时轮转的时间类型: Hour:一小时定时执行一次轮转 Day:一天定时执行一次轮转 Week:一周定时执行一次轮转 Month: 一个月定时执行一次轮转 默认定时执行的时间类型是Hour。

type RotateStrategy

type RotateStrategy interface {
	// ShouldRotate 写入文件时立即判断否应该执行文件轮转
	ShouldRotate(writeSize uint64) bool
	// NotifyRotate 获取定时轮转信号
	NotifyRotate() <-chan struct{}
	// Close 关闭轮转策略
	Close()
}

RotateStrategy 文件轮转的策略

type Rotator

type Rotator struct {
	// contains filtered or unexported fields
}

Rotator 轮转器入口,执行真正的轮转和写入操作 根据轮转策略确定是否执行轮转,轮转策略包括:根据文件大小、定时以及混合策略, 如果需要轮转,根据新的文件名称执行轮转操作。文件轮转后根据压缩策略确定是否执行压缩操作, 以及根据清除策略确定是否执行清除,过期文件的操作。

func NewRotator

func NewRotator(dir, filename string, opts ...Option) (*Rotator, error)

NewRotator 生产环境单例模式

func (*Rotator) Close

func (r *Rotator) Close()

func (*Rotator) Write

func (r *Rotator) Write(p []byte) (int, error)

Write 执行写入逻辑,判断大小是否已经达到最大大小,如果是则执行轮转逻辑 轮转后根据压缩配置执行压缩逻辑

type Snappy

type Snappy struct {
	// contains filtered or unexported fields
}

func (*Snappy) Compress

func (s *Snappy) Compress() error

func (*Snappy) Reset

func (s *Snappy) Reset(w io.Writer, f *os.File)

type TimingType

type TimingType string
const (
	Hour  TimingType = "hour"
	Day   TimingType = "day"
	Week  TimingType = "week"
	Month TimingType = "month"
)

func (TimingType) String

func (t TimingType) String() string

func (TimingType) Valid

func (t TimingType) Valid() bool

type Zstd

type Zstd struct {
	// contains filtered or unexported fields
}

func (*Zstd) Compress

func (z *Zstd) Compress() error

func (*Zstd) Reset

func (z *Zstd) Reset(w io.Writer, f *os.File)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL