mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-15 10:04:07 -08:00
181 lines
5.8 KiB
Go
181 lines
5.8 KiB
Go
|
// Copyright 2012 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 leveldb
|
||
|
|
||
|
import (
|
||
|
"code.google.com/p/goprotobuf/proto"
|
||
|
"errors"
|
||
|
"github.com/matttproud/prometheus/coding"
|
||
|
"github.com/matttproud/prometheus/coding/indexable"
|
||
|
"github.com/matttproud/prometheus/model"
|
||
|
dto "github.com/matttproud/prometheus/model/generated"
|
||
|
"log"
|
||
|
)
|
||
|
|
||
|
func (l *LevelDBMetricPersistence) setLabelPairFingerprints(labelPair *dto.LabelPair, fingerprints *dto.FingerprintCollection) error {
|
||
|
labelPairEncoded := coding.NewProtocolBufferEncoder(labelPair)
|
||
|
fingerprintsEncoded := coding.NewProtocolBufferEncoder(fingerprints)
|
||
|
return l.labelSetToFingerprints.Put(labelPairEncoded, fingerprintsEncoded)
|
||
|
}
|
||
|
|
||
|
func (l *LevelDBMetricPersistence) setLabelNameFingerprints(labelName *dto.LabelName, fingerprints *dto.FingerprintCollection) error {
|
||
|
labelNameEncoded := coding.NewProtocolBufferEncoder(labelName)
|
||
|
fingerprintsEncoded := coding.NewProtocolBufferEncoder(fingerprints)
|
||
|
return l.labelNameToFingerprints.Put(labelNameEncoded, fingerprintsEncoded)
|
||
|
}
|
||
|
|
||
|
func (l *LevelDBMetricPersistence) appendLabelPairFingerprint(labelPair *dto.LabelPair, fingerprint *dto.Fingerprint) error {
|
||
|
if has, hasError := l.HasLabelPair(labelPair); hasError == nil {
|
||
|
var fingerprints *dto.FingerprintCollection
|
||
|
if has {
|
||
|
if existing, existingError := l.getFingerprintsForLabelSet(labelPair); existingError == nil {
|
||
|
fingerprints = existing
|
||
|
} else {
|
||
|
return existingError
|
||
|
}
|
||
|
} else {
|
||
|
fingerprints = &dto.FingerprintCollection{}
|
||
|
}
|
||
|
|
||
|
fingerprints.Member = append(fingerprints.Member, fingerprint)
|
||
|
|
||
|
return l.setLabelPairFingerprints(labelPair, fingerprints)
|
||
|
} else {
|
||
|
return hasError
|
||
|
}
|
||
|
|
||
|
return errors.New("Unknown error when appending fingerprint to label name and value pair.")
|
||
|
}
|
||
|
|
||
|
func (l *LevelDBMetricPersistence) appendLabelNameFingerprint(labelPair *dto.LabelPair, fingerprint *dto.Fingerprint) error {
|
||
|
labelName := &dto.LabelName{
|
||
|
Name: labelPair.Name,
|
||
|
}
|
||
|
|
||
|
if has, hasError := l.HasLabelName(labelName); hasError == nil {
|
||
|
var fingerprints *dto.FingerprintCollection
|
||
|
if has {
|
||
|
if existing, existingError := l.GetLabelNameFingerprints(labelName); existingError == nil {
|
||
|
fingerprints = existing
|
||
|
} else {
|
||
|
return existingError
|
||
|
}
|
||
|
} else {
|
||
|
fingerprints = &dto.FingerprintCollection{}
|
||
|
}
|
||
|
|
||
|
fingerprints.Member = append(fingerprints.Member, fingerprint)
|
||
|
|
||
|
return l.setLabelNameFingerprints(labelName, fingerprints)
|
||
|
} else {
|
||
|
return hasError
|
||
|
}
|
||
|
|
||
|
return errors.New("Unknown error when appending fingerprint to label name and value pair.")
|
||
|
}
|
||
|
|
||
|
func (l *LevelDBMetricPersistence) appendFingerprints(m *dto.Metric) error {
|
||
|
if fingerprintDTO, fingerprintDTOError := model.MessageToFingerprintDTO(m); fingerprintDTOError == nil {
|
||
|
fingerprintKey := coding.NewProtocolBufferEncoder(fingerprintDTO)
|
||
|
metricDTOEncoder := coding.NewProtocolBufferEncoder(m)
|
||
|
|
||
|
if putError := l.fingerprintToMetrics.Put(fingerprintKey, metricDTOEncoder); putError == nil {
|
||
|
labelCount := len(m.LabelPair)
|
||
|
labelPairErrors := make(chan error, labelCount)
|
||
|
labelNameErrors := make(chan error, labelCount)
|
||
|
|
||
|
for _, labelPair := range m.LabelPair {
|
||
|
go func(labelPair *dto.LabelPair) {
|
||
|
labelNameErrors <- l.appendLabelNameFingerprint(labelPair, fingerprintDTO)
|
||
|
}(labelPair)
|
||
|
|
||
|
go func(labelPair *dto.LabelPair) {
|
||
|
labelPairErrors <- l.appendLabelPairFingerprint(labelPair, fingerprintDTO)
|
||
|
}(labelPair)
|
||
|
}
|
||
|
|
||
|
for i := 0; i < cap(labelPairErrors); i++ {
|
||
|
appendError := <-labelPairErrors
|
||
|
|
||
|
if appendError != nil {
|
||
|
return appendError
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for i := 0; i < cap(labelNameErrors); i++ {
|
||
|
appendError := <-labelNameErrors
|
||
|
|
||
|
if appendError != nil {
|
||
|
return appendError
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
|
||
|
} else {
|
||
|
return putError
|
||
|
}
|
||
|
} else {
|
||
|
return fingerprintDTOError
|
||
|
}
|
||
|
|
||
|
return errors.New("Unknown error in appending label pairs to fingerprint.")
|
||
|
}
|
||
|
|
||
|
func (l *LevelDBMetricPersistence) AppendSample(sample *model.Sample) error {
|
||
|
metricDTO := model.SampleToMetricDTO(sample)
|
||
|
|
||
|
if indexHas, indexHasError := l.hasIndexMetric(metricDTO); indexHasError == nil {
|
||
|
if !indexHas {
|
||
|
if indexPutError := l.indexMetric(metricDTO); indexPutError == nil {
|
||
|
if appendError := l.appendFingerprints(metricDTO); appendError != nil {
|
||
|
log.Printf("Could not set metric fingerprint to label pairs mapping: %q\n", appendError)
|
||
|
return appendError
|
||
|
}
|
||
|
} else {
|
||
|
log.Printf("Could not add metric to membership index: %q\n", indexPutError)
|
||
|
return indexPutError
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
log.Printf("Could not query membership index for metric: %q\n", indexHasError)
|
||
|
return indexHasError
|
||
|
}
|
||
|
|
||
|
if fingerprintDTO, fingerprintDTOErr := model.MessageToFingerprintDTO(metricDTO); fingerprintDTOErr == nil {
|
||
|
|
||
|
sampleKeyDTO := &dto.SampleKey{
|
||
|
Fingerprint: fingerprintDTO,
|
||
|
Timestamp: indexable.EncodeTime(sample.Timestamp),
|
||
|
}
|
||
|
|
||
|
sampleValueDTO := &dto.SampleValue{
|
||
|
Value: proto.Float32(float32(sample.Value)),
|
||
|
}
|
||
|
|
||
|
sampleKeyEncoded := coding.NewProtocolBufferEncoder(sampleKeyDTO)
|
||
|
sampleValueEncoded := coding.NewProtocolBufferEncoder(sampleValueDTO)
|
||
|
|
||
|
if putError := l.metricSamples.Put(sampleKeyEncoded, sampleValueEncoded); putError != nil {
|
||
|
log.Printf("Could not append metric sample: %q\n", putError)
|
||
|
return putError
|
||
|
}
|
||
|
} else {
|
||
|
log.Printf("Could not encode metric fingerprint: %q\n", fingerprintDTOErr)
|
||
|
return fingerprintDTOErr
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|