19
19
package sysinfo
20
20
21
21
import (
22
+ "context"
22
23
"fmt"
23
24
"reflect"
24
25
"strings"
25
26
26
- "github.com/prometheus/client_golang/prometheus"
27
+ "github.com/pkg/errors"
28
+ "go.opencensus.io/stats"
29
+ "go.opencensus.io/stats/view"
30
+ "go.opencensus.io/tag"
27
31
28
32
"github.com/cs3org/reva/pkg/utils"
29
33
)
30
34
31
- // PrometheusExporter exports system information via Prometheus.
32
- type PrometheusExporter struct {
33
- registry * prometheus.Registry
34
- sysInfoMetric prometheus.GaugeFunc
35
- }
35
+ type sysInfoMetricsLabels = map [tag.Key ]string
36
+
37
+ func registerSystemInfoMetrics () error {
38
+ labels := getSystemInfoMetricsLabels ("" , SysInfo )
39
+
40
+ // Collect all labels and their values; the values are stored as mutators
41
+ tagKeys := make ([]tag.Key , 0 , len (labels ))
42
+ mutators := make ([]tag.Mutator , 0 , len (labels ))
43
+ for key , value := range labels {
44
+ tagKeys = append (tagKeys , key )
45
+ mutators = append (mutators , tag .Insert (key , value ))
46
+ }
47
+
48
+ // Create the OpenCensus statistics and a corresponding view
49
+ sysInfoStats := stats .Int64 ("sys_info" , "A metric with a constant '1' value labeled by various system information elements" , stats .UnitDimensionless )
50
+ sysInfoView := & view.View {
51
+ Name : sysInfoStats .Name (),
52
+ Description : sysInfoStats .Description (),
53
+ Measure : sysInfoStats ,
54
+ TagKeys : tagKeys ,
55
+ Aggregation : view .LastValue (),
56
+ }
57
+
58
+ if err := view .Register (sysInfoView ); err != nil {
59
+ return errors .Wrap (err , "unable to register the system info metrics view" )
60
+ }
36
61
37
- func (psysinfo * PrometheusExporter ) init (registry * prometheus.Registry ) error {
38
- // Create all necessary Prometheus objects
39
- psysinfo .registry = registry
40
- psysinfo .sysInfoMetric = prometheus .NewGaugeFunc (
41
- prometheus.GaugeOpts {
42
- Namespace : "revad" ,
43
- Name : "sys_info" ,
44
- Help : "A metric with a constant '1' value labeled by various system information elements" ,
45
- ConstLabels : psysinfo .getLabels ("" , SysInfo ),
46
- },
47
- func () float64 { return 1 },
48
- )
49
-
50
- if err := psysinfo .registry .Register (psysinfo .sysInfoMetric ); err != nil {
51
- return fmt .Errorf ("unable to register the system information metrics: %v" , err )
62
+ // Create a new context to serve the metrics
63
+ if ctx , err := tag .New (context .Background (), mutators ... ); err == nil {
64
+ // Just record a simple hardcoded '1' to expose the system info as a metric
65
+ stats .Record (ctx , sysInfoStats .M (1 ))
66
+ } else {
67
+ return errors .Wrap (err , "unable to create a context for the system info metrics" )
52
68
}
53
69
54
70
return nil
55
71
}
56
72
57
- func ( psysinfo * PrometheusExporter ) getLabels ( root string , i interface {}) prometheus. Labels {
58
- labels := prometheus. Labels {}
73
+ func getSystemInfoMetricsLabels ( root string , i interface {}) sysInfoMetricsLabels {
74
+ labels := sysInfoMetricsLabels {}
59
75
60
76
// Iterate over each field of the given interface, recursively collecting the values as labels
61
77
v := reflect .ValueOf (i ).Elem ()
@@ -77,27 +93,14 @@ func (psysinfo *PrometheusExporter) getLabels(root string, i interface{}) promet
77
93
f := v .Field (i )
78
94
if f .Kind () == reflect .Struct || (f .Kind () == reflect .Ptr && f .Elem ().Kind () == reflect .Struct ) {
79
95
// Merge labels recursively
80
- for key , val := range psysinfo . getLabels (fieldName , f .Interface ()) {
96
+ for key , val := range getSystemInfoMetricsLabels (fieldName , f .Interface ()) {
81
97
labels [key ] = val
82
98
}
83
99
} else { // Store the value of the field in the labels
84
- labels [fieldName ] = fmt .Sprintf ("%v" , f )
100
+ key := tag .MustNewKey (fieldName )
101
+ labels [key ] = fmt .Sprintf ("%v" , f )
85
102
}
86
103
}
87
104
88
105
return labels
89
106
}
90
-
91
- // NewPrometheusExporter creates a new Prometheus system information exporter.
92
- func NewPrometheusExporter (registry * prometheus.Registry ) (* PrometheusExporter , error ) {
93
- if registry == nil {
94
- return nil , fmt .Errorf ("no registry provided" )
95
- }
96
-
97
- exporter := & PrometheusExporter {}
98
- if err := exporter .init (registry ); err != nil {
99
- return nil , err
100
- }
101
-
102
- return exporter , nil
103
- }
0 commit comments