g2z

package module
v0.0.0-...-c41ece4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 25, 2016 License: GPL-2.0 Imports: 7 Imported by: 1

README

g2z

Zabbix module adapter for Go

GoDoc Build Status

This project provides Go bindings for creating native Zabbix modules.

WARNING:_ Please see issue #5 before making use of this library. Single threaded workloads are fine but any use of go-routines/threads (or APIs which make use of threads) will not work and probably never will. This is due to irreconcilable architectural differences between the Zabbix agent and Go runtime (sad face...).

Zabbix modules are an effective way of extending the Zabbix agent and server to monitor resources which are not natively supported by Zabbix.

There are currently two ways to extend Zabbix:

User Parameters simply map agent item keys to system calls. While this is by far the easiest way to extend Zabbix, User Parameters require a process fork on every call (a severe performance impact under load) and typically require a script interpreter such as Perl or Ruby and their dependent framework modules.

Loadable Modules offer a significant performance increase (being native C libraries) and reduce the overhead of dependencies. Unfortunately, modules are rarely adopted because the effort and expertise required to write one in C is a great deal more than writing a script in a higher level language like Perl.

This project aims to deliver the best of both worlds; fast, native C libraries, written in an easier high-level language (Go), with all the dependencies bundled into a standalone library file.

The findings of some performance tests are listed in performance.md.

Requirements

  • Go v1.5.0+
  • Zabbix v2.2.0+
  • C build tools (only tested on GCC)

Installation

The module APIs of Zabbix v2 and v3 are currently incompatible. As a result, you must install and import the appropriate version of g2z for your targeted Zabbix version.

For Zabbix v2.X:

$ go get gopkg.in/cavaliercoder/g2z.v2

For Zabbix v3.X:

$ go get gopkg.in/cavaliercoder/g2z.v3

Usage

Here's a quick high-level run down on how to create a Zabbix agent module. For further guidance, there is full API documentation available on godoc.org and an example module included in the g2z sources which implements the dummy C module published by Zabbix.

To begin, create a mandatory main() entry point to your library and import g2z. The main() function will never be called but is a requirement for building shared libraries in Go.

package main

import "github.com/cavaliercoder/g2z"

func main() {
    panic("THIS_SHOULD_NEVER_HAPPEN")
}

Write a Go function which accepts a *g2z.AgentRequest parameter and returns either a string, uint64, float64 or g2z.DiscoveryData as the first parameter, and an error as the second return parameter.

func Echo(request *g2z.AgentRequest) (string, error) {
    return strings.Join(request.Params, " "), nil
}

Create an init() function to register your functions as agent item keys. The init() function is executed by the Go runtime when your module is loaded into Zabbix via dlopen(). You should not execute any other calls in this function, other than registering your items and init/uninit handlers.

func init() {
    g2z.RegisterStringItem("go.echo", "Hello world!", Echo)
}

There are a few different item types you may register. Each requires an agent item key name, some test parameters and a handler function for Zabbix to call when it receives a request for the registered item key.

Compile your project with:

$ go build -buildmode=c-shared

Load your .so module file into Zabbix as per the Zabbix manual.

Test your item keys with zabbix_agentd -p or zabbix_agent_bench.

License

g2z - Zabbix module adapter for Go Copyright (C) 2015 - Ryan Armstrong ryan@cavaliercoder.com

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Documentation

Overview

Package g2z provides Go bindings for creating a native Zabbix module.

An example module is provided with the g2z sources (in dummy/dummy.go) which is a Go implementation of the dummy C module published by Zabbix.

To build a shared library compatible with Zabbix v2.2.0+, this project takes advantage of the c-shared build mode introduced in Go v1.5.0.

package main

import (
	"github.com/cavaliercoder/g2z"
	"strings"
)

// mandatory library entry point, although it is never called.
func main() {
    panic("THIS_SHOULD_NEVER_HAPPEN")
}

// mandatory initialization function
func init() {
    g2z.RegisterStringItem("go.echo", "Hello world!", Echo)
}

// handler for 'go.echo' item
func Echo(request *g2z.AgentRequest) (string, error) {
    return strings.Join(request.Params, " "), nil
}

