diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2023-01-19 14:57:59 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2023-01-26 12:21:25 +0300 |
commit | 512aed451d7e2c0c45629a13c1b12d86dece3131 (patch) | |
tree | c19ee2517f7c96c50246e9db17577fc23c163676 | |
parent | b7bebbe148232d804c8586c067b46e84e702517a (diff) |
housekeeping: Add Prometheus metrics for on-disk repository states
While we're already reporting on-disk repository metrics via the logging
infrastructure, this does not easily allow for creating dashboards that
includes all housekeeping-related data in a single place.
Introduce a bunch of new metrics that allow us to report on different
data structures of repositories:
- Metrics reporting whether specific data structures or extensions
exist in the first place.
- Metrics reporting about how many data structures exist, e.g. to
count the number of loose objects or packfiles.
- Metrics reporting about the size of data structures, e.g. to
report the size of `packed-refs`.
With this infrastructure in place it should be possible to build a
high-level dashboard for repository housekeeping that reports on what
gets repacked, how long it takes, and what the on-disk state of repos
is.
Changelog: added
-rw-r--r-- | internal/git/housekeeping/manager.go | 39 | ||||
-rw-r--r-- | internal/git/housekeeping/optimize_repository.go | 38 |
2 files changed, 71 insertions, 6 deletions
diff --git a/internal/git/housekeeping/manager.go b/internal/git/housekeeping/manager.go index f4407aac0..55f1f24c3 100644 --- a/internal/git/housekeeping/manager.go +++ b/internal/git/housekeeping/manager.go @@ -24,11 +24,14 @@ type Manager interface { type RepositoryManager struct { txManager transaction.Manager - tasksTotal *prometheus.CounterVec - tasksLatency *prometheus.HistogramVec - prunedFilesTotal *prometheus.CounterVec - optimizeFunc func(context.Context, *RepositoryManager, *localrepo.Repo, OptimizationStrategy) error - reposInProgress sync.Map + tasksTotal *prometheus.CounterVec + tasksLatency *prometheus.HistogramVec + prunedFilesTotal *prometheus.CounterVec + dataStructureExistence *prometheus.CounterVec + dataStructureCount *prometheus.HistogramVec + dataStructureSize *prometheus.HistogramVec + optimizeFunc func(context.Context, *RepositoryManager, *localrepo.Repo, OptimizationStrategy) error + reposInProgress sync.Map } // NewManager creates a new RepositoryManager. @@ -58,6 +61,29 @@ func NewManager(promCfg gitalycfgprom.Config, txManager transaction.Manager) *Re }, []string{"filetype"}, ), + dataStructureExistence: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "gitaly_housekeeping_data_structure_existence_total", + Help: "Total number of data structures that exist in the repository", + }, + []string{"data_structure", "exists"}, + ), + dataStructureCount: prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "gitaly_housekeeping_data_structure_wcount", + Help: "Total count of the data structures that exist in the repository", + Buckets: prometheus.ExponentialBucketsRange(1, 10_000_000, 16), + }, + []string{"data_structure"}, + ), + dataStructureSize: prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "gitaly_housekeeping_data_structure_size", + Help: "Total size of the data structures that exist in the repository", + Buckets: prometheus.ExponentialBucketsRange(1, 50_000_000_000, 16), + }, + []string{"data_structure"}, + ), optimizeFunc: optimizeRepository, } } @@ -72,4 +98,7 @@ func (m *RepositoryManager) Collect(metrics chan<- prometheus.Metric) { m.tasksTotal.Collect(metrics) m.tasksLatency.Collect(metrics) m.prunedFilesTotal.Collect(metrics) + m.dataStructureExistence.Collect(metrics) + m.dataStructureCount.Collect(metrics) + m.dataStructureSize.Collect(metrics) } diff --git a/internal/git/housekeeping/optimize_repository.go b/internal/git/housekeeping/optimize_repository.go index 0bea6be53..74f70d1b5 100644 --- a/internal/git/housekeeping/optimize_repository.go +++ b/internal/git/housekeeping/optimize_repository.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "strconv" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "github.com/prometheus/client_golang/prometheus" @@ -63,7 +64,7 @@ func (m *RepositoryManager) OptimizeRepository( if err != nil { return fmt.Errorf("deriving repository info: %w", err) } - repositoryInfo.Log(ctx) + m.reportRepositoryInfo(ctx, repositoryInfo) var strategy OptimizationStrategy if cfg.StrategyConstructor == nil { @@ -75,6 +76,41 @@ func (m *RepositoryManager) OptimizeRepository( return m.optimizeFunc(ctx, m, repo, strategy) } +func (m *RepositoryManager) reportRepositoryInfo(ctx context.Context, info stats.RepositoryInfo) { + info.Log(ctx) + + m.reportDataStructureExistence("commit_graph", info.CommitGraph.Exists) + m.reportDataStructureExistence("commit_graph_bloom_filters", info.CommitGraph.HasBloomFilters) + m.reportDataStructureExistence("commit_graph_generation_data", info.CommitGraph.HasGenerationData) + m.reportDataStructureExistence("commit_graph_generation_data_overflow", info.CommitGraph.HasGenerationDataOverflow) + m.reportDataStructureExistence("bitmap", info.Packfiles.Bitmap.Exists) + m.reportDataStructureExistence("multi_pack_index", info.Packfiles.HasMultiPackIndex) + m.reportDataStructureExistence("multi_pack_index_bitmap", info.Packfiles.MultiPackIndexBitmap.Exists) + + m.reportDataStructureCount("loose_objects", info.LooseObjects.Count) + m.reportDataStructureCount("loose_objects_stale_count", info.LooseObjects.StaleCount) + m.reportDataStructureCount("commit_graph_chain", info.CommitGraph.CommitGraphChainLength) + m.reportDataStructureCount("packfiles", info.Packfiles.Count) + m.reportDataStructureCount("loose_references", info.References.LooseReferencesCount) + + m.reportDataStructureSize("loose_objects", info.LooseObjects.Size) + m.reportDataStructureSize("loose_objects_stale", info.LooseObjects.StaleSize) + m.reportDataStructureSize("packfiles", info.Packfiles.Size) + m.reportDataStructureSize("packed_references", info.References.PackedReferencesSize) +} + +func (m *RepositoryManager) reportDataStructureExistence(dataStructure string, exists bool) { + m.dataStructureExistence.WithLabelValues(dataStructure, strconv.FormatBool(exists)).Inc() +} + +func (m *RepositoryManager) reportDataStructureCount(dataStructure string, count uint64) { + m.dataStructureCount.WithLabelValues(dataStructure).Observe(float64(count)) +} + +func (m *RepositoryManager) reportDataStructureSize(dataStructure string, size uint64) { + m.dataStructureSize.WithLabelValues(dataStructure).Observe(float64(size)) +} + func optimizeRepository( ctx context.Context, m *RepositoryManager, |