Thanos源码专题【左扬精讲】——Thanos Tools 组件(release-0.26)源码阅读和分析(详解 cmd/tools.go)

Thanos Tools 组件(release-0.26)源码阅读和分析(详解 cmd/tools.go)

https://github.com/thanos-io/thanos/blob/v0.26.0/cmd/thanos/tools.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright (c) The Thanos Authors.
// Licensed under the Apache License 2.0.
 
package main
 
import (
    "os"
    "path/filepath"
 
    "github.com/go-kit/log"
    "github.com/go-kit/log/level"
    "github.com/oklog/run"
    "github.com/opentracing/opentracing-go"
    "github.com/pkg/errors"
    "github.com/prometheus/client_golang/prometheus"
 
    "github.com/thanos-io/thanos/pkg/errutil"
    "github.com/thanos-io/thanos/pkg/extkingpin"
    "github.com/thanos-io/thanos/pkg/rules"
)
 
type checkRulesConfig struct {
    rulesFiles []string
}
 
// registerTools 注册各种工具命令到给定的应用实例中
//
// 参数:
//
//  app:指向extkingpin.App类型的指针,表示需要注册命令的应用实例
func registerTools(app *extkingpin.App) {
    // 创建一个名为"tools"的命令,描述为"Tools utility commands"
    cmd := app.Command("tools", "Tools utility commands")
 
    // 注册Bucket相关的命令
    registerBucket(cmd)
    // 注册CheckRules相关的命令
    registerCheckRules(cmd)
}
 
// registerFlag 注册一个名为 "rules" 的命令行标志,并返回 tc 对象
// 参数:
// cmd - extkingpin.FlagClause 类型,表示命令行标志的上下文
// 返回值:
// *checkRulesConfig - 返回 tc 对象
func (tc *checkRulesConfig) registerFlag(cmd extkingpin.FlagClause) *checkRulesConfig {
    // 注册一个名为 "rules" 的命令行标志
    cmd.Flag("rules", "要检查的规则文件glob模式(可重复)").Required().StringsVar(&tc.rulesFiles)
    // 返回 tc 对象
    return tc
}
 
// registerCheckRules 在给定的extkingpin.AppClause上注册 "rules-check" 命令,用于检查规则文件是否有效。
func registerCheckRules(app extkingpin.AppClause) {
    // 注册命令 "rules-check"
    cmd := app.Command("rules-check", "Check if the rule files are valid or not.")
    // 初始化 checkRulesConfig 结构体实例
    crc := &checkRulesConfig{}
    // 注册命令参数
    crc.registerFlag(cmd)
    // 设置命令执行逻辑
    cmd.Setup(func(g *run.Group, logger log.Logger, reg *prometheus.Registry, _ opentracing.Tracer, _ <-chan struct{}, _ bool) error {
        // 添加一个虚拟的 actor,在 run 函数返回后立即终止 group
        // Dummy actor to immediately kill the group after the run function returns.
        g.Add(func() error { return nil }, func(error) {})
        // 检查规则文件
        return checkRulesFiles(logger, &crc.rulesFiles)
    })
}
 
// checkRulesFiles 函数根据提供的模式列表检查规则文件,并返回错误。
//
// 参数:
// logger: log.Logger类型的日志记录器,用于记录日志信息。
// patterns: *[]string类型的指针,指向包含模式列表的切片。
//
// 返回值:
// error类型的返回值,如果所有模式都成功匹配并验证了文件,则返回nil;否则返回一个包含所有错误的MultiError对象。
func checkRulesFiles(logger log.Logger, patterns *[]string) error {
    var failed errutil.MultiError
 
    for _, p := range *patterns {
        // 记录日志,表示正在检查模式
        level.Info(logger).Log("msg", "checking", "pattern", p)
        matches, err := filepath.Glob(p)
        if err != nil || matches == nil {
            // 如果匹配文件未找到,则记录错误日志并添加到失败列表中
            err = errors.New("matching file not found")
            level.Error(logger).Log("result", "FAILED", "error", err)
            level.Info(logger).Log()
            failed.Add(err)
            continue
        }
        for _, fn := range matches {
            // 记录日志,表示正在检查文件
            level.Info(logger).Log("msg", "checking", "filename", filepath.Clean(fn))
            f, er := os.Open(fn)
            if er != nil {
                // 如果打开文件失败,则记录错误日志并添加到失败列表中
                level.Error(logger).Log("result", "FAILED", "error", er)
                level.Info(logger).Log()
                failed.Add(err)
                continue
            }
            // 确保文件在函数结束时关闭
            defer func() { _ = f.Close() }()
 
            n, errs := rules.ValidateAndCount(f)
            if errs.Err() != nil {
                // 如果验证失败,则记录错误日志并添加到失败列表中
                level.Error(logger).Log("result", "FAILED")
                for _, e := range errs {
                    level.Error(logger).Log("error", e.Error())
                    failed.Add(e)
                }
                level.Info(logger).Log()
                continue
            }
            // 记录日志,表示验证成功并输出找到的规则数量
            level.Info(logger).Log("result", "SUCCESS", "rules found", n)
        }
    }
    return failed.Err()
}
posted @   左扬  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
历史上的今天:
2022-02-12 Go从入门到精通——数组(固定大小的连续空间)
levels of contents
点击右上角即可分享
微信分享提示