GoFiber 从零系列(七):go 使用时序数据库influxdb2.0,进行前端监控数据存储

544 阅读2分钟

前言

最近想要对web-see,前端监控项目进行个人化部署。原文使用express进行的后端编写,基于性能考虑使用 gofiber-influxdb进行覆写。

使用docker安装influxdb2.0

参考文章

  • 关键步骤

image.png

  • 成功登录。能进入该页面即完成influxdb数据库安装

image.png

配置文件修改

  • app.ini
[influxdb]
; influxdb2.0 所在地址
HOST = http://192.168.56.10:8086
; 对应token
TOKEN = bAnJagw453GdU1EzHjLDtozj0xoCJiwdZh_0OsaBzxboJGFtQ50ne_UXrCCV6jKwdIX5cDA_Ov-2_HYgBufPSw==
; 
ORG = jinpika
; 库
BUCKET = monitor_fiber

influxdb数据库初始化

  • 创建/models/influx.go文件
package models

import (
	"github.com/influxdata/influxdb-client-go/v2"
	"github.com/influxdata/influxdb-client-go/v2/api"
	"github.com/jinpikaFE/go_fiber/pkg/logging"
	"github.com/jinpikaFE/go_fiber/pkg/setting"
)

// influxdb 的数据库实例
var influxdbClient influxdb2.Client
var org, bucket string

// 写入数据的api 实例
var writeAPI api.WriteAPI
var queryAPI api.QueryAPI

func init() {
	sec, err := setting.Cfg.GetSection("influxdb")
	if err != nil {
		logging.Fatal(2, "Fail to get section 'influxdb': %v", err)
	}

	host := sec.Key("HOST").String()
	token := sec.Key("TOKEN").String()
	org = sec.Key("ORG").String()
	bucket = sec.Key("BUCKET").String()
	// Create a new InfluxDB client instance
	influxdbClient = influxdb2.NewClientWithOptions(host, token, influxdb2.DefaultOptions().SetBatchSize(100))

	// Create a new write API instance
	writeAPI = influxdbClient.WriteAPI(org, bucket)
	queryAPI = influxdbClient.QueryAPI(org)
}

基本添加和删除

  • 创建/models/intest.go 文件
package models

import (
	"context"
	"encoding/json"
	"time"

	influxdb2 "github.com/influxdata/influxdb-client-go/v2"
	"github.com/influxdata/influxdb-client-go/v2/api/write"
	"github.com/jinpikaFE/go_fiber/pkg/untils"
)

func SetTest() *write.Point {
	b, err := json.Marshal(map[string]interface{}{
		"browserVersion": "114.0.0.0",
		"browser":        "Chrome",
		"osVersion":      "10",
		"os":             "Windows",
		"ua":             "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
		"device":         "Unknow",
		"device_type":    "Pc",
	})
	if err != nil {
		return nil
	}
	p := influxdb2.NewPoint("whiteScreen",
		map[string]string{"apikey": "abcd"}, // tag
		map[string]interface{}{ // fields
			"type":       "whiteScreen",
			"time":       1686548461856,
			"status":     "ok",
			"userId":     "123",
			"sdkVersion": "4.0.2",
			"uuid":       "e7dec5f4-b603-4d5f-9921-b7b983d9800d",
			"pageUrl":    "http://localhost:8083/#/",
			"deviceInfo": string(b),
		},
		time.Now()) // 时间戳
	// write point asynchronously
	writeAPI.WritePoint(p)

	// // create point using fluent style
	// p = influxdb2.NewPointWithMeasurement("stat").
	// 	AddTag("unit", "temperature").
	// 	AddField("avg", 23.2).
	// 	AddField("max", 45).
	// 	SetTime(time.Now())
	// // write point asynchronously
	// writeAPI.WritePoint(p)
	writeAPI.Flush()
	return p
}

func GetTest() (interface{}, error) {
	query := `from(bucket:"monitor_fiber")
	|> range(start: -8d)
	|> filter(fn: (r) => r._measurement == "whiteScreen")
	|> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
	|> drop(columns:["_start","_stop"])` // 丢弃不需要的字段 使用pivot 反转处理查询结果,转为key:value格式
	result, err := queryAPI.Query(context.Background(), query)
	if err != nil {
		return nil, err
	}
	results, resErr := untils.InfluxdbQueryResult(result)

	if resErr != nil {
		return nil, resErr
	}

	// 返回 JSON
	return results, nil
}

控制器及路由

  • /controller/intest.go
package controller

import (
	"github.com/gofiber/fiber/v2"
	"github.com/jinpikaFE/go_fiber/models"
	"github.com/jinpikaFE/go_fiber/pkg/app"
)

func SetTest(c *fiber.Ctx) error {
	appF := app.Fiber{C: c}
	p := models.SetTest()
	return appF.Response(fiber.StatusOK, fiber.StatusOK, "SUCCESS", p)
}

func GetTest(c *fiber.Ctx) error {
	appF := app.Fiber{C: c}
	p, err := models.GetTest()
	if err!=nil {
		return appF.Response(fiber.StatusInternalServerError, fiber.StatusInternalServerError, "查询失败", err)
	}
	return appF.Response(fiber.StatusOK, fiber.StatusOK, "SUCCESS", p)
}

  • 路由
{
        apiv1.Post("/intest", controller.SetTest)
        apiv1.Get("/intest", controller.GetTest)
}

image.png