feat: metrics (#1024)

* refactor: switch from opencensus to opentelemetry

* tempo works as designed nooooot

* fix: log traceids

* with grafana agent

* fix: http tracing

* fix: cleanup files

* chore: remove todo

* fix: bad test

* fix: ignore methods in grpc interceptors

* fix: remove test log

* clean up

* typo

* fix(config): configure tracing endpoint

* fix(span): add error id to span

* feat: metrics package

* feat: metrics package

* fix: counter

* fix: metric

* try metrics

* fix: coutner metrics

* fix: active sessin counter

* fix: active sessin counter

* fix: change current Sequence table

* fix: change current Sequence table

* fix: current sequences

* fix: spooler div metrics

* fix: console view

* fix: merge master

* fix: Last spool run on search result instead of eventtimestamp

* fix: go mod

* Update console/src/assets/i18n/de.json

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* fix: pr review

* fix: map

* update oidc pkg

* fix: handlers

* fix: value observer

* fix: remove fmt

* fix: handlers

* fix: tests

* fix: handler minimum cycle duration 1s

* fix(spooler): handler channel buffer

* fix interceptors

Co-authored-by: adlerhurst <silvan.reusser@gmail.com>
Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi
2020-12-02 08:50:59 +01:00
committed by GitHub
parent 723b6b5189
commit 6b3f5b984c
194 changed files with 2570 additions and 1096 deletions

View File

@@ -2,6 +2,12 @@ package api
import (
"context"
admin_es "github.com/caos/zitadel/internal/admin/repository/eventsourcing"
auth_es "github.com/caos/zitadel/internal/auth/repository/eventsourcing"
"github.com/caos/zitadel/internal/telemetry/metrics"
"github.com/caos/zitadel/internal/telemetry/metrics/otel"
view_model "github.com/caos/zitadel/internal/view/model"
"go.opentelemetry.io/otel/api/metric"
"net/http"
"github.com/caos/logging"
@@ -16,7 +22,7 @@ import (
"github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/tracing"
"github.com/caos/zitadel/internal/telemetry/tracing"
)
type Config struct {
@@ -30,19 +36,33 @@ type API struct {
verifier *authz.TokenVerifier
serverPort string
health health
auth auth
admin admin
}
type health interface {
Health(ctx context.Context) error
IamByID(ctx context.Context) (*iam_model.IAM, error)
VerifierClientID(ctx context.Context, appName string) (string, error)
}
func Create(config Config, authZ authz.Config, authZRepo *authz_es.EsRepository, sd systemdefaults.SystemDefaults) *API {
type auth interface {
ActiveUserSessionCount() int64
}
type admin interface {
GetViews() ([]*view_model.View, error)
GetSpoolerDiv(database, viewName string) int64
}
func Create(config Config, authZ authz.Config, authZRepo *authz_es.EsRepository, authRepo *auth_es.EsRepository, adminRepo *admin_es.EsRepository, sd systemdefaults.SystemDefaults) *API {
api := &API{
serverPort: config.GRPC.ServerPort,
}
api.verifier = authz.Start(authZRepo)
api.health = authZRepo
api.auth = authRepo
api.admin = adminRepo
api.grpcServer = server.CreateServer(api.verifier, authZ, sd.DefaultLanguage)
api.gatewayHandler = server.CreateGatewayHandler(config.GRPC)
api.RegisterHandler("", api.healthHandler())
@@ -92,6 +112,7 @@ func (a *API) healthHandler() http.Handler {
handler.HandleFunc("/ready", handleReadiness(checks))
handler.HandleFunc("/validate", handleValidate(checks))
handler.HandleFunc("/clientID", a.handleClientID)
handler.Handle("/metrics", a.handleMetrics())
return handler
}
@@ -132,6 +153,48 @@ func (a *API) handleClientID(w http.ResponseWriter, r *http.Request) {
http_util.MarshalJSON(w, id, nil, http.StatusOK)
}
func (a *API) handleMetrics() http.Handler {
a.registerActiveSessionCounters()
a.registerSpoolerDivCounters()
return metrics.GetExporter()
}
func (a *API) registerActiveSessionCounters() {
metrics.RegisterValueObserver(
metrics.ActiveSessionCounter,
metrics.ActiveSessionCounterDescription,
func(ctx context.Context, result metric.Int64ObserverResult) {
result.Observe(
a.auth.ActiveUserSessionCount(),
)
},
)
}
func (a *API) registerSpoolerDivCounters() {
views, err := a.admin.GetViews()
if err != nil {
logging.Log("API-3M8sd").WithError(err).Error("could not read views for metrics")
return
}
metrics.RegisterValueObserver(
metrics.SpoolerDivCounter,
metrics.SpoolerDivCounterDescription,
func(ctx context.Context, result metric.Int64ObserverResult) {
for _, view := range views {
labels := map[string]interface{}{
metrics.Database: view.Database,
metrics.ViewName: view.ViewName,
}
result.Observe(
a.admin.GetSpoolerDiv(view.Database, view.ViewName),
otel.MapToKeyValue(labels)...,
)
}
},
)
}
type ValidationFunction func(ctx context.Context) error
func validate(ctx context.Context, validations []ValidationFunction) []error {