Compile your shared library with:

$ go build -buildmode=c-shared

You should see the required Zabbix module functions exported in your shared library

$ nm -g
...
0000000000111830 T zbx_module_api_version
0000000000111860 T zbx_module_init
00000000001118f0 T zbx_module_item_list
00000000001118c0 T zbx_module_item_timeout
0000000000111890 T zbx_module_uninit

Load your `.so` module file into Zabbix as per the Zabbix manual

https://www.zabbix.com/documentation/2.2/manual/config/items/loadablemodules#configuration_parameters

Check that your module items are loaded with:

$ zabbix_agentd -t go.echo[hello,world]

For more thorough performance testing, use zabbix_agent_bench

https://github.com/cavaliercoder/zabbix_agent_bench

Index

Examples

Constants

This section is empty.

Variables

View Source
var Timeout int

Timeout is set by Zabbix (via zbx_module_item_timeout()) to the number of seconds that all registered item handlers should obey as a strict timeout.

This timeout is not enforced and should be voluntarily implemented.

Functions

func LogCriticalf

func LogCriticalf(format string, a ...interface{})

LogCriticalf formats according to a format specifier and writes to the Zabbix log file with a critical message.

func LogDebugf

func LogDebugf(format string, a ...interface{})

LogDebugf formats according to a format specifier and writes to the Zabbix log file with a debug message.

func LogErrorf

func LogErrorf(format string, a ...interface{})

LogErrorf formats according to a format specifier and writes to the Zabbix log file with an error message.

func LogInfof

func LogInfof(format string, a ...interface{})

LogInfof formats according to a format specifier and writes to the Zabbix log file with an informational message.

func LogWarningf

func LogWarningf(format string, a ...interface{})

LogWarningf formats according to a format specifier and writes to the Zabbix log file with a warning message.

func RegisterDiscoveryItem

func RegisterDiscoveryItem(key string, testParams string, handler DiscoveryItemHandlerFunc)

RegisterDiscoveryItem registers an agent item key, its test parameters and a handler function with Zabbix for a key which returns DiscoveryData.

This function should only be called from `init()`

Example
package main

import (
	"fmt"
	"github.com/cavaliercoder/g2z"
)

func main() {
	panic("THIS_SHOULD_NEVER_HAPPEN")
}

func init() {
	g2z.RegisterDiscoveryItem("go.discovery", "", Discover)
}

func Discover(request *g2z.AgentRequest) (g2z.DiscoveryData, error) {
	d := make(g2z.DiscoveryData, 5)

	for i := 0; i < 5; i++ {
		d[i] = g2z.DiscoveryItem{
			"index": fmt.Sprintf("%d", i),
		}
	}

	return d, nil
}
Output:

func RegisterDoubleItem

func RegisterDoubleItem(key string, testParams string, handler DoubleItemHandlerFunc)

RegisterDoubleItem registers an agent item key, its test parameters and a handler function with Zabbix for a key which returns a double precision floating point integer.

This function should only be called from `init()`

Example
package main

import (
	"github.com/cavaliercoder/g2z"
)

func main() {
	panic("THIS_SHOULD_NEVER_HAPPEN")
}

func init() {
	g2z.RegisterDoubleItem("go.double", "", Double)
}

func Double(request *g2z.AgentRequest) (float64, error) {
	return 1.23456, nil
}
Output:

func RegisterInitHandler

func RegisterInitHandler(handler InitHandlerFunc)

RegisterInitHandler should be called from init() to register an InitHandlerFunc which will be called when Zabbix calls zbx_module_init().

Example
package main

import (
	"github.com/cavaliercoder/g2z"
)

func main() {
	panic("THIS_SHOULD_NEVER_HAPPEN")
}

func init() {
	g2z.RegisterInitHandler(MyInitFunc)
}

func MyInitFunc() error {
	g2z.LogInfof("MyModule loaded")
	return nil
}
Output:

func RegisterStringItem

func RegisterStringItem(key string, testParams string, handler StringItemHandlerFunc)

RegisterStringItem registers an agent item key, its test parameters and a handler function with Zabbix for a key which returns a string.

This function should only be called from `init()`

