func NewStandardBackend() Backend {
	m := &stdBackend{
		measuringC:             make(chan *stdMeasuring, 1024),
		ssvChangeC:             make(chan *stdSSVChange, 1024),
		retrieverRegistrationC: make(chan *stdRetrieverRegistration),
		commandC:               make(chan *command),
	}
	m.backend = loop.GoRecoverable(m.backendLoop, m.checkRecovering, "monitoring backend")
	return m
}
NewStandardBackend starts the standard monitoring backend.
package monitoring
import (
	"fmt"
	"sort"
	"time"
	"github.com/tideland/golib/errors"
	"github.com/tideland/golib/logger"
	"github.com/tideland/golib/loop"
)
const (
	cmdReset = iota
	cmdMeasuringPointRead
	cmdMeasuringPointsReadAll
	cmdStaySetVariableRead
	cmdStaySetVariablesReadAll
	cmdDynamicStatusRetrieverRead
	cmdDynamicStatusRetrieversReadAll
)
type command struct {
	opCode   int
	args     interface{}
	respChan chan interface{}
}
func (c *command) respond(v interface{}) {
	c.respChan <- v
}
func (c *command) ok() {
	c.respond(true)
}
func (c *command) close() {
	close(c.respChan)
}
type stdMeasuring struct {
	backend   *stdBackend
	id        string
	startTime time.Time
	duration  time.Duration
}
func (m *stdMeasuring) EndMeasuring() time.Duration {
	if m.backend == nil {
		return 0
	}
	m.duration = time.Since(m.startTime)
	m.backend.measuringC <- m
	return m.duration
}
type stdMeasuringPoint struct {
	id          string
	count       int64
	minDuration time.Duration
	maxDuration time.Duration
	avgDuration time.Duration
}
func newStdMeasuringPoint(m *stdMeasuring) *stdMeasuringPoint {
	return &stdMeasuringPoint{
		id:          m.id,
		count:       1,
		minDuration: m.duration,
		maxDuration: m.duration,
		avgDuration: m.duration,
	}
}
func (mp *stdMeasuringPoint) ID() string { return mp.id }
func (mp *stdMeasuringPoint) Count() int64 { return mp.count }
func (mp *stdMeasuringPoint) MinDuration() time.Duration { return mp.minDuration }
func (mp *stdMeasuringPoint) MaxDuration() time.Duration { return mp.maxDuration }
func (mp *stdMeasuringPoint) AvgDuration() time.Duration { return mp.avgDuration }
func (mp *stdMeasuringPoint) update(m *stdMeasuring) {
	average := mp.avgDuration.Nanoseconds()
	mp.count++
	if mp.minDuration > m.duration {
		mp.minDuration = m.duration
	}
	if mp.maxDuration < m.duration {
		mp.maxDuration = m.duration
	}
	mp.avgDuration = time.Duration((average + m.duration.Nanoseconds()) / 2)
}
func (mp *stdMeasuringPoint) String() string {
	return fmt.Sprintf("Measuring Point %q (%dx / min %s / max %s / avg %s)", mp.id, mp.count, mp.minDuration, mp.maxDuration, mp.avgDuration)
}
type stdSSVChange struct {
	id       string
	absolute bool
	variable int64
}
type stdStaySetVariable struct {
	id       string
	count    int64
	actValue int64
	minValue int64
	maxValue int64
	avgValue int64
	total    int64
}
func newStdStaySetVariable(v *stdSSVChange) *stdStaySetVariable {
	return &stdStaySetVariable{
		id:       v.id,
		count:    1,
		actValue: v.variable,
		minValue: v.variable,
		maxValue: v.variable,
		avgValue: v.variable,
	}
}
func (ssv *stdStaySetVariable) ID() string { return ssv.id }
func (ssv *stdStaySetVariable) Count() int64 { return ssv.count }
func (ssv *stdStaySetVariable) ActValue() int64 { return ssv.actValue }
func (ssv *stdStaySetVariable) MinValue() int64 { return ssv.minValue }
func (ssv *stdStaySetVariable) MaxValue() int64 { return ssv.maxValue }
func (ssv *stdStaySetVariable) AvgValue() int64 { return ssv.avgValue }
func (ssv *stdStaySetVariable) update(chg *stdSSVChange) {
	ssv.count++
	if chg.absolute {
		ssv.actValue = chg.variable
	} else {
		ssv.actValue += chg.variable
	}
	ssv.total += chg.variable
	if ssv.minValue > ssv.actValue {
		ssv.minValue = ssv.actValue
	}
	if ssv.maxValue < ssv.actValue {
		ssv.maxValue = ssv.actValue
	}
	ssv.avgValue = ssv.total / ssv.count
}
func (ssv *stdStaySetVariable) String() string {
	return fmt.Sprintf("Stay-Set Variable %q (%dx / act %d / min %d / max %d / avg %d)",
		ssv.id, ssv.count, ssv.actValue, ssv.minValue, ssv.maxValue, ssv.avgValue)
}
type stdRetrieverRegistration struct {
	id  string
	dsr DynamicStatusRetriever
}
type stdDynamicStatusValue struct {
	id    string
	value string
}
func (dsv *stdDynamicStatusValue) ID() string { return dsv.id }
func (dsv *stdDynamicStatusValue) Value() string { return dsv.value }
func (dsv *stdDynamicStatusValue) String() string {
	return fmt.Sprintf("Dynamic Status Value %q (value = %q)", dsv.id, dsv.value)
}
type stdBackend struct {
	etmFilter              IDFilter
	ssvFilter              IDFilter
	dsrFilter              IDFilter
	etmData                map[string]*stdMeasuringPoint
	ssvData                map[string]*stdStaySetVariable
	dsrData                map[string]DynamicStatusRetriever
	measuringC             chan *stdMeasuring
	ssvChangeC             chan *stdSSVChange
	retrieverRegistrationC chan *stdRetrieverRegistration
	commandC               chan *command
	backend                loop.Loop
}