refactor(zabbix): 使 zabbix agent 插件集成独立化

This commit is contained in:
Liam Chan 2024-08-23 13:28:48 +08:00
parent c6803285fe
commit a5f6c3b1d9
12 changed files with 78 additions and 68 deletions

1
.gitignore vendored
View File

@ -170,6 +170,7 @@ Temporary Items
.apdisk .apdisk
# Application # Application
log/
config.dev.yaml config.dev.yaml
compose.dev.yaml compose.dev.yaml

View File

@ -1,12 +1,4 @@
server: app:
port: 8080 port: 8080
host: "localhost" host: "localhost"
app:
url: "http://localhost:8080" url: "http://localhost:8080"
integrations:
zabbix_agent:
plugin:
name: "Onvif"
version: "1.0.0"

View File

@ -4,29 +4,21 @@ import (
"fmt" "fmt"
"github.com/spf13/viper" "github.com/spf13/viper"
"log" "log"
"onvif-agent/constant"
"os" "os"
) )
type config struct { type config struct {
Server serverConfig `mapstructure:"server"` App appConfig `mapstructure:"app"`
App appConfig `mapstructure:"app"`
Integrations integrationConfig `mapstructure:"integrations"`
}
type serverConfig struct {
Port int `mapstructure:"port"`
Host string `mapstructure:"host"`
} }
type appConfig struct { type appConfig struct {
URL string `mapstructure:"url"` Port int `mapstructure:"port"`
Host string `mapstructure:"host"`
URL string `mapstructure:"url"` // web server url
} }
type integrationConfig struct { var Config config
ZabbixAgent IntegrationConfig `mapstructure:"zabbix_agent"`
}
var Conf config
func LoadConfig() error { func LoadConfig() error {
env := os.Getenv("PROFILE") env := os.Getenv("PROFILE")
@ -37,17 +29,18 @@ func LoadConfig() error {
configName = fmt.Sprint("config.", env) configName = fmt.Sprint("config.", env)
} }
log.Println("Loading config: ", configName)
viper.SetConfigName(configName) viper.SetConfigName(configName)
viper.SetConfigType("yaml") viper.SetConfigType("yaml")
viper.AddConfigPath(".") viper.AddConfigPath(".")
viper.AddConfigPath(fmt.Sprintf("/etc/%s", constant.AppName))
if err := viper.ReadInConfig(); err != nil { if err := viper.ReadInConfig(); err != nil {
return err return err
} }
if err := viper.Unmarshal(&Conf); err != nil { log.Println("Loading config file:", viper.ConfigFileUsed())
if err := viper.Unmarshal(&Config); err != nil {
return err return err
} }

View File

@ -1,10 +0,0 @@
package config
type IntegrationConfig struct {
Plugin PluginConfig `mapstructure:"plugin"`
}
type PluginConfig struct {
Name string `mapstructure:"name"`
Version string `mapstructure:"version"`
}

6
constant/app.go Normal file
View File

@ -0,0 +1,6 @@
package constant
const (
AppName = "onvif-agent"
AppVersion = "1.0.0"
)

View File

@ -0,0 +1,5 @@
package zabbixagent
const (
PluginName = "OnvifAgent"
)

View File

@ -7,6 +7,7 @@ import (
"io" "io"
"net/http" "net/http"
"onvif-agent/config" "onvif-agent/config"
"onvif-agent/constant"
"strings" "strings"
) )
@ -22,8 +23,8 @@ type Handler struct {
client *http.Client client *http.Client
} }
func (h *Handler) GetPluginVersion(_ context.Context, _ map[string]string, _ ...string) (any, error) { func (h *Handler) GetAppVersion(_ context.Context, _ map[string]string, _ ...string) (any, error) {
return config.Conf.Integrations.ZabbixAgent.Plugin.Version, nil return constant.AppVersion, nil
} }
func (h *Handler) HTTPClient(ctx context.Context, params map[string]string, _ ...string) (any, error) { func (h *Handler) HTTPClient(ctx context.Context, params map[string]string, _ ...string) (any, error) {
@ -34,13 +35,12 @@ func (h *Handler) HTTPClient(ctx context.Context, params map[string]string, _ ..
url := params["url"] url := params["url"]
if !strings.HasPrefix(url, "http") { if !strings.HasPrefix(url, "http") {
url = fmt.Sprintf("http://localhost:%d/%s", config.Conf.Server.Port, url) url = fmt.Sprintf("http://localhost:%d/%s", config.Config.App.Port, url)
} }
body := params["body"] body := params["body"]
//req, err := http.NewRequestWithContext(ctx, method, "https://api.imbytecat.com/ip", http.NoBody) req, err := http.NewRequestWithContext(ctx, method, "https://api.imbytecat.com/ip", strings.NewReader(body)) // TODO: if empty use http.NoBody
req, err := http.NewRequestWithContext(ctx, method, "https://api.imbytecat.com/ip", strings.NewReader(body))
if err != nil { if err != nil {
return nil, errs.Wrapf(err, "failed to create request") return nil, errs.Wrapf(err, "failed to create request")
} }

View File

@ -3,7 +3,6 @@ package zabbixagent
import ( import (
"errors" "errors"
"fmt" "fmt"
"onvif-agent/config"
"os" "os"
"golang.zabbix.com/sdk/plugin/flag" "golang.zabbix.com/sdk/plugin/flag"
@ -37,7 +36,7 @@ const (
func Run() { func Run() {
err := flag.HandleFlags( err := flag.HandleFlags(
config.Conf.Integrations.ZabbixAgent.Plugin.Name, PluginName,
os.Args[0], os.Args[0],
fmt.Sprintf(copyrightMessage, pluginLicenseYear), fmt.Sprintf(copyrightMessage, pluginLicenseYear),
pluginVersionRC, pluginVersionRC,

View File

@ -7,12 +7,9 @@ import (
"golang.zabbix.com/sdk/plugin" "golang.zabbix.com/sdk/plugin"
"golang.zabbix.com/sdk/plugin/container" "golang.zabbix.com/sdk/plugin/container"
"golang.zabbix.com/sdk/zbxerr" "golang.zabbix.com/sdk/zbxerr"
"onvif-agent/config"
"time" "time"
) )
var Name = config.Conf.Integrations.ZabbixAgent.Plugin.Name
type metricKey string type metricKey string
type metricBinding struct { type metricBinding struct {
@ -34,7 +31,7 @@ func Launch() error {
return err return err
} }
h, err := container.NewHandler(Name) h, err := container.NewHandler(PluginName)
if err != nil { if err != nil {
return errs.Wrap(err, "failed to create new handler") return errs.Wrap(err, "failed to create new handler")
} }
@ -81,11 +78,11 @@ func (p *zabbixAgentPlugin) registerMetrics() error {
p.metrics = map[metricKey]*metricBinding{ p.metrics = map[metricKey]*metricBinding{
"onvif.version": { "onvif.version": {
metric: metric.New( metric: metric.New(
"ONVIF plugin version", "ONVIF app version",
nil, nil,
false, false,
), ),
handler: h.GetPluginVersion, handler: h.GetAppVersion,
}, },
"onvif.client": { "onvif.client": {
metric: metric.New( metric: metric.New(
@ -107,7 +104,7 @@ func (p *zabbixAgentPlugin) registerMetrics() error {
metricSet[string(k)] = m.metric metricSet[string(k)] = m.metric
} }
err := plugin.RegisterMetrics(p, Name, metricSet.List()...) err := plugin.RegisterMetrics(p, PluginName, metricSet.List()...)
if err != nil { if err != nil {
return errs.Wrap(err, "failed to register metrics") return errs.Wrap(err, "failed to register metrics")
} }

55
main.go
View File

@ -1,12 +1,39 @@
package main package main
import ( import (
"fmt"
"github.com/gin-gonic/gin"
"io"
"log" "log"
"onvif-agent/config" "onvif-agent/config"
"onvif-agent/constant"
"onvif-agent/integration/zabbixagent" "onvif-agent/integration/zabbixagent"
"onvif-agent/router"
"os"
"time"
) )
func main() { func main() {
/**
* Logging
*/
date := time.Now().Format("2006-01-02")
f, err := os.OpenFile(fmt.Sprintf("/var/log/%s/%s.log", constant.AppName, date), os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm)
if err != nil {
log.Fatalf("Error opening file: %v", err)
}
defer func(f *os.File) {
err := f.Close()
if err != nil {
log.Fatalf("Error closing file: %v", err)
}
}(f)
writer := io.MultiWriter(os.Stdout, f)
log.SetOutput(writer)
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
/** /**
* Load config * Load config
*/ */
@ -17,23 +44,23 @@ func main() {
/** /**
* Web server * Web server
*/ */
//go func() { go func() {
// r := gin.Default() r := gin.Default()
//
// router.SetupRoutes(r) router.SetupRoutes(r)
//
// addr := fmt.Sprintf("%s:%d", config.Conf.Server.Host, config.Conf.Server.Port) addr := fmt.Sprintf("%s:%d", config.Config.App.Host, config.Config.App.Port)
// if err := r.Run(addr); err != nil { if err := r.Run(addr); err != nil {
// fmt.Println("Failed to start server:", err) fmt.Println("Failed to start server:", err)
// } }
//}() }()
/** /**
* Zabbix agent * Zabbix agent
*/ */
//go func() { go func() {
zabbixagent.Run() zabbixagent.Run()
//}() }()
//select {} select {}
} }

View File

@ -12,7 +12,7 @@ import (
func CreateEventSubscription(c *gin.Context) { func CreateEventSubscription(c *gin.Context) {
xaddr := c.Param("xaddr") xaddr := c.Param("xaddr")
callbackURL := event.AttributedURIType(fmt.Sprintf("%s/onvif/subscriptions/%s/callback", config.Conf.App.URL, xaddr)) callbackURL := event.AttributedURIType(fmt.Sprintf("%s/onvif/subscriptions/%s/callback", config.Config.App.URL, xaddr))
log.Printf("CreateEventSubscription callback URL: %s", callbackURL) log.Printf("CreateEventSubscription callback URL: %s", callbackURL)
conn := conns[xaddr] conn := conns[xaddr]

View File

@ -2,8 +2,8 @@ FROM golang:1.23 AS builder
WORKDIR /build WORKDIR /build
COPY . ./ COPY . ./
RUN GOPROXY=https://goproxy.cn go mod download RUN GOPROXY=https://goproxy.cn go mod download
RUN PROFILE=dev CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -o /app RUN PROFILE=dev CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -o out/app
FROM zabbix/zabbix-agent2:ubuntu-7.0-latest FROM zabbix/zabbix-agent2:ubuntu-7.0-latest
COPY --from=builder /app /usr/sbin/zabbix-agent2-plugin/onvif COPY --from=builder /build/out/app /usr/sbin/onvif-agent
RUN echo "Plugins.Onvif.System.Path=/usr/sbin/zabbix-agent2-plugin/onvif" >> /etc/zabbix/zabbix_agent2.d/plugins.d/onvif.conf RUN echo "Plugins.Onvif.System.Path=/usr/sbin/onvif-agent" >> /etc/zabbix/zabbix_agent2.d/plugins.d/onvif.conf