Написание плагинов
Обзор
Плагин - Go пакет, который определяет структуру и реализует один или несколько интерфейсов плагина (Exporter, Collector, Runner, Watcher):
- plugin.Exporter
Exporter - простейший интерфейс, который выполняет опрос и возвращает значение (значения), ничего, ошибку. Он принимает предварительно обработанные ключ элемента данных, параметры и контекст. Интерфейс Exporter является единственным интерфейсом, к которому можно получить доступ на конкурентной основе. Доступ ко всем остальным интерфейсам плагина эксклюзивный и нельзя вызвать никакой метод, когда плагин уже выполняет какую-нибудь задачу. Также имеется ограничение в 100 максимальных параллельных вызовов Export() на каждый плагин, это значение можно уменьшить, по мере необходимости, каждому плагину отдельно.
- plugin.Collector
Collector используется, когда плагину требуется сбор данных на основе регулярных интервалов. Этот интерфейс обычно используется совместно с Exporter интерфейсом для экспорта собранных данных.
- plugin.Runner
Интерфейс Runner предоставляет средства для выполнения некоторой инициализации при запуске плагина (активизации) и деинициализации при остановке плагина (деактивации). Например, плагин может запускать / останавливать какие-либо фоновые goroutine, реализуя задуманное в Runner интерфейсе.
- plugin.Watcher
Watcher позволяет плагину реализовать свой собственный опрос метрик, без использования внутреннего планировщика агента, например, в плагинах на основе трапов.
По умолчанию плагины неактивны и активируются только когда какая-либо метрика, предлагаемая плагином, начинает наблюдаться.
Плагины располагаются в дереве директории плагинов, сгруппированные по
смыслу, например plugins/system/uptime/uptime.go.
Шаги реализации
Плагин должен импортировать go/internal/plugin пакет.
import "go/internal/plugin"
Плагин должен определять структуру и встраивать plugin.Base структуру.
type Plugin struct {
plugin.Base
}
var impl Plugin
Плагин должен реализовать один или несколько интерфейсов плагина.
func (p *Plugin) Export(key string, params []string) (result interface{}, err error) {
if len(params) > 0 {
p.Debugf("received %d parameters while expected none", len(params))
return nil, errors.New("Too many parameters")
}
return time.Now().Format(time.RFC3339)
}
Плагин должен зарегистрировать себя в процессе инициализации.
func init() {
plugin.RegisterMetric(&impl, "Time", "system.time", "Returns time string in RFC 3999 format.")
}
где RegisterMetric параметры:
- Указатель на реализацию плагина
- Имя плагина (верхний camel-регистр)
- Имя метрики (ключ элемента данных)
- Описание плагина (начиная с символа в верхнем регистре и заканчивая точкой)
Если требуется журналирование, плагин должен использовать функционал журналирования, который поставляется plugin.Base (смотрите пример выше). По сути это просто оболочка вокруг стандартного журналирования, однако, к сообщениям в журнале будет добавляться префикс [<имя плагина>].