golang obtains zabbix graph monitoring chart through itemid

Keywords: Zabbix Python PHP Programming

Brief introduction This article will use golang and the third-party http client library gorequest To write. If you need to use only the golang standard library, please refer to another article of mine golang obtains zabbix graph monitoring chart through itemid

#F&Q

  1. Why golang? It's easy to find the script to download the zabbix graph monitoring chart using python on the Internet. But there are two problems in using python:
  • Using urlib and other underlying libraries, the programming is complex and the readability is poor
  • The python version of the online machine is low, and it is troublesome for the installation script to rely on or update the python version
  1. Why gorequest? gorequest encapsulates the http standard library of golang twice, which makes it convenient to read request body, dto, timeout control, etc. in addition, it adds retry function.

ps: there is a problem. zabbix was unable to log in using the map format when adding query.

code

package zabbix

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"time"

	"github.com/parnurzeal/gorequest"
)
var(
	HTTPRequestTimeOut = time.Duration(5) * time.Second
	HTTPRequestRetryPeriod = time.Duration(5) * time.Second
)
//Get timestamp
func getTimeStr() string {
	timeDelta, _ := time.ParseDuration("-3h")
	stime := time.Now().Add(timeDelta)
	timeStr := stime.Format("20060102150405")
	return timeStr
}

func generateErr(frefix string, errs []error) error {
	if errs == nil {
		return nil
	}
	temp := []string{frefix}
	for _, err := range errs {
		temp = append(temp, err.Error())
	}
	return fmt.Errorf(strings.Join(temp, ":"))
}

type Client struct {
	reqAgent *gorequest.SuperAgent
	username string
	password string
	url      string
}

func New(url, username, password string) *Client {
	reqAgent := gorequest.New().
		SetDoNotClearSuperAgent(true).
		Timeout(HTTPRequestTimeOut).
		Retry(3, HTTPRequestRetryPeriod, http.StatusBadRequest, http.StatusInternalServerError)

	return &Client{
		reqAgent: reqAgent,
		username: username,
		password: password,
		url:      url,
	}
}

func (client *Client) indexUrl() string {
	return fmt.Sprintf("%s/index.php", client.url)
}

func (client *Client) login() error {
	res, _, errs := client.reqAgent.Get(client.indexUrl()).
		Query("autologin=1&enter=Sign%20in").
		Query("name="+client.username).
		Query("password="+client.password).
		Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0").
		AppendHeader("Referer", client.indexUrl()).End()
	if errs != nil {
		return generateErr("", errs)
	}
	fmt.Println(res.Status)
	return nil
}

func (client *Client) SaveImage(itemid, fileName string) (string, error) {

	if err := client.login(); err != nil {
		return "", fmt.Errorf("ZabbixClient:SaveImage:GetCookies:%v", err)

	}
	timeStr := getTimeStr()
	_, byteBody, errs := client.reqAgent.Get(client.url + "/chart.php").
		Query("period=7200&width=600").
		Query("time+" + timeStr).
		Query("itemids=" + itemid).
		EndBytes()
	if errs != nil {
		return "", generateErr("ZabbixClient:SaveImage:RequestImage", errs)
	}
	if fileName == "" {
		fileName = filepath.Join("tmp", timeStr+".jpg")
	} else {
		fileName = filepath.Join("tmp", fileName+".jpg")
	}

	out, err := os.Create(fileName)
	if err != nil {
		return fileName, fmt.Errorf("ZabbixClient:SaveImage:CreateImage:%v", err)
	}
	defer out.Close()
	_, err = out.Write(byteBody)
	if err != nil {
		return fileName, fmt.Errorf("ZabbixClient:SaveImage:SaveImage:%v", err)
	}
	return fileName, nil
}

test

package zabbix

import (
	"testing"
)

func get_client() *Client {
	return New("http://127.0.0.1/zabbix", "Admin", "zabbix")
}

func Test_downloadImage(t *testing.T) {
	client := get_client()
	_, err := client.SaveImage("69618", "")
	if err != nil {
		t.Fatal(err)
	}
}

zabbix_client.go

Posted by ejaboneta on Wed, 25 Dec 2019 13:48:00 -0800