mirror of
https://gogs.blitter.com/RLabs/xs
synced 2024-08-14 10:26:42 +00:00
FreeBSD 12 support (NOTE: xc not yet functional)
Signed-off-by: Russ Magee <rmagee@gmail.com>
This commit is contained in:
parent
09c2408c06
commit
cba36b66f1
891 changed files with 351 additions and 304834 deletions
189
vendor/gopkg.in/hlandau/measurable.v1/measurable.go
generated
vendored
189
vendor/gopkg.in/hlandau/measurable.v1/measurable.go
generated
vendored
|
@ -1,189 +0,0 @@
|
|||
// Package measurable provides a functionality-free integration nexus for
|
||||
// metric registration.
|
||||
//
|
||||
// Measurable is a Go package for connecting service metrics and metric consumers.
|
||||
//
|
||||
// The most noteworthy feature of measurable is that it doesn't do anything.
|
||||
// It contains no functionality for defining or exporting metrics.
|
||||
//
|
||||
// The purpose of measurable is to act as an integration nexus
|
||||
// (https://www.devever.net/~hl/nexuses), essentially a matchmaker between
|
||||
// application metrics and metric consumers. This creates the important feature
|
||||
// that your application's metrics can be defined completely independently of
|
||||
// *how* those metrics are defined.
|
||||
//
|
||||
// Measurable doesn't implement any metric definition or export logic because it
|
||||
// strives to be a neutral intermediary, which abstracts the interface between
|
||||
// measurables and measurable consumers
|
||||
//
|
||||
// Pursuant to this, package measurable is this and only this: an interface
|
||||
// Measurable which all metrics must implement, and a facility for registering
|
||||
// Measurables and visiting them.
|
||||
package measurable // import "gopkg.in/hlandau/measurable.v1"
|
||||
|
||||
import "sync"
|
||||
import "fmt"
|
||||
|
||||
// Measurable is the interface which must be implemented by any metric item to
|
||||
// be used with package measurable. In the current version, v1, it contains
|
||||
// only the MsName() and MsType() methods. All other functionality must be
|
||||
// obtained by interface upgrades.
|
||||
type Measurable interface {
|
||||
// Returns the name of the metric. Names should be in the style
|
||||
// "alpha.beta.gamma-delta", for example "foo.http.requests.count". That is,
|
||||
// names should be lowercase, should express a hierarchy separated by dots,
|
||||
// and have words separated by dashes.
|
||||
//
|
||||
// Some Measurable consumers may mutate these names to satisfy naming
|
||||
// restrictions applied by some graphing systems.
|
||||
MsName() string
|
||||
|
||||
// Return the Measurable type. You can, of course, invent your own Measurable
|
||||
// types, though consumers won't necessarily know what to do with them.
|
||||
MsType() Type
|
||||
}
|
||||
|
||||
var measurablesMutex sync.RWMutex
|
||||
var measurables = map[string]Measurable{}
|
||||
|
||||
// Registers a top-level Configurable.
|
||||
func Register(measurable Measurable) {
|
||||
measurablesMutex.Lock()
|
||||
defer measurablesMutex.Unlock()
|
||||
|
||||
if measurable == nil {
|
||||
panic("cannot register nil measurable")
|
||||
}
|
||||
|
||||
name := measurable.MsName()
|
||||
if name == "" {
|
||||
panic("measurable cannot have empty name")
|
||||
}
|
||||
|
||||
_, exists := measurables[name]
|
||||
if exists {
|
||||
panic(fmt.Sprintf("A measurable with the same name already exists: %s", name))
|
||||
}
|
||||
|
||||
measurables[name] = measurable
|
||||
callRegistrationHooks(measurable, RegisterEvent)
|
||||
}
|
||||
|
||||
func Unregister(measurableName string) {
|
||||
measurablesMutex.Lock()
|
||||
defer measurablesMutex.Unlock()
|
||||
|
||||
measurable, ok := measurables[measurableName]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
callRegistrationHooks(measurable, UnregisterEvent)
|
||||
delete(measurables, measurableName)
|
||||
}
|
||||
|
||||
func Get(measurableName string) Measurable {
|
||||
measurablesMutex.RLock()
|
||||
defer measurablesMutex.RUnlock()
|
||||
|
||||
return measurables[measurableName]
|
||||
}
|
||||
|
||||
// Visits all registered top-level Measurables.
|
||||
//
|
||||
// Returning a non-nil error short-circuits the iteration process and returns
|
||||
// that error.
|
||||
func Visit(do func(measurable Measurable) error) error {
|
||||
measurablesMutex.Lock()
|
||||
defer measurablesMutex.Unlock()
|
||||
|
||||
for _, measurable := range measurables {
|
||||
err := do(measurable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Represents a measurable type.
|
||||
type Type uint32
|
||||
|
||||
const (
|
||||
// A CounterType Measurable represents a non-negative integral value
|
||||
// that monotonously increases. It must implement `MsInt64() int64`.
|
||||
CounterType Type = 0x436E7472
|
||||
|
||||
// A GaugeType Measurable represents an integral value that varies over
|
||||
// time. It must implement `MsInt64() int64`.
|
||||
GaugeType = 0x47617567
|
||||
)
|
||||
|
||||
// Registration hooks.
|
||||
type HookEvent int
|
||||
|
||||
const (
|
||||
// This event is issued when a measurable is registered.
|
||||
RegisterEvent HookEvent = iota
|
||||
|
||||
// This event is issued when a registration hook is registered. It is issued
|
||||
// for every measurable which has already been registered.
|
||||
RegisterCatchupEvent
|
||||
|
||||
// This event is issued when a measurable is unregistered.
|
||||
UnregisterEvent
|
||||
)
|
||||
|
||||
type HookFunc func(measurable Measurable, hookEvent HookEvent)
|
||||
|
||||
var hooksMutex sync.RWMutex
|
||||
var hooks = map[interface{}]HookFunc{}
|
||||
|
||||
// Register for notifications on metric registration. The key must be usable as
|
||||
// a key in a map and identifies the hook. No other hook with the same key must
|
||||
// already exist.
|
||||
//
|
||||
// NOTE: The hook will be called for all registrations which already exist.
|
||||
// This ensures that no registrations are missed in a threadsafe manner.
|
||||
// For these calls, the event will be EventRegisterCatchup.
|
||||
//
|
||||
// The hook must not register or unregister registration hooks or metrics.
|
||||
func RegisterHook(key interface{}, hook HookFunc) {
|
||||
measurablesMutex.RLock()
|
||||
defer measurablesMutex.RUnlock()
|
||||
|
||||
registerHook(key, hook)
|
||||
|
||||
for _, m := range measurables {
|
||||
hook(m, RegisterCatchupEvent)
|
||||
}
|
||||
}
|
||||
|
||||
func registerHook(key interface{}, hook HookFunc) {
|
||||
hooksMutex.Lock()
|
||||
defer hooksMutex.Unlock()
|
||||
|
||||
_, exists := hooks[key]
|
||||
if exists {
|
||||
panic(fmt.Sprintf("A metric registration hook with the same key already exists: %+v", key))
|
||||
}
|
||||
|
||||
hooks[key] = hook
|
||||
}
|
||||
|
||||
// Unregister an existing hook.
|
||||
func UnregisterHook(key interface{}) {
|
||||
hooksMutex.Lock()
|
||||
defer hooksMutex.Unlock()
|
||||
delete(hooks, key)
|
||||
}
|
||||
|
||||
func callRegistrationHooks(measurable Measurable, event HookEvent) {
|
||||
hooksMutex.RLock()
|
||||
defer hooksMutex.RUnlock()
|
||||
|
||||
for _, v := range hooks {
|
||||
v(measurable, event)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue