Add documentation

This commit is contained in:
Holger Obermaier 2022-01-31 14:02:00 +01:00
parent 1f55aa247f
commit fd3c7ed573

View File

@ -11,27 +11,30 @@ import (
// Most functions are derived from github.com/influxdata/line-protocol/metric.go // Most functions are derived from github.com/influxdata/line-protocol/metric.go
// The metric type is extended with an extra meta information list re-using the Tag // The metric type is extended with an extra meta information list re-using the Tag
// type. // type.
//
// See: https://docs.influxdata.com/influxdb/latest/reference/syntax/line-protocol/
type ccMetric struct { type ccMetric struct {
name string name string // Measurement name
tags []*lp.Tag tags []*lp.Tag // ordered list of of tags
fields []*lp.Field fields []*lp.Field // unordered list of of fields
tm time.Time tm time.Time // timestamp
meta []*lp.Tag meta []*lp.Tag // odered list of meta data tags
} }
// ccmetric access functions
type CCMetric interface { type CCMetric interface {
lp.MutableMetric lp.MutableMetric // SetTime, AddTag, AddField
AddMeta(key, value string) AddMeta(key, value string) // Add a meta data tag
MetaList() []*lp.Tag MetaList() []*lp.Tag // Returns the meta data list
RemoveTag(key string) RemoveTag(key string) // Remove a tag addressed by its key
GetTag(key string) (string, bool) GetTag(key string) (string, bool) // Get a tag addressed by its key
GetMeta(key string) (string, bool) GetMeta(key string) (string, bool) // Get a meta data tab addressed by its key
GetField(key string) (interface{}, bool) GetField(key string) (interface{}, bool) // Get a field addressed by its key
HasField(key string) bool HasField(key string) bool // Check if a field key is present
RemoveField(key string) RemoveField(key string) // Remove a field addressed by its key
} }
// Meta returns the list of meta data tags as key-value mapping
func (m *ccMetric) Meta() map[string]string { func (m *ccMetric) Meta() map[string]string {
meta := make(map[string]string, len(m.meta)) meta := make(map[string]string, len(m.meta))
for _, m := range m.meta { for _, m := range m.meta {
@ -40,18 +43,22 @@ func (m *ccMetric) Meta() map[string]string {
return meta return meta
} }
// MetaList returns the list of meta data tags
func (m *ccMetric) MetaList() []*lp.Tag { func (m *ccMetric) MetaList() []*lp.Tag {
return m.meta return m.meta
} }
// String implements the stringer interface for data type ccMetric
func (m *ccMetric) String() string { func (m *ccMetric) String() string {
return fmt.Sprintf("%s %v %v %v %d", m.name, m.Tags(), m.Meta(), m.Fields(), m.tm.UnixNano()) return fmt.Sprintf("%s %v %v %v %d", m.name, m.Tags(), m.Meta(), m.Fields(), m.tm.UnixNano())
} }
// Name returns the metric name
func (m *ccMetric) Name() string { func (m *ccMetric) Name() string {
return m.name return m.name
} }
// Tags returns the the list of tags as key-value-mapping
func (m *ccMetric) Tags() map[string]string { func (m *ccMetric) Tags() map[string]string {
tags := make(map[string]string, len(m.tags)) tags := make(map[string]string, len(m.tags))
for _, tag := range m.tags { for _, tag := range m.tags {
@ -60,10 +67,12 @@ func (m *ccMetric) Tags() map[string]string {
return tags return tags
} }
// TagList returns the list of tags
func (m *ccMetric) TagList() []*lp.Tag { func (m *ccMetric) TagList() []*lp.Tag {
return m.tags return m.tags
} }
// Fields returns the list of fields as key-value-mapping
func (m *ccMetric) Fields() map[string]interface{} { func (m *ccMetric) Fields() map[string]interface{} {
fields := make(map[string]interface{}, len(m.fields)) fields := make(map[string]interface{}, len(m.fields))
for _, field := range m.fields { for _, field := range m.fields {
@ -73,18 +82,22 @@ func (m *ccMetric) Fields() map[string]interface{} {
return fields return fields
} }
// FieldList returns the list of fields
func (m *ccMetric) FieldList() []*lp.Field { func (m *ccMetric) FieldList() []*lp.Field {
return m.fields return m.fields
} }
// Time returns timestamp
func (m *ccMetric) Time() time.Time { func (m *ccMetric) Time() time.Time {
return m.tm return m.tm
} }
// SetTime sets the timestamp
func (m *ccMetric) SetTime(t time.Time) { func (m *ccMetric) SetTime(t time.Time) {
m.tm = t m.tm = t
} }
// HasTag checks if a tag with key equal to <key> is present in the list of tags
func (m *ccMetric) HasTag(key string) bool { func (m *ccMetric) HasTag(key string) bool {
for _, tag := range m.tags { for _, tag := range m.tags {
if tag.Key == key { if tag.Key == key {
@ -94,6 +107,7 @@ func (m *ccMetric) HasTag(key string) bool {
return false return false
} }
// GetTag returns the tag with tag's key equal to <key>
func (m *ccMetric) GetTag(key string) (string, bool) { func (m *ccMetric) GetTag(key string) (string, bool) {
for _, tag := range m.tags { for _, tag := range m.tags {
if tag.Key == key { if tag.Key == key {
@ -103,6 +117,8 @@ func (m *ccMetric) GetTag(key string) (string, bool) {
return "", false return "", false
} }
// RemoveTag removes the tag with tag's key equal to <key>
// and keeps the tag list ordered by the keys
func (m *ccMetric) RemoveTag(key string) { func (m *ccMetric) RemoveTag(key string) {
for i, tag := range m.tags { for i, tag := range m.tags {
if tag.Key == key { if tag.Key == key {
@ -114,6 +130,8 @@ func (m *ccMetric) RemoveTag(key string) {
} }
} }
// AddTag adds a tag (consisting of key and value)
// and keeps the tag list ordered by the keys
func (m *ccMetric) AddTag(key, value string) { func (m *ccMetric) AddTag(key, value string) {
for i, tag := range m.tags { for i, tag := range m.tags {
if key > tag.Key { if key > tag.Key {
@ -134,6 +152,7 @@ func (m *ccMetric) AddTag(key, value string) {
m.tags = append(m.tags, &lp.Tag{Key: key, Value: value}) m.tags = append(m.tags, &lp.Tag{Key: key, Value: value})
} }
// HasTag checks if a meta data tag with meta data's key equal to <key> is present in the list of meta data tags
func (m *ccMetric) HasMeta(key string) bool { func (m *ccMetric) HasMeta(key string) bool {
for _, tag := range m.meta { for _, tag := range m.meta {
if tag.Key == key { if tag.Key == key {
@ -143,6 +162,7 @@ func (m *ccMetric) HasMeta(key string) bool {
return false return false
} }
// GetMeta returns the meta data tag with meta data's key equal to <key>
func (m *ccMetric) GetMeta(key string) (string, bool) { func (m *ccMetric) GetMeta(key string) (string, bool) {
for _, tag := range m.meta { for _, tag := range m.meta {
if tag.Key == key { if tag.Key == key {
@ -152,6 +172,8 @@ func (m *ccMetric) GetMeta(key string) (string, bool) {
return "", false return "", false
} }
// RemoveMeta removes the meta data tag with tag's key equal to <key>
// and keeps the meta data tag list ordered by the keys
func (m *ccMetric) RemoveMeta(key string) { func (m *ccMetric) RemoveMeta(key string) {
for i, tag := range m.meta { for i, tag := range m.meta {
if tag.Key == key { if tag.Key == key {
@ -163,6 +185,8 @@ func (m *ccMetric) RemoveMeta(key string) {
} }
} }
// AddMeta adds a meta data tag (consisting of key and value)
// and keeps the meta data list ordered by the keys
func (m *ccMetric) AddMeta(key, value string) { func (m *ccMetric) AddMeta(key, value string) {
for i, tag := range m.meta { for i, tag := range m.meta {
if key > tag.Key { if key > tag.Key {
@ -183,6 +207,7 @@ func (m *ccMetric) AddMeta(key, value string) {
m.meta = append(m.meta, &lp.Tag{Key: key, Value: value}) m.meta = append(m.meta, &lp.Tag{Key: key, Value: value})
} }
// AddField adds a field (consisting of key and value) to the unordered list of fields
func (m *ccMetric) AddField(key string, value interface{}) { func (m *ccMetric) AddField(key string, value interface{}) {
for i, field := range m.fields { for i, field := range m.fields {
if key == field.Key { if key == field.Key {
@ -193,6 +218,7 @@ func (m *ccMetric) AddField(key string, value interface{}) {
m.fields = append(m.fields, &lp.Field{Key: key, Value: convertField(value)}) m.fields = append(m.fields, &lp.Field{Key: key, Value: convertField(value)})
} }
// GetField returns the field with field's key equal to <key>
func (m *ccMetric) GetField(key string) (interface{}, bool) { func (m *ccMetric) GetField(key string) (interface{}, bool) {
for _, field := range m.fields { for _, field := range m.fields {
if field.Key == key { if field.Key == key {
@ -202,6 +228,7 @@ func (m *ccMetric) GetField(key string) (interface{}, bool) {
return "", false return "", false
} }
// HasField checks if a field with field's key equal to <key> is present in the list of fields
func (m *ccMetric) HasField(key string) bool { func (m *ccMetric) HasField(key string) bool {
for _, field := range m.fields { for _, field := range m.fields {
if field.Key == key { if field.Key == key {
@ -211,6 +238,8 @@ func (m *ccMetric) HasField(key string) bool {
return false return false
} }
// RemoveField removes the field with field's key equal to <key>
// from the unordered list of fields
func (m *ccMetric) RemoveField(key string) { func (m *ccMetric) RemoveField(key string) {
for i, field := range m.fields { for i, field := range m.fields {
if field.Key == key { if field.Key == key {
@ -222,6 +251,7 @@ func (m *ccMetric) RemoveField(key string) {
} }
} }
// New creates a new measurement point
func New( func New(
name string, name string,
tags map[string]string, tags map[string]string,
@ -237,6 +267,7 @@ func New(
meta: nil, meta: nil,
} }
// Sorted list of tags
if len(tags) > 0 { if len(tags) > 0 {
m.tags = make([]*lp.Tag, 0, len(tags)) m.tags = make([]*lp.Tag, 0, len(tags))
for k, v := range tags { for k, v := range tags {
@ -246,6 +277,7 @@ func New(
sort.Slice(m.tags, func(i, j int) bool { return m.tags[i].Key < m.tags[j].Key }) sort.Slice(m.tags, func(i, j int) bool { return m.tags[i].Key < m.tags[j].Key })
} }
// Sorted list of meta data tags
if len(meta) > 0 { if len(meta) > 0 {
m.meta = make([]*lp.Tag, 0, len(meta)) m.meta = make([]*lp.Tag, 0, len(meta))
for k, v := range meta { for k, v := range meta {
@ -255,6 +287,7 @@ func New(
sort.Slice(m.meta, func(i, j int) bool { return m.meta[i].Key < m.meta[j].Key }) sort.Slice(m.meta, func(i, j int) bool { return m.meta[i].Key < m.meta[j].Key })
} }
// Unsorted list of fields
if len(fields) > 0 { if len(fields) > 0 {
m.fields = make([]*lp.Field, 0, len(fields)) m.fields = make([]*lp.Field, 0, len(fields))
for k, v := range fields { for k, v := range fields {
@ -269,6 +302,7 @@ func New(
return m, nil return m, nil
} }
// FromMetric copies the metric <other>
func FromMetric(other CCMetric) CCMetric { func FromMetric(other CCMetric) CCMetric {
m := &ccMetric{ m := &ccMetric{
name: other.Name(), name: other.Name(),
@ -291,6 +325,7 @@ func FromMetric(other CCMetric) CCMetric {
return m return m
} }
// FromInfluxMetric copies the influxDB line protocol metric <other>
func FromInfluxMetric(other lp.Metric) CCMetric { func FromInfluxMetric(other lp.Metric) CCMetric {
m := &ccMetric{ m := &ccMetric{
name: other.Name(), name: other.Name(),
@ -300,16 +335,28 @@ func FromInfluxMetric(other lp.Metric) CCMetric {
tm: other.Time(), tm: other.Time(),
} }
for i, tag := range other.TagList() { for i, otherTag := range other.TagList() {
m.tags[i] = &lp.Tag{Key: tag.Key, Value: tag.Value} m.tags[i] = &lp.Tag{
Key: otherTag.Key,
Value: otherTag.Value,
}
} }
for i, field := range other.FieldList() { for i, otherField := range other.FieldList() {
m.fields[i] = &lp.Field{Key: field.Key, Value: field.Value} m.fields[i] = &lp.Field{
Key: otherField.Key,
Value: otherField.Value,
}
} }
return m return m
} }
// convertField converts data types of fields by the following schemata:
// *float32, *float64, float32, float64 -> float64
// *int, *int8, *int16, *int32, *int64, int, int8, int16, int32, int64 -> int64
// *uint, *uint8, *uint16, *uint32, *uint64, uint, uint8, uint16, uint32, uint64 -> uint64
// *[]byte, *string, []byte, string -> string
// *bool, bool -> bool
func convertField(v interface{}) interface{} { func convertField(v interface{}) interface{} {
switch v := v.(type) { switch v := v.(type) {
case float64: case float64: