mirror of
https://github.com/project-zot/zot.git
synced 2025-01-13 22:50:38 -05:00
refactor: Review metrics endpoints (#1770)
Signed-off-by: Alexei Dodon <adodon@cisco.com>
This commit is contained in:
parent
aae8b7b4e3
commit
14206dd6f3
9 changed files with 76 additions and 80 deletions
|
@ -1,53 +1,53 @@
|
||||||
{
|
{
|
||||||
"distSpecVersion": "1.1.0-dev",
|
"distSpecVersion": "1.1.0-dev",
|
||||||
"storage": {
|
"storage": {
|
||||||
"rootDirectory": "/tmp/zot"
|
"rootDirectory": "/tmp/zot"
|
||||||
},
|
},
|
||||||
"http": {
|
"http": {
|
||||||
"address": "127.0.0.1",
|
"address": "127.0.0.1",
|
||||||
"port": "8080"
|
"port": "8080"
|
||||||
},
|
},
|
||||||
"log": {
|
"log": {
|
||||||
"level": "debug"
|
"level": "debug"
|
||||||
},
|
},
|
||||||
"extensions": {
|
"extensions": {
|
||||||
"metrics": {},
|
"metrics": {},
|
||||||
"sync": {
|
"sync": {
|
||||||
"credentialsFile": "./examples/sync-auth-filepath.json",
|
"credentialsFile": "./examples/sync-auth-filepath.json",
|
||||||
"registries": [
|
"registries": [
|
||||||
{
|
{
|
||||||
"urls": [
|
"urls": [
|
||||||
"https://registry1:5000"
|
"https://registry1:5000"
|
||||||
],
|
],
|
||||||
"onDemand": false,
|
"onDemand": false,
|
||||||
"pollInterval": "6h",
|
"pollInterval": "6h",
|
||||||
"tlsVerify": true,
|
"tlsVerify": true,
|
||||||
"certDir": "/home/user/certs",
|
"certDir": "/home/user/certs",
|
||||||
"maxRetries": 3,
|
"maxRetries": 3,
|
||||||
"retryDelay": "15m",
|
"retryDelay": "15m",
|
||||||
"content": [
|
"content": [
|
||||||
{
|
{
|
||||||
"prefix": "/repo1/repo",
|
"prefix": "/repo1/repo",
|
||||||
"tags": {
|
"tags": {
|
||||||
"regex": "4.*",
|
"regex": "4.*",
|
||||||
"semver": true
|
"semver": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"prefix": "/repo2/repo"
|
"prefix": "/repo2/repo"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"cve": {
|
"cve": {
|
||||||
"updateInterval": "2h"
|
"updateInterval": "2h"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scrub": {
|
"scrub": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"interval": "24h"
|
"interval": "24h"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
"read"
|
"read"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"log": {
|
"log": {
|
||||||
|
|
|
@ -340,6 +340,10 @@ func isOpenIDAuthProviderEnabled(config *Config, provider string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) IsMetricsEnabled() bool {
|
||||||
|
return c.Extensions != nil && c.Extensions.Metrics != nil && *c.Extensions.Metrics.Enable
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Config) IsSearchEnabled() bool {
|
func (c *Config) IsSearchEnabled() bool {
|
||||||
return c.Extensions != nil && c.Extensions.Search != nil && *c.Extensions.Search.Enable
|
return c.Extensions != nil && c.Extensions.Search != nil && *c.Extensions.Search.Enable
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,20 +179,8 @@ func (rh *RouteHandler) SetupRoutes() {
|
||||||
// gql playground
|
// gql playground
|
||||||
gqlPlayground.SetupGQLPlaygroundRoutes(prefixedRouter, rh.c.StoreController, rh.c.Log)
|
gqlPlayground.SetupGQLPlaygroundRoutes(prefixedRouter, rh.c.StoreController, rh.c.Log)
|
||||||
|
|
||||||
// setup extension routes
|
|
||||||
if rh.c.Config != nil {
|
|
||||||
// This logic needs to be reviewed, it should depend on build options
|
|
||||||
// not the general presence of the extensions in config
|
|
||||||
if rh.c.Config.Extensions == nil {
|
|
||||||
// minimal build
|
|
||||||
prefixedRouter.HandleFunc("/metrics", rh.GetMetrics).Methods("GET")
|
|
||||||
} else {
|
|
||||||
// extended build
|
|
||||||
ext.SetupMetricsRoutes(rh.c.Config, rh.c.Router, authHandler, rh.c.Log)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Preconditions for enabling the actual extension routes are part of extensions themselves
|
// Preconditions for enabling the actual extension routes are part of extensions themselves
|
||||||
|
ext.SetupMetricsRoutes(rh.c.Config, rh.c.Router, authHandler, rh.c.Log, rh.c.Metrics)
|
||||||
ext.SetupSearchRoutes(rh.c.Config, prefixedRouter, rh.c.StoreController, rh.c.MetaDB, rh.c.CveInfo,
|
ext.SetupSearchRoutes(rh.c.Config, prefixedRouter, rh.c.StoreController, rh.c.MetaDB, rh.c.CveInfo,
|
||||||
rh.c.Log)
|
rh.c.Log)
|
||||||
ext.SetupImageTrustRoutes(rh.c.Config, prefixedRouter, rh.c.MetaDB, rh.c.Log)
|
ext.SetupImageTrustRoutes(rh.c.Config, prefixedRouter, rh.c.MetaDB, rh.c.Log)
|
||||||
|
@ -1860,11 +1848,6 @@ func (rh *RouteHandler) OpenIDCodeExchangeCallback() rp.CodeExchangeUserinfoCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rh *RouteHandler) GetMetrics(w http.ResponseWriter, r *http.Request) {
|
|
||||||
m := rh.c.Metrics.ReceiveMetrics()
|
|
||||||
zcommon.WriteJSON(w, http.StatusOK, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper routines
|
// helper routines
|
||||||
|
|
||||||
func getContentRange(r *http.Request) (int64 /* from */, int64 /* to */, error) {
|
func getContentRange(r *http.Request) (int64 /* from */, int64 /* to */, error) {
|
||||||
|
|
|
@ -113,7 +113,7 @@ func SessionLogger(ctlr *Controller) mux.MiddlewareFunc {
|
||||||
path = path + "?" + raw
|
path = path + "?" + raw
|
||||||
}
|
}
|
||||||
|
|
||||||
if path != "/v2/metrics" {
|
if path != "/metrics" {
|
||||||
// In order to test metrics feture,the instrumentation related to node exporter
|
// In order to test metrics feture,the instrumentation related to node exporter
|
||||||
// should be handled by node exporter itself (ex: latency)
|
// should be handled by node exporter itself (ex: latency)
|
||||||
monitoring.IncHTTPConnRequests(ctlr.Metrics, method, strconv.Itoa(statusCode))
|
monitoring.IncHTTPConnRequests(ctlr.Metrics, method, strconv.Itoa(statusCode))
|
||||||
|
|
|
@ -121,6 +121,7 @@ func TestNewExporter(t *testing.T) {
|
||||||
So(servercConfig, ShouldNotBeNil)
|
So(servercConfig, ShouldNotBeNil)
|
||||||
baseURL := fmt.Sprintf(BaseURL, serverPort)
|
baseURL := fmt.Sprintf(BaseURL, serverPort)
|
||||||
servercConfig.HTTP.Port = serverPort
|
servercConfig.HTTP.Port = serverPort
|
||||||
|
servercConfig.BinaryType = "minimal"
|
||||||
serverController := zotapi.NewController(servercConfig)
|
serverController := zotapi.NewController(servercConfig)
|
||||||
So(serverController, ShouldNotBeNil)
|
So(serverController, ShouldNotBeNil)
|
||||||
|
|
||||||
|
@ -149,7 +150,7 @@ func TestNewExporter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Side effect of calling this endpoint is that it will enable metrics
|
// Side effect of calling this endpoint is that it will enable metrics
|
||||||
resp, err := resty.R().Get(baseURL + "/v2/metrics")
|
resp, err := resty.R().Get(baseURL + "/metrics")
|
||||||
So(resp, ShouldNotBeNil)
|
So(resp, ShouldNotBeNil)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(resp.StatusCode(), ShouldEqual, 200)
|
So(resp.StatusCode(), ShouldEqual, 200)
|
||||||
|
|
|
@ -8,12 +8,12 @@ import (
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
|
|
||||||
"zotregistry.io/zot/pkg/api/config"
|
"zotregistry.io/zot/pkg/api/config"
|
||||||
|
"zotregistry.io/zot/pkg/extensions/monitoring"
|
||||||
"zotregistry.io/zot/pkg/log"
|
"zotregistry.io/zot/pkg/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func EnableMetricsExtension(config *config.Config, log log.Logger, rootDir string) {
|
func EnableMetricsExtension(config *config.Config, log log.Logger, rootDir string) {
|
||||||
if config.Extensions.Metrics != nil &&
|
if config.IsMetricsEnabled() &&
|
||||||
*config.Extensions.Metrics.Enable &&
|
|
||||||
config.Extensions.Metrics.Prometheus != nil {
|
config.Extensions.Metrics.Prometheus != nil {
|
||||||
if config.Extensions.Metrics.Prometheus.Path == "" {
|
if config.Extensions.Metrics.Prometheus.Path == "" {
|
||||||
config.Extensions.Metrics.Prometheus.Path = "/metrics"
|
config.Extensions.Metrics.Prometheus.Path = "/metrics"
|
||||||
|
@ -26,11 +26,11 @@ func EnableMetricsExtension(config *config.Config, log log.Logger, rootDir strin
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupMetricsRoutes(config *config.Config, router *mux.Router,
|
func SetupMetricsRoutes(config *config.Config, router *mux.Router,
|
||||||
authFunc mux.MiddlewareFunc, log log.Logger,
|
authFunc mux.MiddlewareFunc, log log.Logger, metrics monitoring.MetricServer,
|
||||||
) {
|
) {
|
||||||
log.Info().Msg("setting up metrics routes")
|
log.Info().Msg("setting up metrics routes")
|
||||||
|
|
||||||
if config.Extensions.Metrics != nil && *config.Extensions.Metrics.Enable {
|
if config.IsMetricsEnabled() {
|
||||||
extRouter := router.PathPrefix(config.Extensions.Metrics.Prometheus.Path).Subrouter()
|
extRouter := router.PathPrefix(config.Extensions.Metrics.Prometheus.Path).Subrouter()
|
||||||
extRouter.Use(authFunc)
|
extRouter.Use(authFunc)
|
||||||
extRouter.Methods("GET").Handler(promhttp.Handler())
|
extRouter.Methods("GET").Handler(promhttp.Handler())
|
||||||
|
|
|
@ -4,9 +4,13 @@
|
||||||
package extensions
|
package extensions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"zotregistry.io/zot/pkg/api/config"
|
"zotregistry.io/zot/pkg/api/config"
|
||||||
|
zcommon "zotregistry.io/zot/pkg/common"
|
||||||
|
"zotregistry.io/zot/pkg/extensions/monitoring"
|
||||||
"zotregistry.io/zot/pkg/log"
|
"zotregistry.io/zot/pkg/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,8 +22,12 @@ func EnableMetricsExtension(config *config.Config, log log.Logger, rootDir strin
|
||||||
|
|
||||||
// SetupMetricsRoutes ...
|
// SetupMetricsRoutes ...
|
||||||
func SetupMetricsRoutes(conf *config.Config, router *mux.Router,
|
func SetupMetricsRoutes(conf *config.Config, router *mux.Router,
|
||||||
authFunc mux.MiddlewareFunc, log log.Logger,
|
authFunc mux.MiddlewareFunc, log log.Logger, metrics monitoring.MetricServer,
|
||||||
) {
|
) {
|
||||||
log.Warn().Msg("skipping setting up metrics routes because given zot binary doesn't include this feature," +
|
getMetrics := func(w http.ResponseWriter, r *http.Request) {
|
||||||
"please build a binary that does so")
|
m := metrics.ReceiveMetrics()
|
||||||
|
zcommon.WriteJSON(w, http.StatusOK, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
router.HandleFunc("/metrics", getMetrics).Methods("GET")
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ func NewMetricsClient(config *MetricsConfig, logger log.Logger) *MetricsClient {
|
||||||
|
|
||||||
func (mc *MetricsClient) GetMetrics() (*MetricsInfo, error) {
|
func (mc *MetricsClient) GetMetrics() (*MetricsInfo, error) {
|
||||||
metrics := &MetricsInfo{}
|
metrics := &MetricsInfo{}
|
||||||
if _, err := mc.makeGETRequest(mc.config.Address+"/v2/metrics", metrics); err != nil {
|
if _, err := mc.makeGETRequest(mc.config.Address+"/metrics", metrics); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue