|
- package main
-
- import (
- "database/sql"
- "flag"
- "fmt"
- _ "github.com/mattn/go-sqlite3"
- "github.com/prometheus/client_golang/prometheus"
- "github.com/prometheus/client_golang/prometheus/promauto"
- "github.com/prometheus/client_golang/prometheus/promhttp"
- "math/rand"
- "os"
- "path/filepath"
- "strconv"
- "strings"
-
- "log"
- "net/http"
- "time"
- )
-
- var addr = flag.String("listen-address", ":7070", "The address to listen on for HTTP requests.")
-
- var metrics = []struct {
- name string
- label string
- note string
- labelValues string
- value float64
- }{
- {"metric1", "method,handler", "This is metric1", "a, b", 0},
- {"metric2", "method,handler", "This is metric2", "a, b", 0},
- {"Recall", "model_name", "Model Recall", "a", 0},
- {"Precision", "model_name", "Model Precision", "b", 0},
- }
-
- func recordTaskNumM(db *sql.DB) {
- go func() {
- for {
- rows, err := db.Query("SELECT a.id, a.name, a.task_num, b.task_attr FROM ll_task_grp as a left join ll_tasks as b where a.id=b.id;")
- if err != nil {
- fmt.Println(err)
- }
- for rows.Next() {
- var id int
- var name string
- var taskNum int
- var attr string
- err = rows.Scan(&id, &name, &taskNum, &attr)
- g, err := opsTaskTaskNum.GetMetricWithLabelValues(strconv.Itoa(id), name, attr)
- if err == nil {
- g.Set(float64(taskNum))
- }
- }
- time.Sleep(1 * time.Second)
- }
- }()
- }
-
- func recordTaskSampleMStatusM(db *sql.DB) {
- go func() {
- for {
- rows, err := db.Query("SELECT id, name, deploy, sample_num, task_num FROM ll_task_grp")
- if err != nil {
- fmt.Println(err)
- }
- for rows.Next() {
- var id int
- var name string
- var deploy bool
- var sampleNum int
- var taskNum int
- err = rows.Scan(&id, &name, &deploy, &sampleNum, &taskNum)
- g, err := opsTaskSampleNum.GetMetricWithLabelValues(strconv.Itoa(id), name)
- if err == nil {
- g.Set(float64(sampleNum))
- }
- g, err = opsDeployStatus.GetMetricWithLabelValues(strconv.Itoa(id), name)
- if err == nil {
- if deploy {
- g.Set(1)
- } else {
- g.Set(0)
- }
- }
- }
- time.Sleep(1 * time.Second)
- }
- }()
- }
-
- func recordKnownTasks(db *sql.DB) {
- go func() {
- for {
- rows, err := db.Query("SELECT count(*) as c from ll_task_models where is_current = 1")
- if err != nil {
- fmt.Println(err)
- }
- for rows.Next() {
- var c int
- err = rows.Scan(&c)
- g, err := opsKnowTaskNum.GetMetricWithLabelValues()
- if err == nil {
- g.Set(float64(c))
- }
- }
- time.Sleep(1 * time.Second)
- }
- }()
- }
-
- func recordTaskStatus(db *sql.DB) {
- go func() {
- for {
- rows, err := db.Query("SELECT task_id, model_url, is_current as c from ll_task_models")
- if err != nil {
- fmt.Println(err)
- }
- for rows.Next() {
- var taskId int
- var modelUrl string
- var isCurrent bool
- err = rows.Scan(&taskId, &modelUrl, &isCurrent)
- g, err := opsTaskStatus.GetMetricWithLabelValues(strconv.Itoa(taskId), modelUrl)
- if err == nil {
- if isCurrent {
- g.Set(1)
- } else {
- g.Set(0)
- }
- }
- }
- time.Sleep(1 * time.Second)
- }
- }()
- }
-
- func recordTaskRelationShip(db *sql.DB) {
- go func() {
- for {
- rows, err := db.Query("select grp_id, task_id, transfer_radio from ll_task_relation")
- if err != nil {
- fmt.Println(err)
- }
- for rows.Next() {
- var grpId int
- var taskId int
- var transferRatio float64
- err = rows.Scan(&grpId, &taskId, &transferRatio)
- g, err := opsTaskRelationShip.GetMetricWithLabelValues(strconv.Itoa(grpId), strconv.Itoa(taskId))
- if err == nil {
- g.Set(transferRatio)
- }
- }
- time.Sleep(1 * time.Second)
- }
- }()
- }
-
- func customMetrics(db *sql.DB, registry *prometheus.Registry) {
- // mock
- sql := "insert into metric (name, label, note, last_time) values (?, ?, ?, time('now'))"
- rows, err := db.Query("select count(*) from metric")
- if err != nil {
- fmt.Println(err)
- }
- mock := false
- for rows.Next() {
- var count int
- err = rows.Scan(&count)
- if err != nil {
- fmt.Println(err)
- }
- mock = count == 0
- }
-
- if mock {
- for i, metric := range metrics {
- _, err := db.Exec(sql, metric.name, metric.label, metric.note)
- if err != nil {
- fmt.Println(err)
- }
- _, err = db.Exec("insert into metric_value (metric_id, label_value, value, last_time) values (?, ?, ?, time('now'))",
- i, metric.labelValues, metric.value)
- if err != nil {
- fmt.Println(err)
- }
- }
- mockV := 1.0
- go func() {
- for {
- _, err := db.Exec("update metric_value set value=?", mockV)
- if err != nil {
- fmt.Println(err)
- }
- mockV = rand.Float64()
- time.Sleep(time.Second)
- }
- }()
- }
-
- // register metrics
- registeredMetrics := make([]*prometheus.GaugeVec, 0, 4)
- rows, err = db.Query("select name, label, note from metric order by id asc")
- if err != nil {
- fmt.Println(err)
- }
- for rows.Next() {
- var name string
- var label string
- var note string
- err = rows.Scan(&name, &label, ¬e)
- labels := strings.Split(label, ",")
- for i := range labels {
- labels[i] = strings.TrimSpace(labels[i])
- }
- met := promauto.NewGaugeVec(prometheus.GaugeOpts{
- Name: name,
- Help: note,
- }, labels)
- registry.MustRegister(met)
- registeredMetrics = append(registeredMetrics, met)
- }
-
- go func() {
- for {
- rows, err := db.Query("select metric_id, label_value, `value` from metric_value")
- if err != nil {
- fmt.Println(err)
- }
- for rows.Next() {
- var metricId int
- var labelValue string
- var value float64
- err = rows.Scan(&metricId, &labelValue, &value)
- labelValues := strings.Split(labelValue, ",")
- for i, _ := range labelValues {
- labelValues[i] = strings.TrimSpace(labelValues[i])
- }
- if len(registeredMetrics) <= metricId || registeredMetrics[metricId] == nil {
- continue
- }
- g, err := registeredMetrics[metricId].GetMetricWithLabelValues(labelValues...)
- if err == nil {
- g.Set(value)
- }
- }
- time.Sleep(time.Second)
- }
- }()
- }
-
- func fileScanner(p string, suffix string) {
- go func() {
- for {
- num := 0
- root := p
- err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
- if strings.HasSuffix(path, suffix) {
- num += 1
- }
- return nil
- })
- if err != nil {
- println(err)
- }
- g, err := opsFilesSuffixNum.GetMetricWithLabelValues()
- if err == nil {
- g.Set(float64(num))
- }
- num = 0
- time.Sleep(time.Second)
- }
- }()
- }
-
- var (
- // task metrics
- opsKnowTaskNum = promauto.NewGaugeVec(prometheus.GaugeOpts{
- Name: "know_task_num",
- Help: "Number of known tasks in the knowledge base",
- }, []string{})
- opsTaskSampleNum = promauto.NewGaugeVec(prometheus.GaugeOpts{
- Name: "task_sample_num",
- Help: "The total number of samples in task",
- }, []string{"id", "name"})
- opsTaskTaskNum = promauto.NewGaugeVec(prometheus.GaugeOpts{
- Name: "task_num",
- Help: "The total number of tasks",
- }, []string{"id", "name", "attr"})
- opsTaskRelationShip = promauto.NewGaugeVec(prometheus.GaugeOpts{
- Name: "task_relation_ship",
- Help: "Migration relationship between tasks",
- }, []string{"grp_id", "task_id"})
- opsTaskStatus = promauto.NewGaugeVec(prometheus.GaugeOpts{
- Name: "task_status",
- Help: "Whether the task can be deployed",
- }, []string{"task_id", "model_url"})
- opsDeployStatus = promauto.NewGaugeVec(prometheus.GaugeOpts{
- Name: "deploy_status",
- Help: "Enum(Waiting, OK, NotOK)",
- }, []string{"id", "name"})
- opsFilesSuffixNum = promauto.NewGaugeVec(prometheus.GaugeOpts{
- Name: "files_with_suffix_num",
- Help: "The number of files with suffix",
- }, []string{})
- )
-
- func main() {
- var scannerPath string
- var scannerSuffix string
- flag.StringVar(&scannerPath, "scanner-path", "-", "file scanner path")
- flag.StringVar(&scannerSuffix, "scanner-suffix", "", "file scanner suffix")
- flag.Parse()
- if scannerPath != "-" {
- fileScanner(scannerPath, scannerSuffix)
- }
-
- dbSrc := "kb.sqlite3"
- db, err := sql.Open("sqlite3", dbSrc)
- if err != nil {
- fmt.Printf("Can't open %s\n", dbSrc)
- return
- }
-
- dropTableMetric := "drop table metric"
- dropTableMetricValue := "drop table metric_value"
- _, err = db.Exec(dropTableMetric)
- if err != nil {
- println(err)
- }
- _, err = db.Exec(dropTableMetricValue)
- if err != nil {
- println(err)
- }
- createTableMetric := "create table if not exists metric(id int primary key, `name` text, label text, note text, last_time timestamp)"
- createTableMetricValue := "create table if not exists metric_value(id int primary key, metric_id int, label_value text, `value` float, last_time timestamp)"
- _, err = db.Exec(createTableMetric)
- if err != nil {
- println(err)
- }
- _, err = db.Exec(createTableMetricValue)
- if err != nil {
- println(err)
- }
-
- // Create a new registry.
- reg := prometheus.NewRegistry()
- recordTaskNumM(db)
- recordTaskSampleMStatusM(db)
- recordKnownTasks(db)
- recordTaskRelationShip(db)
- recordTaskStatus(db)
- customMetrics(db, reg)
-
- // Add Go module build info.
- reg.MustRegister(opsKnowTaskNum)
- reg.MustRegister(opsTaskSampleNum)
- reg.MustRegister(opsTaskTaskNum)
- reg.MustRegister(opsTaskRelationShip)
- reg.MustRegister(opsTaskStatus)
- reg.MustRegister(opsDeployStatus)
- reg.MustRegister(opsFilesSuffixNum)
-
- // Expose the registered metrics via HTTP.
- http.Handle("/metrics", promhttp.HandlerFor(
- reg,
- promhttp.HandlerOpts{
- // Opt into OpenMetrics to support exemplars.
- EnableOpenMetrics: true,
- },
- ))
- log.Fatal(http.ListenAndServe(*addr, nil))
- }
|