Example
package main

import (
	"github.com/cavaliercoder/g2z"
	"strings"
)

func main() {
	panic("THIS_SHOULD_NEVER_HAPPEN")
}

func init() {
	g2z.RegisterStringItem("go.echo", "Hello,world", Echo)
}

func Echo(request *g2z.AgentRequest) (string, error) {
	return strings.Join(request.Params, " "), nil
}
Output:

func RegisterUint64Item

func RegisterUint64Item(key string, testParams string, handler Uint64ItemHandlerFunc)

RegisterUint64Item registers an agent item key, its test parameters and a handler function with Zabbix for a key which returns an unsigned integer.

This function should only be called from `init()`

Example
package main

import (
	"github.com/cavaliercoder/g2z"
)

func main() {
	panic("THIS_SHOULD_NEVER_HAPPEN")
}

func init() {
	g2z.RegisterUint64Item("go.ping", "", Ping)
}

func Ping(request *g2z.AgentRequest) (uint64, error) {
	return 1, nil
}
Output:

func RegisterUninitHandler

func RegisterUninitHandler(handler UninitHandlerFunc)

RegisterUninitHandler should be called from init() to register an UninitHandlerFunc which will be called when Zabbix calls zbx_module_uninit().

Example
package main

import (
	"github.com/cavaliercoder/g2z"
)

func main() {
	panic("THIS_SHOULD_NEVER_HAPPEN")
}

func init() {
	g2z.RegisterUninitHandler(MyUninitFunc)
}

func MyUninitFunc() error {
	g2z.LogInfof("MyModule unloaded")
	return nil
}
Output:

Types

type AgentRequest

type AgentRequest struct {
	// Key is the requested agent key (E.g. `agent.version`).
	Key string

	// Params is a slice of strings containing each parameter passed in the agent request for the
	// specified key (E.g. `dummy.echo[<param0>,<param1>]`)
	Params []string
}

A AgentRequest represents an agent item request received from a Zabbix server or perhaps from `zabbix_get`.

type DiscoveryData

type DiscoveryData []DiscoveryItem

DiscoveryData is a slice of DiscoveryItems which is returned for registered discovery rules as a JSON encoded string.

func (DiscoveryData) Json

func (c DiscoveryData) Json() string

Json converts a DiscoveryData struct into a JSON encoded string, compatible with Zabbix Low-Level discovery rules from v2.2.0 and above.

type DiscoveryItem

type DiscoveryItem map[string]string

DiscoveryItem is a map of key/value pairs that represents a single instance of a discovered asset.

type DiscoveryItemHandlerFunc

type DiscoveryItemHandlerFunc func(*AgentRequest) (DiscoveryData, error)

DiscoveryItemHandlerFunc is the function signature for functions which may be registered as an item key handler and return JSON encoded low-level discovery data.

type DoubleItemHandlerFunc

type DoubleItemHandlerFunc func(*AgentRequest) (float64, error)

DoubleItemHandlerFunc is the function signature for functions which may be registered as an item key handler and return a double precision floating point integer value.

type InitHandlerFunc

type InitHandlerFunc func() error

InitHandlerFunc is the function signature for functions which may be registered for callback when a Zabbix agent module is loaded when zbx_module_init() is called.

type StringItemHandlerFunc

type StringItemHandlerFunc func(*AgentRequest) (string, error)

StringItemHandlerFunc is the function signature for functions which may be registered as an item key handler and return a string value.

type Uint64ItemHandlerFunc

type Uint64ItemHandlerFunc func(*AgentRequest) (uint64, error)

Uint64ItemHandlerFunc is the function signature for functions which may be registered as an item key handler and return an unsigned integer value.

type UninitHandlerFunc

type UninitHandlerFunc func() error

UninitHandlerFunc is the function signature for functions which may be registered for callback when a Zabbix agent module is unloaded when zbx_module_uninit() is called.

Directories

Path Synopsis
Package main is a shared library with sample Zabbix bindings which may be loaded into a Zabbix agent or server using the `LoadModule` directive.
Package main is a shared library with sample Zabbix bindings which may be loaded into a Zabbix agent or server using the `LoadModule` directive.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL