mirror of
https://github.com/kubernetes-sigs/prometheus-adapter.git
synced 2026-04-06 17:57:51 +00:00
Cleaning up.
* Wiped out a ton of warnings about comments. * Created consts for `MetricType` values. * `externalInfoMap` can now track multiple series with the same name/namespace and different labels. * `namespace` parameter of external metrics queries is now respected (albeit very rudimentarily) * Metric converter values for external metrics are now converted the same way as for custom metrics (probably still some opportunity for consolidation). * Lots of TODOs actually done. * Deleted a lot of commented out code.
This commit is contained in:
parent
9641e70005
commit
a94494337e
18 changed files with 155 additions and 188 deletions
|
|
@ -34,7 +34,10 @@ type DiscoveryRule struct {
|
||||||
MetricsQuery string `yaml:"metricsQuery,omitempty"`
|
MetricsQuery string `yaml:"metricsQuery,omitempty"`
|
||||||
// MetricType identifies whether the metrics derived from this rule should be classified
|
// MetricType identifies whether the metrics derived from this rule should be classified
|
||||||
// as external or custom metrics.
|
// as external or custom metrics.
|
||||||
MetricType MetricType `yaml:"metricType"`
|
MetricType MetricType `yaml:"metricType,omitempty"`
|
||||||
|
// ExternalMetricNamespaceLabelName identifies what Prometheus label should be examined
|
||||||
|
// to apply a namespace to metrics creates from this rule.
|
||||||
|
ExternalMetricNamespaceLabelName string `yaml:"externalMetricNamespaceLabelName,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegexFilter is a filter that matches positively or negatively against a regex.
|
// RegexFilter is a filter that matches positively or negatively against a regex.
|
||||||
|
|
@ -79,3 +82,12 @@ type NameMapping struct {
|
||||||
|
|
||||||
//MetricType identifies whether a given metric should be handled and interpreted as a Custom or External metric.
|
//MetricType identifies whether a given metric should be handled and interpreted as a Custom or External metric.
|
||||||
type MetricType string
|
type MetricType string
|
||||||
|
|
||||||
|
// Operator represents a key/field's relationship to value(s).
|
||||||
|
// See labels.Requirement and fields.Requirement for more details.
|
||||||
|
type Operator string
|
||||||
|
|
||||||
|
const (
|
||||||
|
External MetricType = "External"
|
||||||
|
Custom MetricType = "Custom"
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -48,13 +48,15 @@ type MetricLister interface {
|
||||||
ListAllMetrics() (metricUpdateResult, error)
|
ListAllMetrics() (metricUpdateResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//A MetricListerWithNotification is a MetricLister that has the ability to notify listeners
|
||||||
|
//when new metric data is available.
|
||||||
type MetricListerWithNotification interface {
|
type MetricListerWithNotification interface {
|
||||||
//It can list metrics, just like a normal MetricLister.
|
|
||||||
MetricLister
|
MetricLister
|
||||||
//Because it periodically pulls metrics, it needs to be Runnable.
|
|
||||||
Runnable
|
Runnable
|
||||||
//It provides notifications when it has new data to supply.
|
|
||||||
|
//AddNotificationReceiver registers a callback to be invoked when new metric data is available.
|
||||||
AddNotificationReceiver(func(metricUpdateResult))
|
AddNotificationReceiver(func(metricUpdateResult))
|
||||||
|
//UpdateNow forces an immediate refresh from the source data. Primarily for test purposes.
|
||||||
UpdateNow()
|
UpdateNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,6 +66,7 @@ type basicMetricLister struct {
|
||||||
lookback time.Duration
|
lookback time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewBasicMetricLister creates a MetricLister that is capable of interactly directly with Prometheus to list metrics.
|
||||||
func NewBasicMetricLister(promClient prom.Client, namers []MetricNamer, lookback time.Duration) MetricLister {
|
func NewBasicMetricLister(promClient prom.Client, namers []MetricNamer, lookback time.Duration) MetricLister {
|
||||||
lister := basicMetricLister{
|
lister := basicMetricLister{
|
||||||
promClient: promClient,
|
promClient: promClient,
|
||||||
|
|
|
||||||
|
|
@ -5,24 +5,37 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//ExportedMetric is a description of an available metric.
|
||||||
type ExportedMetric struct {
|
type ExportedMetric struct {
|
||||||
MetricName string
|
MetricName string
|
||||||
Labels labels.Set
|
Labels labels.Set
|
||||||
Namespace string
|
Namespace string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ExternalInfoMap is a data object that accepts and organizes information
|
||||||
|
//about available metrics.
|
||||||
type ExternalInfoMap interface {
|
type ExternalInfoMap interface {
|
||||||
|
//Begins tracking a metric, returning it to the caller.
|
||||||
TrackMetric(metricName string, generatedBy MetricNamer) ExternalMetricData
|
TrackMetric(metricName string, generatedBy MetricNamer) ExternalMetricData
|
||||||
|
//Exports a collection of all of the metrics currently being tracked.
|
||||||
ExportMetrics() []ExportedMetric
|
ExportMetrics() []ExportedMetric
|
||||||
|
//Finds a tracked metric with the given metric name, if it exists.
|
||||||
FindMetric(metricName string) (data ExternalMetricData, found bool)
|
FindMetric(metricName string) (data ExternalMetricData, found bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ExternalMetricData is a data object that accepts and organizes information
|
||||||
|
//about the various series/namespaces that a metric is associated with.
|
||||||
type ExternalMetricData interface {
|
type ExternalMetricData interface {
|
||||||
|
//MetricName returns the name of the metric represented by this object.
|
||||||
MetricName() string
|
MetricName() string
|
||||||
|
//WithSeries associates the provided labels with this metric.
|
||||||
WithSeries(labels labels.Set)
|
WithSeries(labels labels.Set)
|
||||||
|
//WithNamespacedSeries associates the provided labels with this metric, but within a particular namespace.
|
||||||
WithNamespacedSeries(namespace string, labels labels.Set)
|
WithNamespacedSeries(namespace string, labels labels.Set)
|
||||||
|
//Exports a collection of all the metrics currently being tracked.
|
||||||
ExportMetrics() []ExportedMetric
|
ExportMetrics() []ExportedMetric
|
||||||
GenerateQuery(selector labels.Selector) (prom.Selector, error)
|
//Generates a query to select the series/values for the metric this object represents.
|
||||||
|
GenerateQuery(namespace string, selector labels.Selector) (prom.Selector, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type externalInfoMap struct {
|
type externalInfoMap struct {
|
||||||
|
|
@ -31,18 +44,20 @@ type externalInfoMap struct {
|
||||||
|
|
||||||
type externalMetricData struct {
|
type externalMetricData struct {
|
||||||
metricName string
|
metricName string
|
||||||
namespacedData map[string]labels.Set
|
namespacedData map[string][]labels.Set
|
||||||
generatedBy MetricNamer
|
generatedBy MetricNamer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewExternalMetricData creates an ExternalMetricData for the provided metric name and namer.
|
||||||
func NewExternalMetricData(metricName string, generatedBy MetricNamer) ExternalMetricData {
|
func NewExternalMetricData(metricName string, generatedBy MetricNamer) ExternalMetricData {
|
||||||
return &externalMetricData{
|
return &externalMetricData{
|
||||||
metricName: metricName,
|
metricName: metricName,
|
||||||
generatedBy: generatedBy,
|
generatedBy: generatedBy,
|
||||||
namespacedData: map[string]labels.Set{},
|
namespacedData: map[string][]labels.Set{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewExternalInfoMap creates an empty ExternalInfoMap for storing external metric information.
|
||||||
func NewExternalInfoMap() ExternalInfoMap {
|
func NewExternalInfoMap() ExternalInfoMap {
|
||||||
return &externalInfoMap{
|
return &externalInfoMap{
|
||||||
metrics: map[string]ExternalMetricData{},
|
metrics: map[string]ExternalMetricData{},
|
||||||
|
|
@ -78,18 +93,20 @@ func (d *externalMetricData) MetricName() string {
|
||||||
return d.metricName
|
return d.metricName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *externalMetricData) GenerateQuery(selector labels.Selector) (prom.Selector, error) {
|
func (d *externalMetricData) GenerateQuery(namespace string, selector labels.Selector) (prom.Selector, error) {
|
||||||
return d.generatedBy.QueryForExternalSeries(d.metricName, selector)
|
return d.generatedBy.QueryForExternalSeries(namespace, d.metricName, selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *externalMetricData) ExportMetrics() []ExportedMetric {
|
func (d *externalMetricData) ExportMetrics() []ExportedMetric {
|
||||||
results := make([]ExportedMetric, 0)
|
results := make([]ExportedMetric, 0)
|
||||||
for namespace, labels := range d.namespacedData {
|
for namespace, labelSets := range d.namespacedData {
|
||||||
results = append(results, ExportedMetric{
|
for _, labelSet := range labelSets {
|
||||||
Labels: labels,
|
results = append(results, ExportedMetric{
|
||||||
MetricName: d.metricName,
|
Labels: labelSet,
|
||||||
Namespace: namespace,
|
MetricName: d.metricName,
|
||||||
})
|
Namespace: namespace,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
@ -99,10 +116,13 @@ func (d *externalMetricData) WithSeries(labels labels.Set) {
|
||||||
d.WithNamespacedSeries("", labels)
|
d.WithNamespacedSeries("", labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *externalMetricData) WithNamespacedSeries(namespace string, labels labels.Set) {
|
func (d *externalMetricData) WithNamespacedSeries(namespace string, seriesLabels labels.Set) {
|
||||||
data, found := d.namespacedData[namespace]
|
data, found := d.namespacedData[namespace]
|
||||||
if !found {
|
if !found {
|
||||||
data = labels
|
data = []labels.Set{}
|
||||||
d.namespacedData[namespace] = data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data = append(data, seriesLabels)
|
||||||
|
d.namespacedData[namespace] = data
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,16 +15,7 @@ import (
|
||||||
conv "github.com/directxman12/k8s-prometheus-adapter/pkg/custom-provider/metric-converter"
|
conv "github.com/directxman12/k8s-prometheus-adapter/pkg/custom-provider/metric-converter"
|
||||||
)
|
)
|
||||||
|
|
||||||
//TODO: Make sure everything has the proper licensing disclosure at the top.
|
//TODO: AC - Make sure everything has the proper licensing disclosure at the top.
|
||||||
//TODO: I'd like to move these files into another directory, but the compiler was giving me
|
|
||||||
//some static around unexported types. I'm going to leave things as-is for now, but it
|
|
||||||
//might be worthwhile to, once the shared components are discovered, move some things around.
|
|
||||||
|
|
||||||
//TODO: Some of these members may not be necessary.
|
|
||||||
//Some of them are definitely duplicated between the
|
|
||||||
//external and custom providers. They should probably share
|
|
||||||
//the same instances of these objects (especially the SeriesRegistry)
|
|
||||||
//to cut down on unnecessary chatter/bookkeeping.
|
|
||||||
type externalPrometheusProvider struct {
|
type externalPrometheusProvider struct {
|
||||||
promClient prom.Client
|
promClient prom.Client
|
||||||
metricConverter conv.MetricConverter
|
metricConverter conv.MetricConverter
|
||||||
|
|
@ -32,13 +23,7 @@ type externalPrometheusProvider struct {
|
||||||
seriesRegistry ExternalSeriesRegistry
|
seriesRegistry ExternalSeriesRegistry
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: It probably makes more sense to, once this is functional and complete, roll the
|
//NewExternalPrometheusProvider creates an ExternalMetricsProvider capable of responding to Kubernetes requests for external metric data.
|
||||||
//prometheusProvider and externalPrometheusProvider up into a single type
|
|
||||||
//that implements both interfaces or provide a thin wrapper that composes them.
|
|
||||||
//Just glancing at start.go looks like it would be much more straightforward
|
|
||||||
//to do one of those two things instead of trying to run the two providers
|
|
||||||
//independently.
|
|
||||||
|
|
||||||
func NewExternalPrometheusProvider(seriesRegistry ExternalSeriesRegistry, promClient prom.Client, converter conv.MetricConverter) provider.ExternalMetricsProvider {
|
func NewExternalPrometheusProvider(seriesRegistry ExternalSeriesRegistry, promClient prom.Client, converter conv.MetricConverter) provider.ExternalMetricsProvider {
|
||||||
return &externalPrometheusProvider{
|
return &externalPrometheusProvider{
|
||||||
promClient: promClient,
|
promClient: promClient,
|
||||||
|
|
@ -48,21 +33,17 @@ func NewExternalPrometheusProvider(seriesRegistry ExternalSeriesRegistry, promCl
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *externalPrometheusProvider) GetExternalMetric(namespace string, metricName string, metricSelector labels.Selector) (*external_metrics.ExternalMetricValueList, error) {
|
func (p *externalPrometheusProvider) GetExternalMetric(namespace string, metricName string, metricSelector labels.Selector) (*external_metrics.ExternalMetricValueList, error) {
|
||||||
selector, found := p.seriesRegistry.QueryForMetric(metricName, metricSelector)
|
selector, found := p.seriesRegistry.QueryForMetric(namespace, metricName, metricSelector)
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
return &external_metrics.ExternalMetricValueList{
|
return &external_metrics.ExternalMetricValueList{
|
||||||
Items: []external_metrics.ExternalMetricValue{},
|
Items: []external_metrics.ExternalMetricValue{},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
// query := p.queryBuilder.BuildPrometheusQuery(namespace, metricName, metricSelector, queryMetadata)
|
|
||||||
|
|
||||||
//TODO: I don't yet know what a context is, but apparently I should use a real one.
|
|
||||||
queryResults, err := p.promClient.Query(context.TODO(), pmodel.Now(), selector)
|
queryResults, err := p.promClient.Query(context.TODO(), pmodel.Now(), selector)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//TODO: Is this how folks normally deal w/ errors? Just propagate them upwards?
|
|
||||||
//I should go look at what the customProvider does.
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,31 +14,33 @@ import (
|
||||||
"github.com/directxman12/k8s-prometheus-adapter/pkg/config"
|
"github.com/directxman12/k8s-prometheus-adapter/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//ExternalSeriesRegistry acts as the top-level converter for transforming Kubernetes requests
|
||||||
|
//for external metrics into Prometheus queries.
|
||||||
type ExternalSeriesRegistry interface {
|
type ExternalSeriesRegistry interface {
|
||||||
// ListAllMetrics lists all metrics known to this registry
|
// ListAllMetrics lists all metrics known to this registry
|
||||||
ListAllMetrics() []provider.ExternalMetricInfo
|
ListAllMetrics() []provider.ExternalMetricInfo
|
||||||
QueryForMetric(metricName string, metricSelector labels.Selector) (query prom.Selector, found bool)
|
QueryForMetric(namespace string, metricName string, metricSelector labels.Selector) (query prom.Selector, found bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// overridableSeriesRegistry is a basic SeriesRegistry
|
// overridableSeriesRegistry is a basic SeriesRegistry
|
||||||
type externalSeriesRegistry struct {
|
type externalSeriesRegistry struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
externalInfo map[string]seriesInfo
|
|
||||||
// metrics is the list of all known metrics
|
// metrics is the list of all known metrics
|
||||||
metrics []provider.ExternalMetricInfo
|
metrics []provider.ExternalMetricInfo
|
||||||
|
|
||||||
mapper apimeta.RESTMapper
|
mapper apimeta.RESTMapper
|
||||||
|
|
||||||
metricLister MetricListerWithNotification
|
metricLister MetricListerWithNotification
|
||||||
tonyExternalInfo ExternalInfoMap
|
externalMetricInfo ExternalInfoMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewExternalSeriesRegistry creates an ExternalSeriesRegistry driven by the data from the provided MetricLister.
|
||||||
func NewExternalSeriesRegistry(lister MetricListerWithNotification, mapper apimeta.RESTMapper) ExternalSeriesRegistry {
|
func NewExternalSeriesRegistry(lister MetricListerWithNotification, mapper apimeta.RESTMapper) ExternalSeriesRegistry {
|
||||||
var registry = externalSeriesRegistry{
|
var registry = externalSeriesRegistry{
|
||||||
mapper: mapper,
|
mapper: mapper,
|
||||||
metricLister: lister,
|
metricLister: lister,
|
||||||
tonyExternalInfo: NewExternalInfoMap(),
|
externalMetricInfo: NewExternalInfoMap(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lister.AddNotificationReceiver(registry.onNewDataAvailable)
|
lister.AddNotificationReceiver(registry.onNewDataAvailable)
|
||||||
|
|
@ -50,7 +52,7 @@ func (r *externalSeriesRegistry) filterMetrics(result metricUpdateResult) metric
|
||||||
namers := make([]MetricNamer, 0)
|
namers := make([]MetricNamer, 0)
|
||||||
series := make([][]prom.Series, 0)
|
series := make([][]prom.Series, 0)
|
||||||
|
|
||||||
targetType := config.MetricType("External")
|
targetType := config.External
|
||||||
|
|
||||||
for i, namer := range result.namers {
|
for i, namer := range result.namers {
|
||||||
if namer.MetricType() == targetType {
|
if namer.MetricType() == targetType {
|
||||||
|
|
@ -98,10 +100,16 @@ func (r *externalSeriesRegistry) onNewDataAvailable(result metricUpdateResult) {
|
||||||
// namespaced := identity.namespaced
|
// namespaced := identity.namespaced
|
||||||
name := identity.name
|
name := identity.name
|
||||||
labels := r.convertLabels(series.Labels)
|
labels := r.convertLabels(series.Labels)
|
||||||
//TODO: Figure out the namespace, if applicable
|
|
||||||
metricNs := ""
|
//Check for a label indicating namespace.
|
||||||
|
metricNs, found := series.Labels[model.LabelName(namer.ExternalMetricNamespaceLabelName())]
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
metricNs = ""
|
||||||
|
}
|
||||||
|
|
||||||
trackedMetric := updatedCache.TrackMetric(name, namer)
|
trackedMetric := updatedCache.TrackMetric(name, namer)
|
||||||
trackedMetric.WithNamespacedSeries(metricNs, labels)
|
trackedMetric.WithNamespacedSeries(string(metricNs), labels)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +120,7 @@ func (r *externalSeriesRegistry) onNewDataAvailable(result metricUpdateResult) {
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
|
|
||||||
r.tonyExternalInfo = updatedCache
|
r.externalMetricInfo = updatedCache
|
||||||
r.metrics = convertedMetrics
|
r.metrics = convertedMetrics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,29 +143,20 @@ func (r *externalSeriesRegistry) ListAllMetrics() []provider.ExternalMetricInfo
|
||||||
return r.metrics
|
return r.metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *externalSeriesRegistry) QueryForMetric(metricName string, metricSelector labels.Selector) (query prom.Selector, found bool) {
|
func (r *externalSeriesRegistry) QueryForMetric(namespace string, metricName string, metricSelector labels.Selector) (query prom.Selector, found bool) {
|
||||||
r.mu.RLock()
|
r.mu.RLock()
|
||||||
defer r.mu.RUnlock()
|
defer r.mu.RUnlock()
|
||||||
metric, found := r.tonyExternalInfo.FindMetric(metricName)
|
metric, found := r.externalMetricInfo.FindMetric(metricName)
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
|
glog.V(10).Infof("external metric %q not registered", metricName)
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
query, err := metric.GenerateQuery(metricSelector)
|
query, err := metric.GenerateQuery(namespace, metricSelector)
|
||||||
// info, infoFound := r.info[metricInfo]
|
|
||||||
// if !infoFound {
|
|
||||||
// //TODO: Weird that it switches between types here.
|
|
||||||
// glog.V(10).Infof("metric %v not registered", metricInfo)
|
|
||||||
// return "", false
|
|
||||||
// }
|
|
||||||
|
|
||||||
// query, err := info.namer.QueryForExternalSeries(info.seriesName, metricSelector)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//TODO: See what was being .String() and implement that for ExternalMetricInfo.
|
glog.Errorf("unable to construct query for external metric %s: %v", metricName, err)
|
||||||
// errorVal := metricInfo.String()
|
|
||||||
errorVal := "something"
|
|
||||||
glog.Errorf("unable to construct query for metric %s: %v", errorVal, err)
|
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,6 @@ func (c *matrixConverter) Convert(queryResult prom.QueryResult) (*external_metri
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *matrixConverter) convert(result *model.Matrix) (*external_metrics.ExternalMetricValueList, error) {
|
func (c *matrixConverter) convert(result *model.Matrix) (*external_metrics.ExternalMetricValueList, error) {
|
||||||
//TODO: Implementation.
|
//TODO: AC - Implementation.
|
||||||
return nil, errors.New("converting Matrix results is not yet supported")
|
return nil, errors.New("converting Matrix results is not yet supported")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,14 +30,10 @@ func (c *sampleConverter) Convert(sample *model.Sample) (*external_metrics.Exter
|
||||||
Timestamp: metav1.Time{
|
Timestamp: metav1.Time{
|
||||||
sample.Timestamp.Time(),
|
sample.Timestamp.Time(),
|
||||||
},
|
},
|
||||||
//TODO: I'm not so sure about this type/conversions.
|
Value: *resource.NewMilliQuantity(int64(sample.Value*1000.0), resource.DecimalSI),
|
||||||
//This can't possibly be the right way to convert this.
|
|
||||||
//Also, does K8S only deal win integer metrics?
|
|
||||||
Value: *resource.NewQuantity(int64(float64(sample.Value)), resource.DecimalSI),
|
|
||||||
MetricLabels: labels,
|
MetricLabels: labels,
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Actual errors?
|
|
||||||
return &singleMetric, nil
|
return &singleMetric, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,18 +35,11 @@ func (c *scalarConverter) Convert(queryResult prom.QueryResult) (*external_metri
|
||||||
|
|
||||||
func (c *scalarConverter) convert(input *model.Scalar) (*external_metrics.ExternalMetricValueList, error) {
|
func (c *scalarConverter) convert(input *model.Scalar) (*external_metrics.ExternalMetricValueList, error) {
|
||||||
result := external_metrics.ExternalMetricValueList{
|
result := external_metrics.ExternalMetricValueList{
|
||||||
//Using prometheusProvider.metricsFor(...) as an example,
|
|
||||||
//it seems that I don't need to provide values for
|
|
||||||
//TypeMeta and ListMeta.
|
|
||||||
//TODO: Get some confirmation on this.
|
|
||||||
Items: []external_metrics.ExternalMetricValue{
|
Items: []external_metrics.ExternalMetricValue{
|
||||||
{
|
{
|
||||||
Timestamp: metav1.Time{
|
Timestamp: metav1.Time{
|
||||||
input.Timestamp.Time(),
|
input.Timestamp.Time(),
|
||||||
},
|
},
|
||||||
//TODO: I'm not so sure about this type/conversions.
|
|
||||||
//Is there a meaningful loss of precision here?
|
|
||||||
//Does K8S only deal win integer metrics?
|
|
||||||
Value: *resource.NewMilliQuantity(int64(input.Value*1000.0), resource.DecimalSI),
|
Value: *resource.NewMilliQuantity(int64(input.Value*1000.0), resource.DecimalSI),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package provider
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
|
|
@ -46,8 +47,13 @@ func (c *vectorConverter) convert(result model.Vector) (*external_metrics.Extern
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, val := range result {
|
for _, val := range result {
|
||||||
//TODO: Care about potential errors here.
|
|
||||||
singleMetric, _ := c.SampleConverter.Convert(val)
|
singleMetric, err := c.SampleConverter.Convert(val)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to convert vector: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
items = append(items, *singleMetric)
|
items = append(items, *singleMetric)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/directxman12/k8s-prometheus-adapter/pkg/config"
|
"github.com/directxman12/k8s-prometheus-adapter/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//MetricNameConverter provides functions for naming custom metrics from Promethes series.
|
||||||
type MetricNameConverter interface {
|
type MetricNameConverter interface {
|
||||||
GetMetricNameForSeries(series prom.Series) (string, error)
|
GetMetricNameForSeries(series prom.Series) (string, error)
|
||||||
}
|
}
|
||||||
|
|
@ -17,6 +18,8 @@ type metricNameConverter struct {
|
||||||
nameAs string
|
nameAs string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewMetricNameConverter creates a MetricNameConverter capable of translating Prometheus series names
|
||||||
|
//into custom metric names.
|
||||||
func NewMetricNameConverter(mapping config.NameMapping) (MetricNameConverter, error) {
|
func NewMetricNameConverter(mapping config.NameMapping) (MetricNameConverter, error) {
|
||||||
var nameMatches *regexp.Regexp
|
var nameMatches *regexp.Regexp
|
||||||
var err error
|
var err error
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,10 @@ type MetricNamer interface {
|
||||||
// QueryForSeries returns the query for a given series (not API metric name), with
|
// QueryForSeries returns the query for a given series (not API metric name), with
|
||||||
// the given namespace name (if relevant), resource, and resource names.
|
// the given namespace name (if relevant), resource, and resource names.
|
||||||
QueryForSeries(series string, resource schema.GroupResource, namespace string, names ...string) (prom.Selector, error)
|
QueryForSeries(series string, resource schema.GroupResource, namespace string, names ...string) (prom.Selector, error)
|
||||||
QueryForExternalSeries(series string, metricSelector labels.Selector) (prom.Selector, error)
|
QueryForExternalSeries(namespace string, series string, metricSelector labels.Selector) (prom.Selector, error)
|
||||||
IdentifySeries(series prom.Series) (seriesIdentity, error)
|
IdentifySeries(series prom.Series) (seriesIdentity, error)
|
||||||
MetricType() config.MetricType
|
MetricType() config.MetricType
|
||||||
|
ExternalMetricNamespaceLabelName() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type seriesIdentity struct {
|
type seriesIdentity struct {
|
||||||
|
|
@ -58,7 +59,8 @@ type metricNamer struct {
|
||||||
metricNameConverter MetricNameConverter
|
metricNameConverter MetricNameConverter
|
||||||
mapper apimeta.RESTMapper
|
mapper apimeta.RESTMapper
|
||||||
|
|
||||||
metricType config.MetricType
|
metricType config.MetricType
|
||||||
|
externalMetricNamespaceLabel string
|
||||||
}
|
}
|
||||||
|
|
||||||
// queryTemplateArgs are the arguments for the metrics query template.
|
// queryTemplateArgs are the arguments for the metrics query template.
|
||||||
|
|
@ -74,6 +76,10 @@ func (n *metricNamer) MetricType() config.MetricType {
|
||||||
return n.metricType
|
return n.metricType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *metricNamer) ExternalMetricNamespaceLabelName() string {
|
||||||
|
return n.externalMetricNamespaceLabel
|
||||||
|
}
|
||||||
|
|
||||||
func (n *metricNamer) IdentifySeries(series prom.Series) (seriesIdentity, error) {
|
func (n *metricNamer) IdentifySeries(series prom.Series) (seriesIdentity, error) {
|
||||||
// TODO: warn if it doesn't match any resources
|
// TODO: warn if it doesn't match any resources
|
||||||
resources, namespaced := n.resourceConverter.ResourcesForSeries(series)
|
resources, namespaced := n.resourceConverter.ResourcesForSeries(series)
|
||||||
|
|
@ -219,15 +225,26 @@ func NamersFromConfig(cfg *config.MetricsDiscoveryConfig, mapper apimeta.RESTMap
|
||||||
return nil, fmt.Errorf("unable to create a MetricNameConverter associated with series query %q: %v", rule.SeriesQuery, err)
|
return nil, fmt.Errorf("unable to create a MetricNameConverter associated with series query %q: %v", rule.SeriesQuery, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespaceLabel := ""
|
||||||
|
if rule.MetricType == config.External {
|
||||||
|
namespaceLabel = rule.ExternalMetricNamespaceLabelName
|
||||||
|
}
|
||||||
|
|
||||||
|
metricType := rule.MetricType
|
||||||
|
if metricType == config.MetricType("") {
|
||||||
|
metricType = config.Custom
|
||||||
|
}
|
||||||
|
|
||||||
namer := &metricNamer{
|
namer := &metricNamer{
|
||||||
seriesQuery: prom.Selector(rule.SeriesQuery),
|
seriesQuery: prom.Selector(rule.SeriesQuery),
|
||||||
mapper: mapper,
|
mapper: mapper,
|
||||||
|
|
||||||
resourceConverter: resourceConverter,
|
resourceConverter: resourceConverter,
|
||||||
queryBuilder: queryBuilder,
|
queryBuilder: queryBuilder,
|
||||||
seriesFilterer: seriesFilterer,
|
seriesFilterer: seriesFilterer,
|
||||||
metricNameConverter: metricNameConverter,
|
metricNameConverter: metricNameConverter,
|
||||||
metricType: rule.MetricType,
|
metricType: metricType,
|
||||||
|
externalMetricNamespaceLabel: namespaceLabel,
|
||||||
}
|
}
|
||||||
|
|
||||||
namers[i] = namer
|
namers[i] = namer
|
||||||
|
|
@ -236,8 +253,28 @@ func NamersFromConfig(cfg *config.MetricsDiscoveryConfig, mapper apimeta.RESTMap
|
||||||
return namers, nil
|
return namers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *metricNamer) QueryForExternalSeries(series string, metricSelector labels.Selector) (prom.Selector, error) {
|
func (n *metricNamer) buildNamespaceQueryPartForExternalSeries(namespace string) (queryPart, error) {
|
||||||
queryParts := n.createQueryPartsFromSelector(metricSelector)
|
return queryPart{
|
||||||
|
labelName: n.externalMetricNamespaceLabel,
|
||||||
|
values: []string{namespace},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *metricNamer) QueryForExternalSeries(namespace string, series string, metricSelector labels.Selector) (prom.Selector, error) {
|
||||||
|
queryParts := []queryPart{}
|
||||||
|
|
||||||
|
if namespace != "" {
|
||||||
|
//Build up the namespace part of the query.
|
||||||
|
namespaceQueryPart, err := n.buildNamespaceQueryPartForExternalSeries(namespace)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
queryParts = append(queryParts, namespaceQueryPart)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Build up the query parts from the selector.
|
||||||
|
queryParts = append(queryParts, n.createQueryPartsFromSelector(metricSelector)...)
|
||||||
|
|
||||||
selector, err := n.queryBuilder.BuildSelector(series, "", []string{}, queryParts)
|
selector, err := n.queryBuilder.BuildSelector(series, "", []string{}, queryParts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -87,69 +87,3 @@ func (l *periodicMetricLister) notifyListeners() {
|
||||||
func (l *periodicMetricLister) UpdateNow() {
|
func (l *periodicMetricLister) UpdateNow() {
|
||||||
l.updateMetrics()
|
l.updateMetrics()
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (l *periodicMetricLister) updateMetrics() (metricUpdateResult, error) {
|
|
||||||
|
|
||||||
// result := metricUpdateResult{
|
|
||||||
// series: make([][]prom.Series, 0),
|
|
||||||
// namers: make([]MetricNamer, 0),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// startTime := pmodel.Now().Add(-1 * l.updateInterval)
|
|
||||||
|
|
||||||
// // these can take a while on large clusters, so launch in parallel
|
|
||||||
// // and don't duplicate
|
|
||||||
// selectors := make(map[prom.Selector]struct{})
|
|
||||||
// selectorSeriesChan := make(chan selectorSeries, len(l.namers))
|
|
||||||
// errs := make(chan error, len(l.namers))
|
|
||||||
// for _, namer := range l.namers {
|
|
||||||
// sel := namer.Selector()
|
|
||||||
// if _, ok := selectors[sel]; ok {
|
|
||||||
// errs <- nil
|
|
||||||
// selectorSeriesChan <- selectorSeries{}
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// selectors[sel] = struct{}{}
|
|
||||||
// go func() {
|
|
||||||
// series, err := l.promClient.Series(context.TODO(), pmodel.Interval{startTime, 0}, sel)
|
|
||||||
// if err != nil {
|
|
||||||
// errs <- fmt.Errorf("unable to fetch metrics for query %q: %v", sel, err)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// errs <- nil
|
|
||||||
// selectorSeriesChan <- selectorSeries{
|
|
||||||
// selector: sel,
|
|
||||||
// series: series,
|
|
||||||
// }
|
|
||||||
// }()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // don't do duplicate queries when it's just the matchers that change
|
|
||||||
// seriesCacheByQuery := make(map[prom.Selector][]prom.Series)
|
|
||||||
|
|
||||||
// // iterate through, blocking until we've got all results
|
|
||||||
// for range l.namers {
|
|
||||||
// if err := <-errs; err != nil {
|
|
||||||
// return result, fmt.Errorf("unable to update list of all metrics: %v", err)
|
|
||||||
// }
|
|
||||||
// if ss := <-selectorSeriesChan; ss.series != nil {
|
|
||||||
// seriesCacheByQuery[ss.selector] = ss.series
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// close(errs)
|
|
||||||
|
|
||||||
// newSeries := make([][]prom.Series, len(l.namers))
|
|
||||||
// for i, namer := range l.namers {
|
|
||||||
// series, cached := seriesCacheByQuery[namer.Selector()]
|
|
||||||
// if !cached {
|
|
||||||
// return result, fmt.Errorf("unable to update list of all metrics: no metrics retrieved for query %q", namer.Selector())
|
|
||||||
// }
|
|
||||||
// newSeries[i] = namer.FilterSeries(series)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// glog.V(10).Infof("Set available metric list from Prometheus to: %v", newSeries)
|
|
||||||
|
|
||||||
// result.series = newSeries
|
|
||||||
// result.namers = l.namers
|
|
||||||
// return result, nil
|
|
||||||
// }
|
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,11 @@ type prometheusProvider struct {
|
||||||
SeriesRegistry
|
SeriesRegistry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewPrometheusProvider creates an CustomMetricsProvider capable of responding to Kubernetes requests for custom metric data.
|
||||||
func NewPrometheusProvider(mapper apimeta.RESTMapper, kubeClient dynamic.Interface, promClient prom.Client, namers []MetricNamer, updateInterval time.Duration) (provider.CustomMetricsProvider, Runnable) {
|
func NewPrometheusProvider(mapper apimeta.RESTMapper, kubeClient dynamic.Interface, promClient prom.Client, namers []MetricNamer, updateInterval time.Duration) (provider.CustomMetricsProvider, Runnable) {
|
||||||
|
//TODO: AC - Consider injecting these objects and calling .Run() before calling this function.
|
||||||
basicLister := NewBasicMetricLister(promClient, namers, updateInterval)
|
basicLister := NewBasicMetricLister(promClient, namers, updateInterval)
|
||||||
//TODO: Be sure to run this runnable.
|
|
||||||
// periodicLister, periodicRunnable := NewPeriodicMetricLister(basicLister, updateInterval)
|
|
||||||
periodicLister, _ := NewPeriodicMetricLister(basicLister, updateInterval)
|
periodicLister, _ := NewPeriodicMetricLister(basicLister, updateInterval)
|
||||||
|
|
||||||
seriesRegistry := NewBasicSeriesRegistry(periodicLister, mapper)
|
seriesRegistry := NewBasicSeriesRegistry(periodicLister, mapper)
|
||||||
|
|
||||||
return &prometheusProvider{
|
return &prometheusProvider{
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//QueryBuilder provides functions for generating Prometheus queries.
|
||||||
type QueryBuilder interface {
|
type QueryBuilder interface {
|
||||||
BuildSelector(seriesName string, groupBy string, groupBySlice []string, queryParts []queryPart) (prom.Selector, error)
|
BuildSelector(seriesName string, groupBy string, groupBySlice []string, queryParts []queryPart) (prom.Selector, error)
|
||||||
}
|
}
|
||||||
|
|
@ -17,6 +18,7 @@ type queryBuilder struct {
|
||||||
metricsQueryTemplate *template.Template
|
metricsQueryTemplate *template.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewQueryBuilder creates a QueryBuilder.
|
||||||
func NewQueryBuilder(metricsQuery string) (QueryBuilder, error) {
|
func NewQueryBuilder(metricsQuery string) (QueryBuilder, error) {
|
||||||
metricsQueryTemplate, err := template.New("metrics-query").Delims("<<", ">>").Parse(metricsQuery)
|
metricsQueryTemplate, err := template.New("metrics-query").Delims("<<", ">>").Parse(metricsQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -79,4 +79,4 @@ func TestQueryWithGroupBy(t *testing.T) {
|
||||||
require.Equal(t, selector, expectation)
|
require.Equal(t, selector, expectation)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Ensure that the LabelValuesByName and GroupBySlice placeholders function correctly.
|
//TODO: AC - Ensure that the LabelValuesByName and GroupBySlice placeholders function correctly.
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,9 @@ import (
|
||||||
pmodel "github.com/prometheus/common/model"
|
pmodel "github.com/prometheus/common/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//ResourceConverter is a type for extracting associated Kubernetes GroupResource objects from
|
||||||
|
//Prometheus series and generating appropriate labels to target specific Kubernetes GroupResource
|
||||||
|
//objects.
|
||||||
type ResourceConverter interface {
|
type ResourceConverter interface {
|
||||||
// ResourcesForSeries returns the group-resources associated with the given series,
|
// ResourcesForSeries returns the group-resources associated with the given series,
|
||||||
// as well as whether or not the given series has the "namespace" resource).
|
// as well as whether or not the given series has the "namespace" resource).
|
||||||
|
|
@ -34,6 +37,7 @@ type resourceConverter struct {
|
||||||
labelTemplate *template.Template
|
labelTemplate *template.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewResourceConverter creates a ResourceConverter that will use the provided parameters to map data between Prometheus and Kubernetes.
|
||||||
func NewResourceConverter(resourceTemplate string, overrides map[string]config.GroupResource, mapper apimeta.RESTMapper) (ResourceConverter, error) {
|
func NewResourceConverter(resourceTemplate string, overrides map[string]config.GroupResource, mapper apimeta.RESTMapper) (ResourceConverter, error) {
|
||||||
converter := &resourceConverter{
|
converter := &resourceConverter{
|
||||||
labelToResource: make(map[pmodel.LabelName]schema.GroupResource),
|
labelToResource: make(map[pmodel.LabelName]schema.GroupResource),
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import (
|
||||||
"github.com/directxman12/k8s-prometheus-adapter/pkg/config"
|
"github.com/directxman12/k8s-prometheus-adapter/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//SeriesFilterer provides functions for filtering collections of Prometheus series
|
||||||
|
//to only those that meet certain requirements.
|
||||||
type SeriesFilterer interface {
|
type SeriesFilterer interface {
|
||||||
FilterSeries(series []prom.Series) []prom.Series
|
FilterSeries(series []prom.Series) []prom.Series
|
||||||
AddRequirement(filter config.RegexFilter) error
|
AddRequirement(filter config.RegexFilter) error
|
||||||
|
|
@ -16,6 +18,8 @@ type seriesFilterer struct {
|
||||||
seriesMatchers []*reMatcher
|
seriesMatchers []*reMatcher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewSeriesFilterer creates a SeriesFilterer that will remove any series that do not
|
||||||
|
//meet the requirements of the provided RegexFilter(s).
|
||||||
func NewSeriesFilterer(filters []config.RegexFilter) (SeriesFilterer, error) {
|
func NewSeriesFilterer(filters []config.RegexFilter) (SeriesFilterer, error) {
|
||||||
seriesMatchers := make([]*reMatcher, len(filters))
|
seriesMatchers := make([]*reMatcher, len(filters))
|
||||||
for i, filterRaw := range filters {
|
for i, filterRaw := range filters {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import (
|
||||||
|
|
||||||
"github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider"
|
"github.com/kubernetes-incubator/custom-metrics-apiserver/pkg/provider"
|
||||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
|
|
||||||
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
prom "github.com/directxman12/k8s-prometheus-adapter/pkg/client"
|
||||||
"github.com/directxman12/k8s-prometheus-adapter/pkg/config"
|
"github.com/directxman12/k8s-prometheus-adapter/pkg/config"
|
||||||
|
|
@ -49,8 +48,6 @@ type SeriesRegistry interface {
|
||||||
// SeriesForMetric looks up the minimum required series information to make a query for the given metric
|
// SeriesForMetric looks up the minimum required series information to make a query for the given metric
|
||||||
// against the given resource (namespace may be empty for non-namespaced resources)
|
// against the given resource (namespace may be empty for non-namespaced resources)
|
||||||
QueryForMetric(info provider.CustomMetricInfo, namespace string, resourceNames ...string) (query prom.Selector, found bool)
|
QueryForMetric(info provider.CustomMetricInfo, namespace string, resourceNames ...string) (query prom.Selector, found bool)
|
||||||
// TODO: Don't house the external metric stuff side-by-side with the custom metric stuff.
|
|
||||||
QueryForExternalMetric(info provider.ExternalMetricInfo, metricSelector labels.Selector) (query prom.Selector, found bool)
|
|
||||||
// MatchValuesToNames matches result values to resource names for the given metric and value set
|
// MatchValuesToNames matches result values to resource names for the given metric and value set
|
||||||
MatchValuesToNames(metricInfo provider.CustomMetricInfo, values pmodel.Vector) (matchedValues map[string]pmodel.SampleValue, found bool)
|
MatchValuesToNames(metricInfo provider.CustomMetricInfo, values pmodel.Vector) (matchedValues map[string]pmodel.SampleValue, found bool)
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +75,7 @@ type basicSeriesRegistry struct {
|
||||||
metricLister MetricListerWithNotification
|
metricLister MetricListerWithNotification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewBasicSeriesRegistry creates a SeriesRegistry driven by the data from the provided MetricLister.
|
||||||
func NewBasicSeriesRegistry(lister MetricListerWithNotification, mapper apimeta.RESTMapper) SeriesRegistry {
|
func NewBasicSeriesRegistry(lister MetricListerWithNotification, mapper apimeta.RESTMapper) SeriesRegistry {
|
||||||
var registry = basicSeriesRegistry{
|
var registry = basicSeriesRegistry{
|
||||||
mapper: mapper,
|
mapper: mapper,
|
||||||
|
|
@ -93,7 +91,7 @@ func (r *basicSeriesRegistry) filterMetrics(result metricUpdateResult) metricUpd
|
||||||
namers := make([]MetricNamer, 0)
|
namers := make([]MetricNamer, 0)
|
||||||
series := make([][]prom.Series, 0)
|
series := make([][]prom.Series, 0)
|
||||||
|
|
||||||
targetType := config.MetricType("Custom")
|
targetType := config.Custom
|
||||||
|
|
||||||
for i, namer := range result.namers {
|
for i, namer := range result.namers {
|
||||||
if namer.MetricType() == targetType {
|
if namer.MetricType() == targetType {
|
||||||
|
|
@ -205,30 +203,6 @@ func (r *basicSeriesRegistry) QueryForMetric(metricInfo provider.CustomMetricInf
|
||||||
return query, true
|
return query, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *basicSeriesRegistry) QueryForExternalMetric(metricInfo provider.ExternalMetricInfo, metricSelector labels.Selector) (query prom.Selector, found bool) {
|
|
||||||
r.mu.RLock()
|
|
||||||
defer r.mu.RUnlock()
|
|
||||||
//TODO: Implementation
|
|
||||||
return "", false
|
|
||||||
// info, infoFound := r.info[metricInfo]
|
|
||||||
// if !infoFound {
|
|
||||||
// //TODO: Weird that it switches between types here.
|
|
||||||
// glog.V(10).Infof("metric %v not registered", metricInfo)
|
|
||||||
// return "", false
|
|
||||||
// }
|
|
||||||
|
|
||||||
// query, err := info.namer.QueryForExternalSeries(info.seriesName, metricSelector)
|
|
||||||
// if err != nil {
|
|
||||||
// //TODO: See what was being .String() and implement that for ExternalMetricInfo.
|
|
||||||
// // errorVal := metricInfo.String()
|
|
||||||
// errorVal := "something"
|
|
||||||
// glog.Errorf("unable to construct query for metric %s: %v", errorVal, err)
|
|
||||||
// return "", false
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return query, true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *basicSeriesRegistry) MatchValuesToNames(metricInfo provider.CustomMetricInfo, values pmodel.Vector) (matchedValues map[string]pmodel.SampleValue, found bool) {
|
func (r *basicSeriesRegistry) MatchValuesToNames(metricInfo provider.CustomMetricInfo, values pmodel.Vector) (matchedValues map[string]pmodel.SampleValue, found bool) {
|
||||||
r.mu.RLock()
|
r.mu.RLock()
|
||||||
defer r.mu.RUnlock()
|
defer r.mu.RUnlock()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue