手把手教你为开源项目贡献代码

背景

前段时间无意间看到一篇公众号 招贤令:一起来搞一个新开源项目,作者介绍他想要做一个开源项目:cprobe 用于整合目前市面上散落在各地的 Exporter,统一进行管理。

比如我们常用的 blackbox_exporter/mysqld_exporter 等。

以往的每一个 Exporter 都需要单独部署运维。

同时又完全兼容 Prometheus 生态,也可以复用现有的监控面板。

恰好这段时间我也在公司从事可观测性相关的业务,发现这确实是一个痛点。

于是便一直在关注这个项目,同时也做了些贡献;因为该项目的核心是用于整合 exporter,所以为其编写插件也是非常重要的贡献了。

编写插件

整个项目执行流程图如下:

可以看到编写插件最核心的便是自定义插件解析自定义的配置文件、抓取指标的逻辑。

比如我们需要在配置中指定抓取目标的域名、抓取规则等。

这里 cprobe 已经抽象出了两个接口,我们只需要做对应的实现即可。

go 复制代码
type Plugin interface {  
    // ParseConfig is used to parse config  
    ParseConfig(baseDir string, bs []byte) (any, error)  
    // Scrape is used to scrape metrics, cfg need to be cast specific cfg  
    Scrape(ctx context.Context, target string, cfg any, ss *types.Samples) error  
}

下面就以我之前编写的 Consul 为例。

yaml 复制代码
# Allows any Consul server (non-leader) to service a read.  
allow_stale = true  
  
# === CA  
# File path to a PEM-encoded certificate authority used to validate the authenticity of a server certificate.  
ca_file = "/etc/consul.d/consul-agent-ca.pem"  
  
# File path to a PEM-encoded certificate used with the private key to verify the exporter's authenticity.  
cert_file = "/etc/consul.d/consul-agent.pem"  
  
# Generate a health summary for each service instance. Needs n+1 queries to collect all information.  
health_summary = true  
  
# File path to a PEM-encoded private key used with the certificate to verify the exporter's authenticity  
key_file = "/etc/consul.d/consul-agent-key.pem"  
  
# Disable TLS host verification.  
insecure = false

这里每个插件的配置都不相同,所以我们需要将配置解析到具体的结构体中。

go 复制代码
func (*Consul) ParseConfig(baseDir string, bs []byte) (any, error) {  
    var c Config  
    err := toml.Unmarshal(bs, &c)  
    if err != nil {  
       return nil, err  
    }  
  
    if c.Timeout == 0 {  
       c.Timeout = time.Millisecond * 500  
    }  
    return &c, nil  
}

解析配置文件没啥好说的,根据自己的逻辑实现即可,可能会配置一些默认值而已。


下面是核心的抓取逻辑,本质上就是使用对应插件的 Client 获取一些核心指标封装为 PrometheusMetric,然后由 cprobe 写入到远端的 Prometheus 中(或者是兼容 Prometheus 的数据库中)。

go 复制代码
// Create client
config.HttpClient.Timeout = opts.Timeout  
config.HttpClient.Transport = transport  
  
client, err := consul_api.NewClient(config)  
if err != nil {  
    return nil, err  
}  
  
var requestLimitChan chan struct{}  
if opts.RequestLimit > 0 {  
    requestLimitChan = make(chan struct{}, opts.RequestLimit)  
}

所有的指标数据都是通过对应的客户端获取。

如果是迁移一个存在的 export 到 cprobe 中时,这些抓取代码我们都可以直接复制对应 repo 中的代码。

比如我就是参考的:https://github.com/prometheus/consul_exporter

除非我们是重新写一个插件,不然对于一些流行的库或者是中间件都已经有对应的 exporter 了。

具体的列表可以参考这里:
https://prometheus.io/docs/instrumenting/exporters/

之后便需要在对应的插件目录(./conf.d)创建我们的配置文件:

为了方便测试,可以在启动 cprobe 时添加 -no-writer 让指标打印在控制台,从而方便调试。

总结

之前就有人问我有没有毕竟好上手的开源项目,这不就来了吗?

正好目前项目创建时间不长,代码和功能也比较简单,同时还有可观察系统大佬带队,确实是一个非常适合新手参与的开源项目。

项目地址:

https://github.com/cprobe/cprobe

私货

最后夹带一点私货:前两天帮一个读者朋友做了一次付费的技术咨询(主要是关于 Pulsar 相关的),也是我第一次做付费内容,这种拿人钱财替人消灾难道就是知识付费的味道吗😂?

所以我就趁热打铁在朋友圈发了个广告,没想到又有个朋友找我做关于职场相关咨询,最后能帮助到对方自己也很开心。

其实经常也有人通过社媒、邮件等渠道找我帮忙看问题,一些简单的我通常也会抽时间回复。

但后面这位朋友也提到,如果我不是付费,他也不好意思来找我聊这些内容,毕竟涉及到一些隐私,同时也需要占用双方 1~2 小时的时间。

这样明码标价的方式确实也能更方便的沟通,同时也能减轻对方的心里负担,直接从白嫖转为付费大佬。

铺垫了这么多,主要目的是想进行一个小范围的尝试,如果对以下内容感兴趣的朋友欢迎加我微信私聊:

包括但不限于技术、职场、开源等我有经验的行业都可以聊。

反馈不错的话也需要可以作为我的长期副业做下去。

相关推荐
修己xj1 小时前
Anki:让记忆更高效、更智能的开源力量
开源
冬奇Lab7 小时前
一天一个开源项目(第17篇):ViMax - 多智能体视频生成框架,导演、编剧、制片人全包
开源·音视频开发
一个处女座的程序猿8 小时前
AI之Agent之VibeCoding:《Vibe Coding Kills Open Source》翻译与解读
人工智能·开源·vibecoding·氛围编程
一只大侠的侠9 小时前
React Native开源鸿蒙跨平台训练营 Day16自定义 useForm 高性能验证
flutter·开源·harmonyos
IvorySQL10 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
一只大侠的侠11 小时前
Flutter开源鸿蒙跨平台训练营 Day11从零开发商品详情页面
flutter·开源·harmonyos
一只大侠的侠11 小时前
React Native开源鸿蒙跨平台训练营 Day18自定义useForm表单管理实战实现
flutter·开源·harmonyos
一只大侠的侠11 小时前
React Native开源鸿蒙跨平台训练营 Day20自定义 useValidator 实现高性能表单验证
flutter·开源·harmonyos
晚霞的不甘11 小时前
Flutter for OpenHarmony 可视化教学:A* 寻路算法的交互式演示
人工智能·算法·flutter·架构·开源·音视频
晚霞的不甘13 小时前
Flutter for OpenHarmony 实现计算几何:Graham Scan 凸包算法的可视化演示
人工智能·算法·flutter·架构·开源·音视频