github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/vector/hnsw/metrics.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package hnsw
    13  
    14  import (
    15  	"time"
    16  
    17  	"github.com/prometheus/client_golang/prometheus"
    18  	"github.com/weaviate/weaviate/usecases/monitoring"
    19  )
    20  
    21  type Metrics struct {
    22  	enabled          bool
    23  	tombstones       prometheus.Gauge
    24  	threads          prometheus.Gauge
    25  	insert           prometheus.Gauge
    26  	insertTime       prometheus.ObserverVec
    27  	delete           prometheus.Gauge
    28  	deleteTime       prometheus.ObserverVec
    29  	cleaned          prometheus.Counter
    30  	size             prometheus.Gauge
    31  	grow             prometheus.Observer
    32  	startupProgress  prometheus.Gauge
    33  	startupDurations prometheus.ObserverVec
    34  	startupDiskIO    prometheus.ObserverVec
    35  }
    36  
    37  func NewMetrics(prom *monitoring.PrometheusMetrics,
    38  	className, shardName string,
    39  ) *Metrics {
    40  	if prom == nil {
    41  		return &Metrics{enabled: false}
    42  	}
    43  
    44  	if prom.Group {
    45  		className = "n/a"
    46  		shardName = "n/a"
    47  	}
    48  
    49  	tombstones := prom.VectorIndexTombstones.With(prometheus.Labels{
    50  		"class_name": className,
    51  		"shard_name": shardName,
    52  	})
    53  
    54  	threads := prom.VectorIndexTombstoneCleanupThreads.With(prometheus.Labels{
    55  		"class_name": className,
    56  		"shard_name": shardName,
    57  	})
    58  
    59  	cleaned := prom.VectorIndexTombstoneCleanedCount.With(prometheus.Labels{
    60  		"class_name": className,
    61  		"shard_name": shardName,
    62  	})
    63  
    64  	insert := prom.VectorIndexOperations.With(prometheus.Labels{
    65  		"class_name": className,
    66  		"shard_name": shardName,
    67  		"operation":  "create",
    68  	})
    69  
    70  	insertTime := prom.VectorIndexDurations.MustCurryWith(prometheus.Labels{
    71  		"class_name": className,
    72  		"shard_name": shardName,
    73  		"operation":  "create",
    74  	})
    75  
    76  	del := prom.VectorIndexOperations.With(prometheus.Labels{
    77  		"class_name": className,
    78  		"shard_name": shardName,
    79  		"operation":  "delete",
    80  	})
    81  
    82  	deleteTime := prom.VectorIndexDurations.MustCurryWith(prometheus.Labels{
    83  		"class_name": className,
    84  		"shard_name": shardName,
    85  		"operation":  "delete",
    86  	})
    87  
    88  	size := prom.VectorIndexSize.With(prometheus.Labels{
    89  		"class_name": className,
    90  		"shard_name": shardName,
    91  	})
    92  
    93  	grow := prom.VectorIndexMaintenanceDurations.With(prometheus.Labels{
    94  		"class_name": className,
    95  		"shard_name": shardName,
    96  		"operation":  "grow",
    97  	})
    98  
    99  	startupProgress := prom.StartupProgress.With(prometheus.Labels{
   100  		"class_name": className,
   101  		"shard_name": shardName,
   102  		"operation":  "hnsw_read_commitlogs",
   103  	})
   104  
   105  	startupDurations := prom.StartupDurations.MustCurryWith(prometheus.Labels{
   106  		"class_name": className,
   107  		"shard_name": shardName,
   108  	})
   109  
   110  	startupDiskIO := prom.StartupDiskIO.MustCurryWith(prometheus.Labels{
   111  		"class_name": className,
   112  		"shard_name": shardName,
   113  	})
   114  
   115  	return &Metrics{
   116  		enabled:          true,
   117  		tombstones:       tombstones,
   118  		threads:          threads,
   119  		cleaned:          cleaned,
   120  		insert:           insert,
   121  		insertTime:       insertTime,
   122  		delete:           del,
   123  		deleteTime:       deleteTime,
   124  		size:             size,
   125  		grow:             grow,
   126  		startupProgress:  startupProgress,
   127  		startupDurations: startupDurations,
   128  		startupDiskIO:    startupDiskIO,
   129  	}
   130  }
   131  
   132  func (m *Metrics) AddTombstone() {
   133  	if !m.enabled {
   134  		return
   135  	}
   136  
   137  	m.tombstones.Inc()
   138  }
   139  
   140  func (m *Metrics) RemoveTombstone() {
   141  	if !m.enabled {
   142  		return
   143  	}
   144  
   145  	m.tombstones.Dec()
   146  }
   147  
   148  func (m *Metrics) StartCleanup(threads int) {
   149  	if !m.enabled {
   150  		return
   151  	}
   152  
   153  	m.threads.Add(float64(threads))
   154  }
   155  
   156  func (m *Metrics) EndCleanup(threads int) {
   157  	if !m.enabled {
   158  		return
   159  	}
   160  
   161  	m.threads.Sub(float64(threads))
   162  }
   163  
   164  func (m *Metrics) CleanedUp() {
   165  	if !m.enabled {
   166  		return
   167  	}
   168  
   169  	m.cleaned.Inc()
   170  }
   171  
   172  func (m *Metrics) InsertVector() {
   173  	if !m.enabled {
   174  		return
   175  	}
   176  
   177  	m.insert.Inc()
   178  }
   179  
   180  func (m *Metrics) DeleteVector() {
   181  	if !m.enabled {
   182  		return
   183  	}
   184  
   185  	m.delete.Inc()
   186  }
   187  
   188  func (m *Metrics) SetSize(size int) {
   189  	if !m.enabled {
   190  		return
   191  	}
   192  
   193  	m.size.Set(float64(size))
   194  }
   195  
   196  func (m *Metrics) GrowDuration(start time.Time) {
   197  	if !m.enabled {
   198  		return
   199  	}
   200  
   201  	took := float64(time.Since(start)) / float64(time.Millisecond)
   202  	m.grow.Observe(took)
   203  }
   204  
   205  type Observer func(start time.Time)
   206  
   207  func noOpObserver(start time.Time) {
   208  	// do nothing
   209  }
   210  
   211  func (m *Metrics) TrackInsertObserver(step string) Observer {
   212  	if !m.enabled {
   213  		return noOpObserver
   214  	}
   215  
   216  	curried := m.insertTime.With(prometheus.Labels{"step": step})
   217  
   218  	return func(start time.Time) {
   219  		took := float64(time.Since(start)) / float64(time.Millisecond)
   220  		curried.Observe(took)
   221  	}
   222  }
   223  
   224  func (m *Metrics) TrackDelete(start time.Time, step string) {
   225  	if !m.enabled {
   226  		return
   227  	}
   228  
   229  	took := float64(time.Since(start)) / float64(time.Millisecond)
   230  	m.deleteTime.With(prometheus.Labels{"step": step}).Observe(took)
   231  }
   232  
   233  func (m *Metrics) StartupProgress(ratio float64) {
   234  	if !m.enabled {
   235  		return
   236  	}
   237  
   238  	m.startupProgress.Set(ratio)
   239  }
   240  
   241  func (m *Metrics) TrackStartupTotal(start time.Time) {
   242  	if !m.enabled {
   243  		return
   244  	}
   245  
   246  	took := float64(time.Since(start)) / float64(time.Millisecond)
   247  	m.startupDurations.With(prometheus.Labels{"operation": "hnsw_read_all_commitlogs"}).Observe(took)
   248  }
   249  
   250  func (m *Metrics) TrackStartupIndividual(start time.Time) {
   251  	if !m.enabled {
   252  		return
   253  	}
   254  
   255  	took := float64(time.Since(start)) / float64(time.Millisecond)
   256  	m.startupDurations.With(prometheus.Labels{"operation": "hnsw_read_single_commitlog"}).Observe(took)
   257  }
   258  
   259  func (m *Metrics) TrackStartupReadCommitlogDiskIO(read int64, nanoseconds int64) {
   260  	if !m.enabled {
   261  		return
   262  	}
   263  
   264  	seconds := float64(nanoseconds) / float64(time.Second)
   265  	throughput := float64(read) / float64(seconds)
   266  	m.startupDiskIO.With(prometheus.Labels{"operation": "hnsw_read_commitlog"}).Observe(throughput)
   267  }