Go 语言实现,将 SQL Server 中每个表的大小信息传输到 Prometheus

为了用 Go 语言编写一个程序,将 SQL Server 中每个表的大小信息传输到 Prometheus,你可以遵循以下步骤。
这个过程包括连接到 SQL Server、执行查询获取表大小数据,并使用 Prometheus 客户端库将这些数据暴露给 Prometheus 抓取。

步骤 1: 设置项目环境

首先,确保你已经安装了 Go 和必要的依赖项。然后创建一个新的 Go 模块:

mkdir sql_to_prometheus cd sql_to_prometheus go mod init sql_to_prometheus
步骤 2: 添加依赖
接下来,添加用于连接 SQL Server 和与 Prometheus 交互的依赖包。你需要
github.com/denisenkom/go-mssqldb 来连接 SQL Server,以及
github.com/prometheus/client_golang 来处理 Prometheus 指标。

go get github.com/denisenkom/go-mssqldb go get github.com/prometheus/client_golang/prometheus/promhttp go get github.com/prometheus/client_golang/prometheus
步骤 3: 编写 Go 程序

创建一个名为 main.go 的文件,并在其中编写如下代码:

package main import ( "database/sql" "fmt" "log" "net/http" _ "github.com/denisenkom/go-mssqldb" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) // 定义一个自定义的 Prometheus Gauge 用来存储表大小信息 var tableSizeGauge = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "sql_table_size_mb", Help: "Size of SQL tables in MB", }, []string{"table"}, ) func init() { // 注册自定义的 Gauge 到 Prometheus 默认的注册表中 prometheus.MustRegister(tableSizeGauge) } func collectTableSizes(db *sql.DB) { query := `

use LQtex

SELECT

t.NAME AS TableName,

p.rows AS RowCounts,

SUM(a.total_pages) * 8/1024 AS TotalSpaceMB,

SUM(a.used_pages) * 8/1024 AS UsedSpaceMB,

(SUM(a.total_pages) - SUM(a.used_pages)) * 8/1024 AS UnusedSpaceMB

FROM

sys.tables t

INNER JOIN

sys.indexes i ON t.OBJECT_ID = i.object_id

INNER JOIN

sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id

INNER JOIN

sys.allocation_units a ON p.partition_id = a.container_id

WHERE

t.is_ms_shipped = 0 AND i.object_id > 255 -- 排除系统表

GROUP BY

t.NAME, p.rows

ORDER BY

TotalSpaceMB DESC`

	rows, err := db.Query(query)
	if err != nil {
		log.Fatalf("Error executing query: %v", err)
	}
	defer rows.Close()

	tableSizeGauge.Reset() // 清除旧的数据

	for rows.Next() {
		var tableName string
		var totalSpaceMB float64
		err := rows.Scan(&tableName, &totalSpaceMB, nil, nil)
		if err != nil {
			log.Printf("Error scanning row: %v", err)
			continue
		}
		tableSizeGauge.WithLabelValues(tableName).Set(totalSpaceMB)
	}

	if err = rows.Err(); err != nil {
		log.Fatalf("Error iterating over rows: %v", err)
	}
}

func main() {
	// 替换为你的 SQL Server 连接字符串
	connString := "server=your_server;user id=your_user;password=your_password;database=your_db;encrypt=disable"

	db, err := sql.Open("sqlserver", connString)
	if err != nil {
		log.Fatalf("Error opening database: %v", err)
	}
	defer db.Close()

	err = db.Ping()
	if err != nil {
		log.Fatalf("Error pinging database: %v", err)
	}

	http.Handle("/metrics", promhttp.Handler())
	go func() {
		http.ListenAndServe(":9104", nil)
	}()

	log.Println("Starting to collect metrics...")

	// 每隔一段时间收集一次表大小信息
	ticker := time.NewTicker(60 * time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			collectTableSizes(db)
		}
	}
}

步骤 4: 配置和运行程序
保存 main.go 文件后,在命令行中运行以下命令来构建并启动应用程序:
go build -o sql_to_prometheus ./sql_to_prometheus
步骤 5: 配置 Prometheus
最后,更新你的 Prometheus 配置 (prometheus.yml),使其能够抓取你新创建的服务提供的指标:scrape_configs:
- job_name: 'sql_table_sizes' static_configs: - targets: ['localhost:9104']

重启 Prometheus 以应用新的配置。现在,Prometheus 应该可以开始抓取来自 SQL Server 的表大小信息了。
注意事项
•安全性:请确保你的数据库连接字符串安全,避免泄露敏感信息。
•性能:根据你的需求调整定时器的时间间隔(当前设置为每分钟),以平衡监控频率和系统负载。
•错误处理:示例代码中的错误处理较为简单;在生产环境中,你可能需要更健壮的错误处理逻辑。
通过上述步骤,你就完成了一个简单的 Go 程序,它可以定期从 SQL Server 获取表大小信息,并将其暴露给 Prometheus 抓取。

  

posted @ 2024-12-25 17:30  zhaoguanhao  阅读(25)  评论(0)    收藏  举报