// Copyright 2013 Prometheus Team // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package model import ( "bytes" "code.google.com/p/goprotobuf/proto" "fmt" dto "github.com/prometheus/prometheus/model/generated" "sort" "time" ) const ( // XXX: Re-evaluate down the road. reservedDelimiter = `"` ) // A LabelSet is a collection of LabelName and LabelValue pairs. The LabelSet // may be fully-qualified down to the point where it may resolve to a single // Metric in the data store or not. All operations that occur within the realm // of a LabelSet can emit a vector of Metric entities to which the LabelSet may // match. type LabelSet map[LabelName]LabelValue func (l LabelSet) String() string { var ( buffer bytes.Buffer labels LabelNames labelCount int = len(l) ) for name := range l { labels = append(labels, name) } sort.Sort(labels) fmt.Fprintf(&buffer, "{") for i := 0; i < labelCount; i++ { var ( label = labels[i] value = l[label] ) switch i { case labelCount - 1: fmt.Fprintf(&buffer, "%s=%s", label, value) default: fmt.Fprintf(&buffer, "%s=%s, ", label, value) } } fmt.Fprintf(&buffer, "}") return buffer.String() } // A Metric is similar to a LabelSet, but the key difference is that a Metric is // a singleton and refers to one and only one stream of samples. type Metric map[LabelName]LabelValue // A SampleValue is a representation of a value for a given sample at a given // time. type SampleValue float64 func (s SampleValue) Equal(o SampleValue) bool { return s == o } func (s SampleValue) ToDTO() *float64 { return proto.Float64(float64(s)) } func (v SampleValue) MarshalJSON() ([]byte, error) { return []byte(fmt.Sprintf("\"%f\"", v)), nil } func (s SamplePair) MarshalJSON() ([]byte, error) { return []byte(fmt.Sprintf("{\"Value\": \"%f\", \"Timestamp\": %d}", s.Value, s.Timestamp.Unix())), nil } type SamplePair struct { Value SampleValue Timestamp time.Time } func (s SamplePair) Equal(o SamplePair) (equal bool) { switch { case !s.Value.Equal(o.Value): return case !s.Timestamp.Equal(o.Timestamp): return } return true } type Values []SamplePair func (v Values) Len() int { return len(v) } func (v Values) Less(i, j int) bool { return v[i].Timestamp.Before(v[j].Timestamp) } func (v Values) Swap(i, j int) { v[i], v[j] = v[j], v[i] } // FirstTimeAfter indicates whether the first sample of a set is after a given // timestamp. func (v Values) FirstTimeAfter(t time.Time) bool { return v[0].Timestamp.After(t) } // LastTimeBefore indicates whether the last sample of a set is before a given // timestamp. func (v Values) LastTimeBefore(t time.Time) bool { return v[len(v)-1].Timestamp.Before(t) } // InsideInterval indicates whether a given range of sorted values could contain // a value for a given time. func (v Values) InsideInterval(t time.Time) (s bool) { if v.Len() == 0 { return } if t.Before(v[0].Timestamp) { return } if !v[v.Len()-1].Timestamp.Before(t) { return } return true } // TruncateBefore returns a subslice of the original such that extraneous // samples in the collection that occur before the provided time are // dropped. The original slice is not mutated. func (v Values) TruncateBefore(t time.Time) (values Values) { index := sort.Search(len(v), func(i int) bool { timestamp := v[i].Timestamp return timestamp.After(t) || timestamp.Equal(t) }) switch index { case 0: values = v case len(v): values = v[len(v)-1:] default: values = v[index-1:] } return } func NewValuesFromDTO(dto *dto.SampleValueSeries) (v Values) { for _, value := range dto.Value { v = append(v, SamplePair{ Timestamp: time.Unix(*value.Timestamp, 0), Value: SampleValue(*value.Value), }) } return } type SampleSet struct { Metric Metric Values Values } type Interval struct { OldestInclusive time.Time NewestInclusive time.Time }