Documentation ¶
Overview ¶
Package dagr is an InfluxDB measurement library.
You can use dagr to keeping track of and write primitive types understood by InfluxDB. Measurements are written in line protocol format, per InfluxDB 0.9.x docs:
- Line Protocol: https://influxdb.com/docs/v0.9/write_protocols/line.html - Line Protocol Syntax: https://influxdb.com/docs/v0.9/write_protocols/write_syntax.html
dagr has a handful of types, Int, Float, Bool, and String, that allow atomic updates to their values from concurrent goroutines, and a few provisions for writing measurements in line protocol format.
Index ¶
- Constants
- Variables
- func AddFloat(field Field, incr float64) bool
- func AddInt(field Field, incr int64) bool
- func WriteMeasurement(w io.Writer, m Measurement) (n int64, err error)
- func WriteMeasurements(w io.Writer, ms ...Measurement) (n int64, err error)
- type Bool
- type Error
- type Field
- type Fields
- type Float
- type FloatAdder
- type Int
- type IntAdder
- type Logger
- type Measurement
- type Point
- func (p *Point) Compiled() Measurement
- func (p *Point) GetFields() Fields
- func (p *Point) GetKey() string
- func (p *Point) GetTags() Tags
- func (p *Point) MarshalJSON() ([]byte, error)
- func (p *Point) RemoveField(name string)
- func (p *Point) RemoveTag(name string)
- func (p *Point) SetField(name string, value Field)
- func (p *Point) SetKey(key string)
- func (p *Point) SetTag(name, value string)
- func (p *Point) WriteTo(w io.Writer) (int64, error)
- type PointAllocFunc
- type PointAllocator
- type PointSet
- func (p *PointSet) Clear()
- func (p *PointSet) FieldsForID(identifier string, opaque interface{}) Fields
- func (p *PointSet) GetFields() Fields
- func (p *PointSet) GetKey() string
- func (p *PointSet) GetTags() Tags
- func (p *PointSet) Remove(identifier string)
- func (p *PointSet) WriteTo(w io.Writer) (int64, error)
- type RawBool
- type RawFloat
- type RawInt
- type RawPoint
- type RawString
- type SnapshotField
- type SnapshotMeasurement
- type StaticPointAllocator
- type String
- type Tags
- type TimeMeasurement
Examples ¶
Constants ¶
const ( ErrNoFields = Error(1 + iota) // Returned by WriteMeasurement(s) when a measurement has no fields ErrEmptyKey // Used to panic when attempting to allocate a point with an empty key ErrNoAllocator // Used to panic when attempting to allocate a PointSet with a nil allocator )
Variables ¶
var ( DiscardLogger = discardLogger{} StdLogger = defaultLogger{} Log Logger = DiscardLogger )
Functions ¶
func AddFloat ¶
AddFloat adds incr to any field that implements either FloatAdder or IntAdder (by converting incr to an int64) and returns true. If the field doesn't implement either interface, it returns false. If field is nil, it returns false.
func AddInt ¶
AddInt adds incr to any field that implements either IntAdder or FloatAdder (by converting incr to a float64) and returns true. If the field doesn't implement either interface, it returns false. This can be used to interact with elements of Fields without requiring you to perform type assertions. If field is nil, it returns false.
func WriteMeasurement ¶
func WriteMeasurement(w io.Writer, m Measurement) (n int64, err error)
WriteMeasurement writes a single measurement, m, to w. It returns the number of bytes written and any error that occurred when writing the measurement.
When writing tags and fields, both are sorted by name in ascending order. So, a tag named "pid" will precede a tag named "version", and a field name "depth" will precede a field named "value".
If the measurement has no fields, it returns 0 and ErrNoFields.
If the measurement implements io.WriterTo, this simply calls that instead of WriteMeasurement.
Example ¶
integer := new(Int) boolean := new(Bool) float := new(Float) str := new(String) integer.Set(123) boolean.Set(true) float.Set(123.456) str.Set(`a "string" of sorts`) m := NewPoint( "service.some_event", Tags{"pid": fmt.Sprint(1234), "host": "example.local"}, Fields{"value": integer, "depth": float, "on": boolean, "msg": str}, ) WriteMeasurement(os.Stdout, m)
Output: service.some_event,host=example.local,pid=1234 depth=123.456,msg="a \"string\" of sorts",on=T,value=123i 1136214245000000000
Example (Compiled) ¶
Compiled measurements can be used to speed up encoding if you're frequently writing a large number of measurements. In most cases, this is entirely unnecessary. Compiled measurements only update their field values and are otherwise immutable.
integer := new(Int) boolean := new(Bool) float := new(Float) str := new(String) integer.Set(123) boolean.Set(true) float.Set(123.456) str.Set(`a "string" of sorts`) m := NewPoint( "service.some_event", Tags{"pid": fmt.Sprint(1234), "host": "example.local"}, Fields{"value": integer, "depth": float, "on": boolean, "msg": str}, ).Compiled() WriteMeasurement(os.Stdout, m)
Output: service.some_event,host=example.local,pid=1234 depth=123.456,msg="a \"string\" of sorts",on=T,value=123i 1136214245000000000
func WriteMeasurements ¶
func WriteMeasurements(w io.Writer, ms ...Measurement) (n int64, err error)
WriteMeasurements writes all measurements with fields to w. Like WriteMeasurement, this will buffer the measurements before writing them in their entirety to w. This is effectively the same as iterating over ms and writing each measurement to a temporary buffer before writing to w.
Unlike WriteMeasurement, this will not return an error if a measurement has no fields. Measurements without fields are silently ignored. If no measurements are written, WriteMeasurements returns 0 and nil.
Types ¶
type Bool ¶
type Bool uint32
Bool is a Field that stores an InfluxDB boolean value. When written, it is encoded as either T or F, depending on its value. Its zero value is false.
func (*Bool) MarshalJSON ¶
func (*Bool) UnmarshalJSON ¶
type Error ¶
type Error int
Error is any error code that is returned by a dagr function or method or might be worth catching a panic on.
type Field ¶
Field is any field value an InfluxDB measurement may hold. Fields must be duplicate-able (e.g., for snapshotting and such). Methods that modify field state must be safe for use across multiple goroutines. If the type implementing Field does not have mutable state, it is considered read-only.
In order to keep fields and their names separate, Field is not responsible for writing its name, and should not attempt to write a name, only its value.
type Float ¶
type Float uint64
Float is a Field that stores an InfluxDB float value. When written, it's encoded as a float64 using as few digits as possible (i.e., its precision is -1 when passed to FormatFloat). Different behavior may be desirable, in which case it's necessary to implement your own float field. Updates to Float are atomic.
func (*Float) MarshalJSON ¶
func (*Float) UnmarshalJSON ¶
type FloatAdder ¶
type FloatAdder interface {
Add(float64)
}
FloatAdder defines anything that can have a float64 added to itself (e.g., a Float).
type Int ¶
type Int int64
Int is a Field that stores an InfluxDB integer value. When written, it's encoded as a 64-bit integer with the 'i' suffix, per InfluxDB documentation (e.g., "123456i" sans quotes).
func (*Int) MarshalJSON ¶
func (*Int) UnmarshalJSON ¶
type IntAdder ¶
type IntAdder interface {
Add(int64)
}
IntAdder defines anything that can have an int64 added to itself (e.g., an Int).
type Measurement ¶
Measurement defines the minimum interface for a measurement that could be passed to InfluxDB. All measurements must have a key and a minimum of one field. Tags are optional.
Unless stated otherwise, the results of Tags and Fields are considered immutable.
type Point ¶
type Point struct {
// contains filtered or unexported fields
}
Point is a single Measurement as understood by InfluxDB.
func NewPoint ¶
NewPoint allocates a new Point with the given key, tags, and fields. If key is empty, NewPoint panics. If fields is empty, the point cannot be written until it has at least one field.
func (*Point) Compiled ¶
func (p *Point) Compiled() Measurement
Compiled returns a compiled form of the point. The resulting Measurement is immutable except for its field values. New fields may not be added and it will not return a key, tags, or values. The compiled form of a point is only useful to improve write times on points when necessary. If the point has no fields, it returns nil, as the point is not valid to write.
func (*Point) GetFields ¶
GetFields returns a map of the point's fields. This map is a copy of the point's state and may be modified without affecting the point. The fields themselves are those held by the point, however, and modifying them will modify the point's state.
func (*Point) GetTags ¶
GetTags returns a copy of the point's tags as a map of names to values. Names and values are not escaped. It is safe to copy and modify the result of this method.
func (*Point) MarshalJSON ¶
Example ¶
integer := new(Int) boolean := new(Bool) float := new(Float) str := new(String) integer.Set(123) boolean.Set(true) float.Set(123.456) str.Set(`a "string" of sorts`) m := NewPoint( "service.some_event", Tags{"pid": fmt.Sprint(1234), "host": "example.local"}, Fields{"value": integer, "depth": float, "on": boolean, "msg": str}, ) bs, err := json.MarshalIndent(m, "", " ") if err != nil { panic(err) } fmt.Printf("%s", bs)
Output: { "Key": "service.some_event", "Timestamp": "1136214245000000000", "Tags": { "depth": 123.456, "msg": "a \"string\" of sorts", "on": true, "value": 123 }, "Fields": { "host": "example.local", "pid": "1234" } }
func (*Point) RemoveField ¶
RemoveField removes a field with the given name. If name is empty, the call is a no-op. It is safe to call RemoveField from concurrent goroutines.
func (*Point) RemoveTag ¶
RemoveTag removes the tag with the given name from the point. If name is empty, the call is a no-op. It is safe to call from concurrent goroutines.
func (*Point) SetField ¶
SetField sets a field with the given name and value. If name is empty, the call is a no-op. If value is nil, it removes the field.
type PointAllocFunc ¶
type PointAllocFunc func(identifier string, opaque interface{}) (key string, tags Tags, fields Fields)
func (PointAllocFunc) AllocatePoint ¶
func (fn PointAllocFunc) AllocatePoint(identifier string, opaque interface{}) (key string, tags Tags, fields Fields)
type PointAllocator ¶
type PointAllocator interface {
AllocatePoint(identifier string, opaque interface{}) (key string, tags Tags, fields Fields)
}
PointAllocator is used to prepare a point from an identifier. Given the identifier, the PointAllocator must return a key, tags, and fields for a new Point to use. The PointAllocator can signal that an identifier should not receive a point by returning an empty key or no fields.
The map of tags and fields are copied, so you may return prefabricated maps of tags or fields (though usually you'll want at least one of a unique tag or field per point).
The opaque value has no effect on the identifier, but can be used to pass specific information to affect the result of the allocator (e.g., an *http.Request that might contain a path to include a tag).
type PointSet ¶
type PointSet struct {
// contains filtered or unexported fields
}
PointSet is a simple collection of (compiled) points that supports dynamic allocation and revocation of points. It is intended for situations where you have a single point form varying across a tag or field, such as a request path or some other varying data.
func NewPointSet ¶
func NewPointSet(allocator PointAllocator) *PointSet
NewPointSet allocates a new PointSet with the given allocator. If allocator is nil, the function panics with ErrNoAllocator. You shouldn't bother recovering from this because there is no recovering from a PointSet without an allocator.
func (*PointSet) FieldsForID ¶
FieldsForID returns the fields for a particular identifier. If no point is found and no point can be allocated for the identifier, it returns nil. The identifier may be an empty string.
type RawPoint ¶
RawPoint is a simple Field implementation that has no read/write concurrency guarantees. It's useful as a read-only point that can be written out and quickly discarded. It's a good idea to make use of the raw field types for this as well to avoid the overhead of atomics.
type SnapshotField ¶
Snapshotter is an interface that any Field may implement that returns a more-or-less frozen instance of a field.
type SnapshotMeasurement ¶
type SnapshotMeasurement interface { Measurement Snapshot() TimeMeasurement }
type StaticPointAllocator ¶
type StaticPointAllocator struct { Key string Tags Tags Fields Fields // All fields will be duplicated to ensure that they're unique among points // If either IdnetifierTag or IdentifierField is set, the tag/field with that name will be assigned the // identifier passed to the StaticPointAllocator. IdentifierTag string IdentifierField string }
StaticPointAllocator is a simple PointAllocator that reuses a single key and set of tags and fields.
If fields is nil, IdentifierField must be non-empty, otherwise it will never produce a valid point.
func (StaticPointAllocator) AllocatePoint ¶
func (s StaticPointAllocator) AllocatePoint(identifier string, _ interface{}) (key string, tags Tags, fields Fields)
type String ¶
type String struct {
// contains filtered or unexported fields
}
String is a Field that stores an InfluxDB string value.
func (*String) MarshalJSON ¶
func (*String) UnmarshalJSON ¶
type TimeMeasurement ¶
type TimeMeasurement interface { GetTime() time.Time Measurement }
TimeMeasurement is a measurement that has a known, known, fixed time. It can be considered a measurement that is fixed to a specific point in time. TimeMeasurements are not necessarily read-only and may, for example, return time.Now(). In general, it is better to not implement TimeMeasurement if your measurement is returning time.Now().
func Snapshot ¶
func Snapshot(m Measurement) TimeMeasurement
Snapshot creates and returns a new measurement that implements TimeMeasurement. This Measurement is detached from its original source and is intended to be fixed in time. This is roughly the same as duplicating a point and its fields.
If either the measurement's key or fields are empty, Snapshot returns nil.