pslog

package module
v1.0.14 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2023 License: MIT Imports: 22 Imported by: 0

README

ps-log 日志分析

项目背景
  1. 开发/测试/生产环境(微服务数量在 40+ 情况下), 出现了 error log等不能被开发感知, 当反馈到开发时时间间隔较长, 如何解决?

    解决: 定时(如:10m)去解析 log 中每行包含 error 的内容, 再进行对应的处理(如: 发钉钉, 发邮件, 发es等)

  2. 定时去分析 log 吗, 需要实时感知 error log 怎么办呢?

    解决: 通过文件事件通知来感知文件变化呀, 有变化的时候就去查看文件内容呀

  3. 实时感知的文件需要起多个监听任务吗? 需要多次打开相同的文件怎么处理呢?

    解决: 不需要,只需要1个监听者,1个处理者; 可以通过池化文件句柄

介绍
go get -u gitee.com/xuesongtao/ps-log
  1. 支持 定时/实时 去解析多个 log 文件; 采集完后会根据配置进行采集位置的持久化保存(即: 文件偏移量保存), 便于停机后重启防止出现重复采集现象(注: Change 设置的比较大时, 需要注意处理重启服务时, 偏移量未保存出现的重复数据)
  2. 支持 log 行内容 多个匹配规则; 支持解析错误堆栈(即: 支持行内容合并); 匹配的内容支持不同的处理方式(支持同步/异步处理)
  3. 采用文件池将频繁使用的句柄进行缓存; 采用 tire 树缓存匹配规则提高匹配效率

简易流程图

使用
实时监听
func main() {
	ps, err := pslog.NewPsLog(pslog.WithAsync2Tos())
	if err != nil {
		panic(err)
	}
	defer ps.Close()

	// 实时监听
	if err := ps.TailLogs(); err != nil {
		panic(err)
	}

	tmp := "log/test.log"
	handler := &pslog.Handler{
		CleanOffset: true,           // 重新加载时, 清理已保存的 文件偏移量
		Change:      -1,             // 每次都保存文件偏移量
		Tail:        true,           // 实时监听
		ExpireAt:    pslog.NoExpire, // 不过期
		Targets: []*pslog.Target{
			{
				Content:  " ",        // 目标内容
				Excludes: []string{}, // 排查内容
				To:       []pslog.PsLogWriter{&pslog.Stdout{}},
			},
		},
	}

	// 注册
	if err := ps.Register(handler); err != nil {
		panic(err)
	}
	closeCh := make(chan int)
	go func() {
		fh := xfile.NewFileHandle(tmp)
		if err := fh.Initf(os.O_RDWR | os.O_APPEND | os.O_TRUNC); err != nil {
			log.Println(err)
			return
		}
		defer fh.Close()
		for i := 0; i < 10; i++ {
			time.Sleep(10 * time.Millisecond)
			_, err := fh.AppendContent(time.Now().Format(base.DatetimeFmt+".000") + " " + fmt.Sprint(i) + "\n")
			if err != nil {
				log.Println("write err:", err)
			}
		}
		close(closeCh)
	}()

	// 添加待监听的 path
	if err := ps.AddPaths(tmp); err != nil {
		panic(err)
	}

	// dump
	log.Println(ps.List())
	for range closeCh {
	}
}
其他
  • 采集服务示例: gitee

  • 欢迎大佬们指正, 希望大佬给❤️,to gitee, github

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	NoExpire = base.Datetime2TimeObj("9999-12-31 23:59:59") // 不过期
)

Functions

func PrintFilePool added in v1.0.6

func PrintFilePool(print bool)

PrintFilePool 是否打印 filePool log

func SetLogger

func SetLogger(l plg.PsLogger)

SetLogger 设置 logger

Types

type FileInfo

type FileInfo struct {
	Handler *Handler // 这里优先 PsLog.handler
	Dir     string   // 文件目录
	Name    string   // 文件名
	// contains filtered or unexported fields
}

func (*FileInfo) CleanNameFmt

func (f *FileInfo) CleanNameFmt() string

CleanNameFmt 清理 Name 中的格式, 如: test.log => test

func (*FileInfo) FileName

func (f *FileInfo) FileName() string

FileName 获取文件的全路径名

func (*FileInfo) HandlerIsNil

func (f *FileInfo) HandlerIsNil() bool

HandlerIsNil

func (*FileInfo) IsExpire

func (f *FileInfo) IsExpire(t ...time.Time) bool

IsExpire 文件是否过期

func (*FileInfo) Parse

func (f *FileInfo) Parse(path string)

Parse 解析 path

func (*FileInfo) PsLogDir added in v1.0.0

func (f *FileInfo) PsLogDir() string

PsLogDir 目录

type Handler

type Handler struct {
	LoopParse   bool          // 循环解析, 用于监听单文件日志, 说明: 这个采集的有可能不准确(在这种是基于文件大小和内存记录的偏移量做比较, 模式建议用 tail, cron 的话如果间隔时间太长就可能漏)
	CleanOffset bool          // 是否需要清理保存的 offset, 只限于开机后一次
	Tail        bool          // 是否实时处理, 说明: true 为实时; false 需要外部定时调用
	Change      int32         // 文件 offset 变化次数, 为持久化文件偏移量数阈值, 当, 说明: -1 为实时保存; 0 达到默认值 defaultHandleChange 时保存; 其他 大于后会保存
	ExpireDur   time.Duration // 文件句柄过期间隔, 常用于全局配置
	ExpireAt    time.Time     // 文件句柄过期时间, 优先 ExpireDur 如: 2022-12-03 11:11:10
	MergeRule   line.Merger   // 日志文件行合并规则, 默认 单行处理

	Targets []*Target // 目标 msg
	Ext     string    // 外部存入, 回调返回
	// contains filtered or unexported fields
}

Handler 处理的部分

func (*Handler) Valid

func (h *Handler) Valid() error

type LogDir added in v1.0.0

type LogDir struct {
	Namespace   string   // log 的命名空间
	Name        string   // 项目中 log 的目录名, 为空时, 默认 defaultLogDir
	TargetNames []string // 目标文件名
}

type LogHandlerBus added in v1.0.0

type LogHandlerBus struct {
	LogPath string // log 的路径
	Msg     string // buf 中的 string
	Ext     string // Handler 中的 Ext 值
	// contains filtered or unexported fields
}

logHandler 解析到的内容

func (*LogHandlerBus) Reset added in v1.0.0

func (l *LogHandlerBus) Reset()

func (*LogHandlerBus) Write added in v1.0.0

func (l *LogHandlerBus) Write(b []byte)

type LogPath added in v1.0.0

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

func NewLogPath added in v1.0.0

func NewLogPath() *LogPath

func (*LogPath) ParseLogPath added in v1.0.0

func (l *LogPath) ParseLogPath(project *Project) []*ProjectLog

ParseLogPaths 解析项目 log path

func (*LogPath) ParseSrc added in v1.0.0

func (l *LogPath) ParseSrc(src *ProjectSrc) []*ProjectLog

ParseSrc 收集 src 下的 go 项目, 注意: src.SrcPath 必须为绝对路径 src 目录即为项目根目录, 目录结构如下:

src ├── demo1 │ ├── app │ ├── boot │ ├── config │ ├── log │ ├── main.go └── demo2 │ ├── app │ ├── boot │ ├── config │ ├── log │ ├── main.go

func (*LogPath) SetExcludeProjectDir added in v1.0.0

func (l *LogPath) SetExcludeProjectDir(paths ...string)

SetExcludeProjectDir 设置排除的项目目录

type Matcher added in v1.0.0

type Matcher interface {
	Null() bool
	Insert(bytes []byte, target ...*Target)
	Search(target []byte) bool
	GetTarget(target []byte) (*Target, bool)
}

type Opt

type Opt func(*PsLog)

Opt

func WithAsync2Tos

func WithAsync2Tos() Opt

WithAsync2Tos 异步处理 tos

func WithCleanUpTime

func WithCleanUpTime(dur time.Duration) Opt

WithCleanUpTime 设置清理 logMap 的周期

func WithTaskPoolSize

func WithTaskPoolSize(size int, workMaxLifetimeSec ...int64) Opt

WithTaskPoolSize 设置协程池大小

type Project added in v1.0.0

type Project struct {
	LogDir      *LogDir
	ProjectPath string // 项目 path, 必须为绝对路径, 如: /root/demo/src/demo
}

Project 项目根目录

type ProjectLog added in v1.0.0

type ProjectLog struct {
	ProjectName string
	Namespace   string // log 的命名空间
	LogPath     string // 项目的 log path
}

type ProjectSrc added in v1.0.0

type ProjectSrc struct {
	LogDir  *LogDir
	SrcPath string // 根目录 path, 必须为绝对路径, 如: /root/demo/src
}

ProjectSrc 项目根目录

type PsLog

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

PsLog 解析 log

func NewPsLog

func NewPsLog(opts ...Opt) (*PsLog, error)

NewPsLog 是根据提供的 log path 进行逐行解析 注: 结束时需要调用 Close

func (*PsLog) AddPath2Handler added in v1.0.0

func (p *PsLog) AddPath2Handler(path string, handler *Handler) error

AddPath2Handler 单个添加, 如果 path 已存在则跳过, 反之新增 会根据文件对应的 Handler 进行处理, 如果为 Handler 为 nil, 会按 p.handler 来处理

func (*PsLog) AddPath2HandlerMap

func (p *PsLog) AddPath2HandlerMap(path2HandlerMap map[string]*Handler) error

