Collect metrics about search and index durations

This commit is contained in:
André Duffeck
2025-07-08 15:03:19 +02:00
parent 273c0ed270
commit 791b4df173
3 changed files with 51 additions and 12 deletions

View File

@@ -2,6 +2,7 @@ package metrics
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var (
@@ -19,41 +20,52 @@ type Metrics struct {
EventsOutstandingAcks prometheus.Gauge
EventsUnprocessed prometheus.Gauge
EventsRedelivered prometheus.Gauge
SearchDuration *prometheus.HistogramVec
IndexDuration *prometheus.HistogramVec
}
// New initializes the available metrics.
func New() *Metrics {
m := &Metrics{
BuildInfo: prometheus.NewGaugeVec(prometheus.GaugeOpts{
BuildInfo: promauto.NewGaugeVec(prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: Subsystem,
Name: "build_info",
Help: "Build information",
}, []string{"version"}),
EventsOutstandingAcks: prometheus.NewGauge(prometheus.GaugeOpts{
EventsOutstandingAcks: promauto.NewGauge(prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: Subsystem,
Name: "events_outstanding_acks",
Help: "Number of outstanding acks for events",
}),
EventsUnprocessed: prometheus.NewGauge(prometheus.GaugeOpts{
EventsUnprocessed: promauto.NewGauge(prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: Subsystem,
Name: "events_unprocessed",
Help: "Number of unprocessed events",
}),
EventsRedelivered: prometheus.NewGauge(prometheus.GaugeOpts{
EventsRedelivered: promauto.NewGauge(prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: Subsystem,
Name: "events_redelivered",
Help: "Number of redelivered events",
}),
SearchDuration: promauto.NewHistogramVec(prometheus.HistogramOpts{
Namespace: Namespace,
Subsystem: Subsystem,
Name: "search_duration_seconds",
Help: "Duration of search operations in seconds",
Buckets: []float64{0.1, 0.5, 1, 2.5, 5, 10, 30, 60},
}, []string{"status"}),
IndexDuration: promauto.NewHistogramVec(prometheus.HistogramOpts{
Namespace: Namespace,
Subsystem: Subsystem,
Name: "index_duration_seconds",
Help: "Duration of indexing operations in seconds",
Buckets: []float64{0.1, 0.5, 1, 2.5, 5, 10, 30, 60, 120, 300, 600, 1200},
}, []string{"status"}),
}
_ = prometheus.Register(m.BuildInfo)
_ = prometheus.Register(m.EventsOutstandingAcks)
_ = prometheus.Register(m.EventsUnprocessed)
_ = prometheus.Register(m.EventsRedelivered)
return m
}

View File

@@ -14,6 +14,7 @@ import (
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
collaborationv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
libregraph "github.com/opencloud-eu/libre-graph-api-go"
revactx "github.com/opencloud-eu/reva/v2/pkg/ctx"
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool"
@@ -21,7 +22,6 @@ import (
"github.com/opencloud-eu/reva/v2/pkg/storage/utils/walker"
"github.com/opencloud-eu/reva/v2/pkg/storagespace"
"github.com/opencloud-eu/reva/v2/pkg/utils"
libregraph "github.com/opencloud-eu/libre-graph-api-go"
"golang.org/x/sync/errgroup"
"google.golang.org/protobuf/types/known/fieldmaskpb"
@@ -31,6 +31,7 @@ import (
"github.com/opencloud-eu/opencloud/services/search/pkg/config"
"github.com/opencloud-eu/opencloud/services/search/pkg/content"
"github.com/opencloud-eu/opencloud/services/search/pkg/engine"
"github.com/opencloud-eu/opencloud/services/search/pkg/metrics"
)
const (
@@ -59,6 +60,7 @@ type Service struct {
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
engine engine.Engine
extractor content.Extractor
metrics *metrics.Metrics
serviceAccountID string
serviceAccountSecret string
@@ -67,12 +69,13 @@ type Service struct {
var errSkipSpace error
// NewService creates a new Provider instance.
func NewService(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], eng engine.Engine, extractor content.Extractor, logger log.Logger, cfg *config.Config) *Service {
func NewService(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], eng engine.Engine, extractor content.Extractor, metrics *metrics.Metrics, logger log.Logger, cfg *config.Config) *Service {
var s = &Service{
gatewaySelector: gatewaySelector,
engine: eng,
logger: logger,
extractor: extractor,
metrics: metrics,
serviceAccountID: cfg.ServiceAccount.ServiceAccountID,
serviceAccountSecret: cfg.ServiceAccount.ServiceAccountSecret,
@@ -85,6 +88,17 @@ func NewService(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], eng e
func (s *Service) Search(ctx context.Context, req *searchsvc.SearchRequest) (*searchsvc.SearchResponse, error) {
s.logger.Debug().Str("query", req.Query).Msg("performing a search")
// collect metrics
startTime := time.Now()
success := false
defer func() {
status := "success"
if !success {
status = "error"
}
s.metrics.SearchDuration.WithLabelValues(status).Observe(time.Since(startTime).Seconds())
}()
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
return nil, err
@@ -255,6 +269,7 @@ func (s *Service) Search(ctx context.Context, req *searchsvc.SearchRequest) (*se
matches = matches[0:limit]
}
success = true
return &searchsvc.SearchResponse{
Matches: matches,
TotalMatches: total,
@@ -425,6 +440,17 @@ func (s *Service) IndexSpace(spaceID *provider.StorageSpaceId) error {
}
rootID.OpaqueId = rootID.SpaceId
// Collect metrics
startTime := time.Now()
success := false
defer func() {
status := "success"
if !success {
status = "error"
}
s.metrics.IndexDuration.WithLabelValues(status).Observe(time.Since(startTime).Seconds())
}()
w := walker.NewWalker(s.gatewaySelector)
err = w.Walk(ownerCtx, &rootID, func(wd string, info *provider.ResourceInfo, err error) error {
if err != nil {
@@ -465,6 +491,7 @@ func (s *Service) IndexSpace(spaceID *provider.StorageSpaceId) error {
}
logDocCount(s.engine, s.logger)
success = true
return nil
}

View File

@@ -79,7 +79,7 @@ func NewHandler(opts ...Option) (searchsvc.SearchProviderHandler, func(), error)
return nil, teardown, fmt.Errorf("unknown search extractor: %s", cfg.Extractor.Type)
}
ss := search.NewService(selector, eng, extractor, logger, cfg)
ss := search.NewService(selector, eng, extractor, options.Metrics, logger, cfg)
// setup event handling