Написание плагинов

Обзор

Плагин - 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 (смотрите пример выше). По сути это просто оболочка вокруг стандартного журналирования, однако, к сообщениям в журнале будет добавляться префикс [<имя плагина>].