golang 自定义exporter - 服务连接数 portConnCount_exporter 导出器

需求:

1、计算当前6379 、3306 服务的连接数

2、可prometheus 语法查询

下面代码可直接使用:

注:

1、windows 与linux的区分 第38行代码
localAddr := fields[1] //windows为fields[1] , linux为fields[3]

2、如需求 增加/修改/删除 端口,可参考第70 71行即可

cpp 复制代码
 70         NewPrometheusGauge(3306)
 71         NewPrometheusGauge(6379)

代码

cpp 复制代码
package main

import (
        "fmt"
        "log"
        "net/http"
        "os/exec"
        "strings"
        "time"

        "github.com/prometheus/client_golang/prometheus"
        "github.com/prometheus/client_golang/prometheus/promhttp"
)

func PortConnCounts(port int) float64 {
        // 执行netstat命令
        out, err := exec.Command("netstat", "-an").Output()
        if err != nil {
                fmt.Println("执行netstat命令失败:", err)
                return -1
        }

        // 解析netstat命令输出
        result := string(out)
        lines := strings.Split(result, "\n")
        // fmt.Printf("lines: %v\n", lines)

        var count float64 = 0
        for _, line := range lines {
                // 忽略空行和表头
                if line == "" || strings.Contains(line, "Active Internet connections") || strings.Contains(line, "Proto") {
                        continue
                }

                fields := strings.Fields(line)
                if len(fields) >= 4 {
                        // 获取本地地址和端口
                        localAddr := fields[3] //windows为fields[1]  linux为fields[3]
                        addrParts := strings.Split(localAddr, ":")
                        if len(addrParts) >= 2 {
                                localPort := addrParts[len(addrParts)-1]
                                if localPort == fmt.Sprint(port) {
                                        count++
                                }
                        }
                }
        }
        log.Printf("  port: %v count: %v\n", port, count)
        return count
}

func NewPrometheusGauge(port int) {
        t1 := prometheus.NewGauge(prometheus.GaugeOpts{
                Name: fmt.Sprint("portconnscount", port),
                Help: fmt.Sprint("portconnscount", port, "每10秒执行一次,端口链接数,误差1个左右, 误差在于:::ipv6的显示"),
        })
        // 注册指标
        prometheus.MustRegister(t1)

        // 每秒钟增加指标值
        go func() {
                for {
                        t1.Set(PortConnCounts(port))
                        time.Sleep(time.Second * 10)
                }
        }()
}

func main() {
        NewPrometheusGauge(3306)
        NewPrometheusGauge(6379)

        // 创建一个 Gauge 指标

        // 处理 "/metrics" 路径,暴露指标
        http.Handle("/metrics", promhttp.Handler())
        log.Fatal(http.ListenAndServe(":9101", nil))
}

生成 二进制文件

cpp 复制代码
//get 一下包
go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp

go build -o portConnCount_exporter main.go

执行

cpp 复制代码
nohup ./portConnCount_exporter &

[root@www netstat.go]# tail -f nohup.out 
2023/08/09 15:56:39   port: 6379 count: 2272
2023/08/09 15:56:39   port: 3306 count: 100
2023/08/09 15:56:49   port: 3306 count: 100
2023/08/09 15:56:49   port: 6379 count: 2272
2023/08/09 15:56:59   port: 6379 count: 2272
2023/08/09 15:56:59   port: 3306 count: 100
2023/08/09 15:57:09   port: 6379 count: 2272
2023/08/09 15:57:09   port: 3306 count: 100
2023/08/09 15:57:20   port: 6379 count: 2272

网页访问

http://ip:9101/metrics

prometheus语法查询

Grafana

------------end

相关推荐
GM_8283 小时前
【Go项目基建】GORM框架实现SQL校验拦截器(完整源码+详解)
sql·golang·拦截器·gorm·慢查询·持久层基建
YGGP10 小时前
3D 版接雨水
golang
苦逼IT运维11 小时前
Jenkins 监控方案:Prometheus + Grafana 实践
jenkins·grafana·prometheus
脚踏实地的大梦想家16 小时前
【Go】P2 Golang 常量与变量
开发语言·后端·golang
张璐月16 小时前
go docker-compose启动前后端分离项目 踩坑之旅
开发语言·docker·golang
福大大架构师每日一题18 小时前
go 1.25.1发布:重点修复net/http跨域保护安全漏洞(CVE-2025-47910)
开发语言·http·golang
Dear.爬虫19 小时前
Golang中逃逸现象, 变量“何时栈?何时堆?”
开发语言·后端·golang
参.商.19 小时前
【Day21】146.LRU缓存 (Least Recently Used)
leetcode·缓存·golang
澡点睡觉1 天前
【golang长途旅行第38站】工厂模式
开发语言·后端·golang