github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/operators/prometheus/prometheus.go (about) 1 // Copyright 2023 The Inspektor Gadget authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package prometheus 16 17 import ( 18 "fmt" 19 "net/http" 20 21 "github.com/prometheus/client_golang/prometheus/promhttp" 22 log "github.com/sirupsen/logrus" 23 "go.opentelemetry.io/otel/exporters/prometheus" 24 "go.opentelemetry.io/otel/metric" 25 sdkmetric "go.opentelemetry.io/otel/sdk/metric" 26 27 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets" 28 "github.com/inspektor-gadget/inspektor-gadget/pkg/operators" 29 "github.com/inspektor-gadget/inspektor-gadget/pkg/params" 30 "github.com/inspektor-gadget/inspektor-gadget/pkg/prometheus/config" 31 ) 32 33 type PrometheusProvider interface { 34 GetPrometheusConfig() *config.Config 35 SetMetricsProvider(metric.MeterProvider) 36 } 37 38 const ( 39 // ParamEnableMetrics = "enable-metrics" 40 ParamListenAddress = "metrics-listen-address" 41 ParamMetricsPath = "metrics-path" 42 // keep aligned with values in pkg/resources/manifests/deploy.yaml 43 DefaultListenAddr = "0.0.0.0:2223" 44 DefaultMetricsPath = "/metrics" 45 ) 46 47 type Prometheus struct { 48 exporter *prometheus.Exporter 49 meterProvider metric.MeterProvider 50 bucketConfigs map[string]*BucketConfig 51 } 52 53 func (p *Prometheus) EnrichEvent(a any) error { 54 return nil 55 } 56 57 func (p *Prometheus) Name() string { 58 return "Prometheus" 59 } 60 61 func (p *Prometheus) Description() string { 62 return "Provides a facility to export metrics using Prometheus" 63 } 64 65 func (p *Prometheus) Dependencies() []string { 66 return nil 67 } 68 69 func (p *Prometheus) GlobalParamDescs() params.ParamDescs { 70 return params.ParamDescs{ 71 // TODO: this should be a deploy time flag 72 //{ 73 // Key: ParamEnableMetrics, 74 // Title: "Enable Prometheus metrics", 75 // DefaultValue: "false", 76 // Description: "Enables exporting prometheus metrics", 77 // TypeHint: params.TypeBool, 78 //}, 79 // TODO: find a way to expose this to ig-k8s users 80 { 81 Key: ParamListenAddress, 82 Title: "Listen address", 83 DefaultValue: DefaultListenAddr, 84 Description: "Address to serve prometheus metrics on", 85 }, 86 { 87 Key: ParamMetricsPath, 88 Title: "Metrics path", 89 DefaultValue: DefaultMetricsPath, 90 Description: "Path to export prometheus metrics on", 91 }, 92 } 93 } 94 95 func (p *Prometheus) ParamDescs() params.ParamDescs { 96 return nil 97 } 98 99 func (p *Prometheus) Init(globalParams *params.Params) error { 100 //if !globalParams.Get(ParamEnableMetrics).AsBool() { 101 // return nil 102 //} 103 104 exporter, err := prometheus.New() 105 if err != nil { 106 return fmt.Errorf("initialize prometheus exporter: %w", err) 107 } 108 p.exporter = exporter 109 p.meterProvider = sdkmetric.NewMeterProvider(sdkmetric.WithReader(exporter), sdkmetric.WithView(p.histogramViewFunc())) 110 111 listenAddress := globalParams.Get(ParamListenAddress).AsString() 112 metricsPath := globalParams.Get(ParamMetricsPath).AsString() 113 114 go func() { 115 mux := http.NewServeMux() 116 mux.Handle(metricsPath, promhttp.Handler()) 117 err := http.ListenAndServe(listenAddress, mux) 118 if err != nil { 119 log.Errorf("serving http: %s", err) 120 return 121 } 122 }() 123 return nil 124 } 125 126 func (p *Prometheus) CanOperateOn(gadget gadgets.GadgetDesc) bool { 127 inst, ok := gadget.(gadgets.GadgetInstantiate) 128 if !ok { 129 return false 130 } 131 tempInstance, err := inst.NewInstance() 132 if err != nil { 133 return false 134 } 135 if _, ok := tempInstance.(PrometheusProvider); !ok { 136 return false 137 } 138 return true 139 } 140 141 func (p *Prometheus) Close() error { 142 return nil 143 } 144 145 func (p *Prometheus) Instantiate(gadgetCtx operators.GadgetContext, gadgetInstance any, params *params.Params) (operators.OperatorInstance, error) { 146 if provider, ok := gadgetInstance.(PrometheusProvider); ok { 147 provider.SetMetricsProvider(p.meterProvider) 148 p.bucketConfigs = bucketConfigsFromConfig(provider.GetPrometheusConfig()) 149 } 150 return p, nil 151 } 152 153 func (p *Prometheus) PreGadgetRun() error { 154 return nil 155 } 156 157 func (p *Prometheus) PostGadgetRun() error { 158 return nil 159 } 160 161 func init() { 162 operators.Register(&Prometheus{}) 163 }