Plugin Development Guide
Learn how to create custom plugins for ZMS
Plugin Development Guide
ZMS uses HashiCorp’s go-plugin framework for a robust plugin system. Plugins run as separate processes and communicate with the main application via gRPC. This provides better isolation, version compatibility, and crash resilience compared to shared libraries.
Architecture Overview
- Main Process: Runs ZMS core application and manages plugin lifecycle
- Plugin Processes: Independent executables that implement observer functionality
- Communication: gRPC-based with Protocol Buffers for data serialization
- Configuration: Sent from main process to plugin via gRPC during initialization
Plugin Structure
A plugin must be implemented as a standalone Go application with the following requirements:
- Package Declaration: Must be
package main - Main Function: Plugin binary entry point that serves the gRPC interface
- Interface Implementation: Must implement
plugin.ObserverGRPCinterface - Base Observer: Should embed
plugin.BaseObserverGRPCfor core functionality
Plugin Template
Here’s a complete template for creating a new plugin:
|
|
Building Plugins
Plugins are built as standalone executables (NOT shared libraries):
|
|
Plugin Configuration
Configure plugins in your zmsd.yaml:
|
|
Available Functionality
Plugins have access to core ZMS functionality through the embedded BaseObserverGRPC:
- Filtering: Use
p.FilterHistory(),p.FilterTrends(),p.FilterEvents()helper methods - Configuration: All settings passed via
InitializeRequestproto message - Logging: Use
p.Loggerfor structured logging - Context: All methods receive context for cancellation/timeout support
Type Conversions
The plugin system uses Protocol Buffers for data serialization. Proto messages use enum types that need to be cast to int32 when working with zbx types:
Proto Enums
proto.ValueType- Data type (FLOAT, CHARACTER, LOG, UNSIGNED, TEXT)proto.EventValue- Event type (RECOVERY, PROBLEM)proto.Severity- Severity level (NOT_CLASSIFIED, INFORMATION, WARNING, AVERAGE, HIGH, DISASTER)
Converting Proto Types to ZBX Types
The BaseObserverGRPC.FilterHistory(), FilterTrends(), and FilterEvents() helper methods automatically handle conversion from proto types to zbx types. When you need to work with raw proto data:
|
|
The proto definitions in pkg/proto/zbx_exports.proto define the enum values to match Zabbix’s internal constants.
Custom Filters
Plugins can implement custom filtering logic by providing their own filter.Filter implementation. This allows plugins to filter data based on criteria beyond tag-based filtering.
Example: LOG Type Filter
The log_print example plugin implements a custom filter that only accepts LOG-type history items:
|
|
To use a custom filter, assign it during plugin initialization:
|
|
Plugin Examples
The examples/plugins/ directory contains working plugin examples:
- log_print: Simple plugin that outputs LOG-type history items to stdout/stderr. Demonstrates custom filtering and basic data processing.
Development Workflow
- Create Plugin: Write your plugin following the template above
- Build: Compile as standalone executable using
go build - Test Locally: Run plugin with ZMS to test functionality
- Deploy: Place compiled executable in plugins directory
- Configure: Add target configuration referencing plugin name
Plugin Architecture Benefits
The gRPC-based plugin system provides:
- Process Isolation: Plugins run as separate processes
- Version Compatibility: No Go version matching required between plugin and main application
- Crash Resilience: Plugin failures don’t affect the main ZMS process
- Type Safety: gRPC with Protocol Buffers ensures correct data serialization
- Configuration Flexibility: Settings sent via gRPC during initialization
- Independent Updates: Plugins can be updated without recompiling ZMS
Plugin Best Practices
- Error Handling: Return errors via
SaveResponsewith error message - Resource Management: Implement cleanup logic in
Cleanup()method - Filter Usage: Use built-in filter helpers (
FilterHistory, etc.) - Logging: Use the provided
Loggerfor consistent logging - Context Awareness: Respect context cancellation in long-running operations
- Testing: Test plugins independently before integrating with ZMS
Troubleshooting
- Plugin Load Errors: Ensure plugin executable has execute permissions
- Connection Failures: Check that plugin implements required gRPC service correctly
- Handshake Errors: Verify
HandshakeConfigmatches between plugin and main app - Data Processing Issues: Check proto conversion and filter logic
- Missing Configuration: Ensure all required fields in
InitializeRequestare handled
Building Multiple Plugins
Use the Makefile to build all plugins at once:
|
|
The Makefile automatically discovers and builds all plugins that have a main.go file in subdirectories of the plugins/ folder.