mirror of
				https://github.com/prometheus/node_exporter.git
				synced 2025-08-20 18:33:52 -07:00 
			
		
		
		
	* remove injection hook for textfile metrics, convert them to prometheus format * add support for summaries * add support for histograms * add logic for handling inconsistent labels within a metric family for counter, gauge, untyped * change logic for parsing the metrics textfile * fix logic to adding missing labels * Export time and error metrics for textfiles * Add tests for new textfile collector, fix found bugs * refactor Update() to split into smaller functions * remove parseTextFiles(), fix import issue * add mtime metric directly to channel, fix handling of mtime during testing * rename variables related to labels * refactor: add default case, remove if guard for metrics, remove extra loop and slice * refactor: remove extra loop iterating over metric families * test: add test case for different metric type, fix found bug * test: add test for metrics with inconsistent labels * test: add test for histogram * test: add test for histogram with extra dimension * test: add test for summary * test: add test for summary with extra dimension * remove unnecessary creation of protobuf * nit: remove extra blank line
		
			
				
	
	
		
			123 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2015 The Prometheus Authors
 | |
| // 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 collector
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"io/ioutil"
 | |
| 	"net/http"
 | |
| 	"net/http/httptest"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/prometheus/client_golang/prometheus"
 | |
| 	"github.com/prometheus/client_golang/prometheus/promhttp"
 | |
| 	"github.com/prometheus/common/log"
 | |
| 	kingpin "gopkg.in/alecthomas/kingpin.v2"
 | |
| )
 | |
| 
 | |
| type collectorAdapter struct {
 | |
| 	Collector
 | |
| }
 | |
| 
 | |
| // Describe implements the prometheus.Collector interface.
 | |
| func (a collectorAdapter) Describe(ch chan<- *prometheus.Desc) {
 | |
| 	// We have to send *some* metric in Describe, but we don't know which ones
 | |
| 	// we're going to get, so just send a dummy metric.
 | |
| 	ch <- prometheus.NewDesc("dummy_metric", "Dummy metric.", nil, nil)
 | |
| }
 | |
| 
 | |
| // Collect implements the prometheus.Collector interface.
 | |
| func (a collectorAdapter) Collect(ch chan<- prometheus.Metric) {
 | |
| 	err := a.Update(ch)
 | |
| 	if err != nil {
 | |
| 		panic(fmt.Sprintf("failed to update collector: %v", err))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestTextfileCollector(t *testing.T) {
 | |
| 	tests := []struct {
 | |
| 		path string
 | |
| 		out  string
 | |
| 	}{
 | |
| 		{
 | |
| 			path: "fixtures/textfile/no_metric_files",
 | |
| 			out:  "fixtures/textfile/no_metric_files.out",
 | |
| 		},
 | |
| 		{
 | |
| 			path: "fixtures/textfile/two_metric_files",
 | |
| 			out:  "fixtures/textfile/two_metric_files.out",
 | |
| 		},
 | |
| 		{
 | |
| 			path: "fixtures/textfile/nonexistent_path",
 | |
| 			out:  "fixtures/textfile/nonexistent_path.out",
 | |
| 		},
 | |
| 		{
 | |
| 			path: "fixtures/textfile/different_metric_types",
 | |
| 			out:  "fixtures/textfile/different_metric_types.out",
 | |
| 		},
 | |
| 		{
 | |
| 			path: "fixtures/textfile/inconsistent_metrics",
 | |
| 			out:  "fixtures/textfile/inconsistent_metrics.out",
 | |
| 		},
 | |
| 		{
 | |
| 			path: "fixtures/textfile/histogram",
 | |
| 			out:  "fixtures/textfile/histogram.out",
 | |
| 		},
 | |
| 		{
 | |
| 			path: "fixtures/textfile/histogram_extra_dimension",
 | |
| 			out:  "fixtures/textfile/histogram_extra_dimension.out",
 | |
| 		},
 | |
| 		{
 | |
| 			path: "fixtures/textfile/summary",
 | |
| 			out:  "fixtures/textfile/summary.out",
 | |
| 		},
 | |
| 		{
 | |
| 			path: "fixtures/textfile/summary_extra_dimension",
 | |
| 			out:  "fixtures/textfile/summary_extra_dimension.out",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for i, test := range tests {
 | |
| 		mtime := 1.0
 | |
| 		c := &textFileCollector{
 | |
| 			path:  test.path,
 | |
| 			mtime: &mtime,
 | |
| 		}
 | |
| 
 | |
| 		// Suppress a log message about `nonexistent_path` not existing, this is
 | |
| 		// expected and clutters the test output.
 | |
| 		log.AddFlags(kingpin.CommandLine)
 | |
| 		_, err := kingpin.CommandLine.Parse([]string{"--log.level", "fatal"})
 | |
| 		if err != nil {
 | |
| 			t.Fatal(err)
 | |
| 		}
 | |
| 
 | |
| 		registry := prometheus.NewRegistry()
 | |
| 		registry.MustRegister(collectorAdapter{c})
 | |
| 
 | |
| 		rw := httptest.NewRecorder()
 | |
| 		promhttp.HandlerFor(registry, promhttp.HandlerOpts{}).ServeHTTP(rw, &http.Request{})
 | |
| 		got := string(rw.Body.String())
 | |
| 
 | |
| 		want, err := ioutil.ReadFile(test.out)
 | |
| 		if err != nil {
 | |
| 			t.Fatalf("%d. error reading fixture file %s: %s", i, test.out, err)
 | |
| 		}
 | |
| 
 | |
| 		if string(want) != got {
 | |
| 			t.Fatalf("%d.%q want:\n\n%s\n\ngot:\n\n%s", i, test.path, string(want), got)
 | |
| 		}
 | |
| 	}
 | |
| }
 |