collector

package
v1.2.15 Latest Latest
Warning

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

Go to latest
Published: Sep 16, 2023 License: LGPL-3.0 Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Collector

type Collector struct {

	// Target is the addr of the target this collector is responsible for.
	Target string

	// Provider is the session provider to use to establish new sessions with
	// the BMC when required.
	Provider session.Provider

	// Timeout is the time to allow for each collection before returning what we
	// have. This exists to ensure fairness when multiple scrapers are querying
	// the exporter for a given BMC. Collection will return when this duration
	// has passed, or the context expires (whichever happens first).
	Timeout time.Duration

	// Context is our way of passing a context to the Collect() method, so we
	// can implement an end-to-end timeout for the scrape in the exporter. The
	// ultimate aim is to give up scraping before Prometheus gives up on us, so
	// we can return at least a subset of metrics, even if we don't have time to
	// collect them all.
	//
	// This is a huge hack, but it is safe here. Target sets this before calling
	// ServeHTTP() on the http.Handler returned by promhttp for this collector's
	// registry. As access to a given target is serialised by the event loop,
	// there is no race, and no locking is required. See #13 for more context
	// (ba dum tss).
	Context context.Context
	// contains filtered or unexported fields
}

Collector implements the custom collector to scrape metrics from a single BMC on demand. Note this struct is only called by a single Target by a single goroutine, so contrary to the Prometheus docs, is not safe for concurrent use.

func (*Collector) Close

func (c *Collector) Close(ctx context.Context)

Close cleanly terminates the underlying BMC connection and socket that powers the collector. The collector is left in a usable state - calling Collect() will re-establish a connection. The context constrains the time allowed to execute the Close Session command. This is used when the connection is thought to have expired, and when shutting down the entire exporter.

func (*Collector) Collect

func (c *Collector) Collect(ch chan<- prometheus.Metric)

Collect sends a number of commands to the BMC to gather metrics about its current state.

Contrary to the Prometheus docs, this method is *not* safe for calling concurrently: a given BMC is always collected by the same goroutine, so concurrent collections are not possible. If it's possible for Prometheus to do a spurious collection, then we're in trouble, so we don't implement the locking to add complexity and give a false sense of security, when in reality there would be deadlocks.

func (*Collector) Describe

func (c *Collector) Describe(d chan<- *prometheus.Desc)

func (*Collector) LastCollection

func (c *Collector) LastCollection() int64

LastCollection returns when this collector was last invoked as nanoseconds since the Unix epoch. If required, it can be converted to a time.Time using time.Unix(0, <value>). It is used by mapper GC to determine which BMCs are no longer being scraped, so their http.Handlers can be removed.

type Subcollector

type Subcollector interface {

	// Initialise configures this subcollector to work with the provided
	// session, doing any relevant detection. It is expected that the
	// subcollector retain the session. We do it this way to avoid allocating a
	// new subcollector struct each session; instead, subcollectors are bound to
	// the lifetime of the target's prometheus.Collector. This is also necessary
	// to ensure Describe() can be called on that collector at any time. A
	// side-effect is detection must not depend on the machine being on and
	// sensors returning a value.
	//
	// Whether this method should return an error is an interesting discussion.
	// The obvious case is to avoid incomplete initialisation, resulting in us
	// ignoring features of the BMC (e.g. DCMI) because we didn't have enough
	// time to detect them. This would lead to missing metrics for the entire
	// length of the session. The issue is BMCs have a habit of ignoring
	// commands they don't know about. A missed deadline could be us taking too
	// long (e.g. packet loss, high latency), or it could be the BMC ignoring
	// us; we can never be sure which. This is the case with all commands that
	// could be sent in this method. If the implementation is sure it is not
	// sending a command the BMC may not support, it can return an error to void
	// the session and retry next scrape. This is a signal for a human to
	// investigate why it's taking so long.
	//
	// The SDR repo is passed as an optimisation to relieve multiple
	// subcollectors from having to retrieve this several times themselves; it
	// should not be modified.
	//
	// Initialise should (re)allocate as little memory as possible. For example,
	// subcollectors should contain all their commands as fields, lasting for
	// the lifetime of the object, so no allocations occur during initialisation
	// or collection.
	Initialise(context.Context, bmc.Session, bmc.SDRRepository) error

	// Describe is identical to prometheus.Collector's Describe() method. It
	// should statically send all descriptors for metrics the subcollector is
	// capable of yielding to the provided channel.
	Describe(chan<- *prometheus.Desc)

	// Collect sends the relevant commands to the BMC, yielding appropriate
	// metrics. It must return when the context is cancelled. An error should be
	// returned if collection fails to complete successfully, e.g. if the
	// context expires before a valid response is received. Note it should not
	// return an error if the BMC does not support its function, or if a sensor
	// cannot be read, as the machine could be turned off. It is acceptable for
	// this method to panic (e.g. segfault due to nil session) if Initialise()
	// was not called before.
	Collect(context.Context, chan<- prometheus.Metric) error
}

Subcollector is implemented by things that know how to produce a subset of a BMC's metrics. We use this rather than prometheus.Collector, as these collections have a timeout and must be cancellable. This is very similar to the node_exporter's Collector interface.

Jump to

Keyboard shortcuts

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