366 lines
12 KiB
Go
366 lines
12 KiB
Go
|
// Licensed to Elasticsearch B.V. under one or more contributor
|
||
|
// license agreements. See the NOTICE file distributed with
|
||
|
// this work for additional information regarding copyright
|
||
|
// ownership. Elasticsearch B.V. licenses this file to you under
|
||
|
// the Apache License, Version 2.0 (the "License"); you may
|
||
|
// not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing,
|
||
|
// software distributed under the License is distributed on an
|
||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
// KIND, either express or implied. See the License for the
|
||
|
// specific language governing permissions and limitations
|
||
|
// under the License.
|
||
|
|
||
|
/*
|
||
|
Package mb (short for Metricbeat) contains the public interfaces that are used
|
||
|
to implement Modules and their associated MetricSets.
|
||
|
*/
|
||
|
package mb
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net/url"
|
||
|
"time"
|
||
|
|
||
|
"github.com/elastic/beats/libbeat/common"
|
||
|
"github.com/elastic/beats/libbeat/monitoring"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
// TimestampKey is the key used in events created by MetricSets to add their
|
||
|
// own timestamp to an event. If a timestamp is not specified then the that
|
||
|
// the fetch started will be used.
|
||
|
TimestampKey string = "@timestamp"
|
||
|
|
||
|
// ModuleDataKey is the key used in events created by MetricSets to add data
|
||
|
// to an event that is common to the module. The data must be a
|
||
|
// common.MapStr and when the final event is built the object will be stored
|
||
|
// in the event under a key that is the module name.
|
||
|
ModuleDataKey string = "_module"
|
||
|
|
||
|
// NamespaceKey is used to define a different namespace for the metricset
|
||
|
// This is useful for dynamic metricsets or metricsets which do not
|
||
|
// put the name under the same name as the package. This is for example
|
||
|
// the case in elasticsearch `node_stats` which puts the data under `node.stats`.
|
||
|
NamespaceKey string = "_namespace"
|
||
|
|
||
|
// RTTKey is used by a MetricSet to specify the round trip time (RTT), or
|
||
|
// total amount of time, taken to collect the information in the event. The
|
||
|
// data must be of type time.Duration otherwise the value is ignored.
|
||
|
RTTKey string = "_rtt"
|
||
|
)
|
||
|
|
||
|
// Module interfaces
|
||
|
|
||
|
// Module is the common interface for all Module implementations.
|
||
|
type Module interface {
|
||
|
Name() string // Name returns the name of the Module.
|
||
|
Config() ModuleConfig // Config returns the ModuleConfig used to create the Module.
|
||
|
UnpackConfig(to interface{}) error // UnpackConfig unpacks the raw module config to the given object.
|
||
|
}
|
||
|
|
||
|
// BaseModule implements the Module interface.
|
||
|
//
|
||
|
// When a Module needs to store additional data or provide methods to its
|
||
|
// MetricSets, it can embed this type into another struct to satisfy the
|
||
|
// Module interface requirements.
|
||
|
type BaseModule struct {
|
||
|
name string
|
||
|
config ModuleConfig
|
||
|
rawConfig *common.Config
|
||
|
}
|
||
|
|
||
|
func (m *BaseModule) String() string {
|
||
|
return fmt.Sprintf(`{name:"%v", config:%v}`, m.name, m.config.String())
|
||
|
}
|
||
|
|
||
|
func (m *BaseModule) GoString() string { return m.String() }
|
||
|
|
||
|
// Name returns the name of the Module.
|
||
|
func (m *BaseModule) Name() string { return m.name }
|
||
|
|
||
|
// Config returns the ModuleConfig used to create the Module.
|
||
|
func (m *BaseModule) Config() ModuleConfig { return m.config }
|
||
|
|
||
|
// UnpackConfig unpacks the raw module config to the given object.
|
||
|
func (m *BaseModule) UnpackConfig(to interface{}) error {
|
||
|
return m.rawConfig.Unpack(to)
|
||
|
}
|
||
|
|
||
|
// MetricSet interfaces
|
||
|
|
||
|
// MetricSet is the common interface for all MetricSet implementations. In
|
||
|
// addition to this interface, all MetricSets must implement either
|
||
|
// EventFetcher or EventsFetcher (but not both).
|
||
|
type MetricSet interface {
|
||
|
ID() string // Unique ID identifying a running MetricSet.
|
||
|
Name() string // Name returns the name of the MetricSet.
|
||
|
Module() Module // Module returns the parent Module for the MetricSet.
|
||
|
Host() string // Host returns a hostname or other module specific value
|
||
|
// that identifies a specific host or service instance from which to collect
|
||
|
// metrics.
|
||
|
HostData() HostData // HostData returns the parsed host data.
|
||
|
Registration() MetricSetRegistration // Params used in registration.
|
||
|
Metrics() *monitoring.Registry // MetricSet specific metrics
|
||
|
}
|
||
|
|
||
|
// Closer is an optional interface that a MetricSet can implement in order to
|
||
|
// cleanup any resources it has open at shutdown.
|
||
|
type Closer interface {
|
||
|
Close() error
|
||
|
}
|
||
|
|
||
|
// EventFetcher is a MetricSet that returns a single event when collecting data.
|
||
|
// Use ReportingMetricSet for new MetricSet implementations.
|
||
|
type EventFetcher interface {
|
||
|
MetricSet
|
||
|
Fetch() (common.MapStr, error)
|
||
|
}
|
||
|
|
||
|
// EventsFetcher is a MetricSet that returns a multiple events when collecting
|
||
|
// data. Use ReportingMetricSet for new MetricSet implementations.
|
||
|
type EventsFetcher interface {
|
||
|
MetricSet
|
||
|
Fetch() ([]common.MapStr, error)
|
||
|
}
|
||
|
|
||
|
// Reporter is used by a MetricSet to report events, errors, or errors with
|
||
|
// metadata. The methods return false if and only if publishing failed because
|
||
|
// the MetricSet is being closed.
|
||
|
//
|
||
|
// Deprecated: Use ReporterV2.
|
||
|
type Reporter interface {
|
||
|
Event(event common.MapStr) bool // Event reports a single successful event.
|
||
|
ErrorWith(err error, meta common.MapStr) bool // ErrorWith reports a single error event with the additional metadata.
|
||
|
Error(err error) bool // Error reports a single error event.
|
||
|
}
|
||
|
|
||
|
// ReportingMetricSet is a MetricSet that reports events or errors through the
|
||
|
// Reporter interface. Fetch is called periodically to collect events.
|
||
|
//
|
||
|
// Deprecated: Use ReportingMetricSetV2.
|
||
|
type ReportingMetricSet interface {
|
||
|
MetricSet
|
||
|
Fetch(r Reporter)
|
||
|
}
|
||
|
|
||
|
// PushReporter is used by a MetricSet to report events, errors, or errors with
|
||
|
// metadata. It provides a done channel used to signal that reporter should
|
||
|
// stop.
|
||
|
//
|
||
|
// Deprecated: Use PushReporterV2.
|
||
|
type PushReporter interface {
|
||
|
Reporter
|
||
|
|
||
|
// Done returns a channel that's closed when work done on behalf of this
|
||
|
// reporter should be canceled.
|
||
|
Done() <-chan struct{}
|
||
|
}
|
||
|
|
||
|
// PushMetricSet is a MetricSet that pushes events (rather than pulling them
|
||
|
// periodically via a Fetch callback). Run is invoked to start the event
|
||
|
// subscription and it should block until the MetricSet is ready to stop or
|
||
|
// the PushReporter's done channel is closed.
|
||
|
//
|
||
|
// Deprecated: Use PushMetricSetV2.
|
||
|
type PushMetricSet interface {
|
||
|
MetricSet
|
||
|
Run(r PushReporter)
|
||
|
}
|
||
|
|
||
|
// V2 Interfaces
|
||
|
|
||
|
// ReporterV2 is used by a MetricSet to report Events. The methods return false
|
||
|
// if and only if publishing failed because the MetricSet is being closed.
|
||
|
type ReporterV2 interface {
|
||
|
Event(event Event) bool // Event reports a single successful event.
|
||
|
Error(err error) bool
|
||
|
}
|
||
|
|
||
|
// PushReporterV2 is used by a MetricSet to report events, errors, or errors with
|
||
|
// metadata. It provides a done channel used to signal that reporter should
|
||
|
// stop.
|
||
|
type PushReporterV2 interface {
|
||
|
ReporterV2
|
||
|
|
||
|
// Done returns a channel that's closed when work done on behalf of this
|
||
|
// reporter should be canceled.
|
||
|
Done() <-chan struct{}
|
||
|
}
|
||
|
|
||
|
// ReportingMetricSetV2 is a MetricSet that reports events or errors through the
|
||
|
// ReporterV2 interface. Fetch is called periodically to collect events.
|
||
|
type ReportingMetricSetV2 interface {
|
||
|
MetricSet
|
||
|
Fetch(r ReporterV2)
|
||
|
}
|
||
|
|
||
|
// PushMetricSetV2 is a MetricSet that pushes events (rather than pulling them
|
||
|
// periodically via a Fetch callback). Run is invoked to start the event
|
||
|
// subscription and it should block until the MetricSet is ready to stop or
|
||
|
// the PushReporterV2's done channel is closed.
|
||
|
type PushMetricSetV2 interface {
|
||
|
MetricSet
|
||
|
Run(r PushReporterV2)
|
||
|
}
|
||
|
|
||
|
// HostData contains values parsed from the 'host' configuration. Other
|
||
|
// configuration data like protocols, usernames, and passwords may also be
|
||
|
// used to construct this HostData data.
|
||
|
type HostData struct {
|
||
|
URI string // The full URI that should be used in connections.
|
||
|
SanitizedURI string // A sanitized version of the URI without credentials.
|
||
|
|
||
|
// Parts of the URI.
|
||
|
|
||
|
Host string // The host and possibly port.
|
||
|
User string // Username
|
||
|
Password string // Password
|
||
|
}
|
||
|
|
||
|
func (h HostData) String() string {
|
||
|
return fmt.Sprintf(`{SanitizedURI:"%v", Host:"%v"}`, h.SanitizedURI, h.Host)
|
||
|
}
|
||
|
|
||
|
func (h HostData) GoString() string { return h.String() }
|
||
|
|
||
|
// BaseMetricSet implements the MetricSet interface.
|
||
|
//
|
||
|
// The BaseMetricSet type can be embedded into another struct to satisfy the
|
||
|
// MetricSet interface requirements, leaving only the Fetch() method to be
|
||
|
// implemented to have a complete MetricSet implementation.
|
||
|
type BaseMetricSet struct {
|
||
|
id string
|
||
|
name string
|
||
|
module Module
|
||
|
host string
|
||
|
hostData HostData
|
||
|
registration MetricSetRegistration
|
||
|
metrics *monitoring.Registry
|
||
|
}
|
||
|
|
||
|
func (b *BaseMetricSet) String() string {
|
||
|
moduleName := "nil"
|
||
|
if b.module != nil {
|
||
|
moduleName = b.module.Name()
|
||
|
}
|
||
|
return fmt.Sprintf(`{name:"%v", module:"%v", hostData:%v, registration:%v}`,
|
||
|
b.name, moduleName, b.hostData.String(), b.registration)
|
||
|
}
|
||
|
|
||
|
func (b *BaseMetricSet) GoString() string { return b.String() }
|
||
|
|
||
|
// ID returns the unique ID of the MetricSet.
|
||
|
func (b *BaseMetricSet) ID() string {
|
||
|
return b.id
|
||
|
}
|
||
|
|
||
|
// Metrics returns the metrics registry.
|
||
|
func (b *BaseMetricSet) Metrics() *monitoring.Registry {
|
||
|
return b.metrics
|
||
|
}
|
||
|
|
||
|
// Name returns the name of the MetricSet. It should not include the name of
|
||
|
// the module.
|
||
|
func (b *BaseMetricSet) Name() string {
|
||
|
return b.name
|
||
|
}
|
||
|
|
||
|
// FullyQualifiedName returns the complete name of the MetricSet, including the
|
||
|
// name of the module.
|
||
|
func (b *BaseMetricSet) FullyQualifiedName() string {
|
||
|
return b.Module().Name() + "/" + b.Name()
|
||
|
}
|
||
|
|
||
|
// Module returns the parent Module for the MetricSet.
|
||
|
func (b *BaseMetricSet) Module() Module {
|
||
|
return b.module
|
||
|
}
|
||
|
|
||
|
// Host returns the hostname or other module specific value that identifies a
|
||
|
// specific host or service instance from which to collect metrics.
|
||
|
func (b *BaseMetricSet) Host() string {
|
||
|
return b.host
|
||
|
}
|
||
|
|
||
|
// HostData returns the parsed host data.
|
||
|
func (b *BaseMetricSet) HostData() HostData {
|
||
|
return b.hostData
|
||
|
}
|
||
|
|
||
|
// Registration returns the parameters that were used when the MetricSet was
|
||
|
// registered with the registry.
|
||
|
func (b *BaseMetricSet) Registration() MetricSetRegistration {
|
||
|
return b.registration
|
||
|
}
|
||
|
|
||
|
// Configuration types
|
||
|
|
||
|
// ModuleConfig is the base configuration data for all Modules.
|
||
|
//
|
||
|
// The Raw config option is used to enable raw fields in a metricset. This means
|
||
|
// the metricset fetches not only the predefined fields but add alls raw data under
|
||
|
// the raw namespace to the event.
|
||
|
type ModuleConfig struct {
|
||
|
Hosts []string `config:"hosts"`
|
||
|
Period time.Duration `config:"period" validate:"positive"`
|
||
|
Timeout time.Duration `config:"timeout" validate:"positive"`
|
||
|
Module string `config:"module" validate:"required"`
|
||
|
MetricSets []string `config:"metricsets"`
|
||
|
Enabled bool `config:"enabled"`
|
||
|
Raw bool `config:"raw"`
|
||
|
Query QueryParams `config:"query"`
|
||
|
}
|
||
|
|
||
|
func (c ModuleConfig) String() string {
|
||
|
return fmt.Sprintf(`{Module:"%v", MetricSets:%v, Enabled:%v, `+
|
||
|
`Hosts:[%v hosts], Period:"%v", Timeout:"%v", Raw:%v, Query:%v}`,
|
||
|
c.Module, c.MetricSets, c.Enabled, len(c.Hosts), c.Period, c.Timeout,
|
||
|
c.Raw, c.Query)
|
||
|
}
|
||
|
|
||
|
func (c ModuleConfig) GoString() string { return c.String() }
|
||
|
|
||
|
// QueryParams is a convenient map[string]interface{} wrapper to implement the String interface which returns the
|
||
|
// values in common query params format (key=value&key2=value2) which is the way that the url package expects this
|
||
|
// params (without the initial '?')
|
||
|
type QueryParams map[string]interface{}
|
||
|
|
||
|
// String returns the values in common query params format (key=value&key2=value2) which is the way that the url
|
||
|
// package expects this params (without the initial '?')
|
||
|
func (q QueryParams) String() (s string) {
|
||
|
u := url.Values{}
|
||
|
|
||
|
for k, v := range q {
|
||
|
if values, ok := v.([]interface{}); ok {
|
||
|
for _, innerValue := range values {
|
||
|
u.Add(k, fmt.Sprintf("%v", innerValue))
|
||
|
}
|
||
|
} else {
|
||
|
//nil values in YAML shouldn't be stringified anyhow
|
||
|
if v == nil {
|
||
|
u.Add(k, "")
|
||
|
} else {
|
||
|
u.Add(k, fmt.Sprintf("%v", v))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return u.Encode()
|
||
|
}
|
||
|
|
||
|
// defaultModuleConfig contains the default values for ModuleConfig instances.
|
||
|
var defaultModuleConfig = ModuleConfig{
|
||
|
Enabled: true,
|
||
|
Period: time.Second * 10,
|
||
|
}
|
||
|
|
||
|
// DefaultModuleConfig returns a ModuleConfig with the default values populated.
|
||
|
func DefaultModuleConfig() ModuleConfig {
|
||
|
return defaultModuleConfig
|
||
|
}
|