AddPath2HandlerMap 添加文件对应的处理方法, 如果 path 已存在则跳过, 反之新增 会根据文件对应的 Handler 进行处理, 如果为 Handler 为 nil, 会按 p.handler 来处理

func (*PsLog) AddPaths

func (p *PsLog) AddPaths(paths ...string) error

AddPaths 添加 path, path 必须为文件全路径, 如果 path 已存在则跳过, 反之新增 根据 p.handler 进行处理

func (*PsLog) Close

func (p *PsLog) Close()

Close 释放资源

func (*PsLog) CronLogs

func (p *PsLog) CronLogs(makeUpTail ...bool)

cronLog 定时解析 log makeUpTail 标记是否补偿 tail 模式, 防止文件开启后没有变化

func (*PsLog) HasClose added in v1.0.0

func (p *PsLog) HasClose() bool

HasClose 是否已经关闭

func (*PsLog) List added in v1.0.0

func (p *PsLog) List(printTarget ...bool) string

List 返回待处理的内容 printTarget 是否打印 TARGETS, EXCLUDES(因为这两个可能会很多), 默认 true 格式: -------------------------------------------------------------------------------------- | PATH | OPEN | EXPIRE | TAIL | BEGIN | OFFSET | TARGETS | EXCLUDES | -------------------------------------------------------------------------------------- | xxxx | 2 | XXXX-XX-XX XX:XX:XX | true | 0 | 100 |【 ERRO 】| | ---------------------------------------------------------------------------------------

func (*PsLog) Register

func (p *PsLog) Register(handler *Handler) error

Register 注册处理器

func (*PsLog) ReplacePath2Handler added in v1.0.3

func (p *PsLog) ReplacePath2Handler(path string, handler *Handler) error

ReplacePath2Handler 新增文件对应的处理方法, 如果 path 已存在则替换, 反之新增 会根据文件对应的 Handler 进行处理, 如果为 Handler 为 nil, 会按 p.handler 来处理

func (*PsLog) TailLogs

func (p *PsLog) TailLogs(watchChSize ...int) error

TailLogs 实时解析 log watchSize 为监听到文件变化处理数据的 chan 的长度, 建议为监听文件的个数

type PsLogWriter added in v1.0.0

type PsLogWriter interface {
	WriteTo(bus *LogHandlerBus)
}

type Simple added in v1.0.0

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

Simple 简单匹配

func (*Simple) GetTarget added in v1.0.0

func (s *Simple) GetTarget(target []byte) (*Target, bool)

func (*Simple) Insert added in v1.0.0

func (s *Simple) Insert(bytes []byte, target ...*Target)

func (*Simple) Null added in v1.0.0

func (s *Simple) Null() bool

func (*Simple) Search added in v1.0.0

func (s *Simple) Search(target []byte) bool

type Stdout added in v1.0.0

type Stdout struct{}

func (*Stdout) WriteTo added in v1.0.0

func (p *Stdout) WriteTo(bus *LogHandlerBus)

type Target

type Target struct {
	Content string // 目标内容

	Excludes []string      // 排除 msg
	To       []PsLogWriter // 一个目标内容, 多种处理方式
	// contains filtered or unexported fields
}

Target 目标内容

type Tire added in v1.0.0

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

字典树

func (*Tire) GetTarget added in v1.0.0

func (t *Tire) GetTarget(target []byte) (*Target, bool)

GetTarget 获取 target

func (*Tire) Insert added in v1.0.0

func (t *Tire) Insert(bytes []byte, target ...*Target)

Insert 新增模式串

func (*Tire) Null added in v1.0.0

func (t *Tire) Null() bool

null 是否为空

func (*Tire) Search added in v1.0.0

func (t *Tire) Search(target []byte) bool

Search 查询主串

type Watch

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

Watch 监听的文件

func NewWatch

func NewWatch() (*Watch, error)

NewWatch 监听

func (*Watch) Add

func (w *Watch) Add(paths ...string) error

Add 添加待 watch 的路径 说明:

  1. 自动去重
  2. paths 中可以为目录和文件
  3. 建议使用绝对路径

func (*Watch) Close

func (w *Watch) Close()

Close

func (*Watch) Remove

func (w *Watch) Remove(paths ...string) error

Remove 移除待 watch 的路径

func (*Watch) Watch

func (w *Watch) Watch(busCh chan *WatchFileInfo)

Watch 文件异步监听

func (*Watch) WatchList

func (w *Watch) WatchList() string

WatchList 查询监听的所有 path 格式: ---------------------- | WATCH-PATH | DIR | ---------------------- | xxxx | true | -----------------------

type WatchFileInfo

type WatchFileInfo struct {
	IsDir bool   // 是否为目录
	Path  string // 原始添加的文件路径, 这里可能是文件路径或目录路径
}

WatchFileInfo

Directories

Path Synopsis
_example

Jump to

Keyboard shortcuts

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