fix: initialize ManagedContainers metric with correct count on startup
SyncContainers now reports the delta between actual container count and the UpDownCounter value, so the metric reflects reality after startup and reconnect syncs. Deploy/Remove also track managedCount to keep the counter consistent across the full lifecycle.
- commit
- 0567a55682aa3693aef35f0f8c8c079bef779cf0
- author
- brice · · 2026-02-10 08:50 UTC
- parent
- ea73af7
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +13 -0
M internal/usecase/container/service.go +13 -0
| @@ -76,6 +76,7 @@ type Service struct { | |||
| 76 | 76 | metrics *telemetry.Metrics | |
| 77 | 77 | containers map[string]*domain.Container | |
| 78 | 78 | attachments map[string][]string // ownerDomain → []containerIDs | |
| 79 | + | managedCount int64 // tracks UpDownCounter value for delta computation | |
| 79 | 80 | mu sync.RWMutex | |
| 80 | 81 | deployMu sync.Map // per-domain deploy locks (domain → *domainDeployLock) | |
| 81 | 82 | monitor *Monitor | |
| @@ -456,6 +457,9 @@ func (s *Service) activateDeployedContainer(ctx context.Context, domainName stri | |||
| 456 | 457 | s.mu.Lock() | |
| 457 | 458 | _, wasTracked := s.containers[domainName] | |
| 458 | 459 | s.containers[domainName] = container | |
| 460 | + | if !wasTracked { | |
| 461 | + | s.managedCount++ | |
| 462 | + | } | |
| 459 | 463 | s.mu.Unlock() | |
| 460 | 464 | ||
| 461 | 465 | // Track managed container count (only increment for new domains, not replacements) | |
| @@ -679,6 +683,7 @@ func (s *Service) Remove(ctx context.Context, containerID string, force bool) er | |||
| 679 | 683 | if c.ID == containerID { | |
| 680 | 684 | delete(s.containers, d) | |
| 681 | 685 | removedDomain = d | |
| 686 | + | s.managedCount-- | |
| 682 | 687 | log.Info().Str("domain", d).Msg("container removed") | |
| 683 | 688 | break | |
| 684 | 689 | } | |
| @@ -912,8 +917,16 @@ func (s *Service) SyncContainers(ctx context.Context) error { | |||
| 912 | 917 | ||
| 913 | 918 | s.mu.Lock() | |
| 914 | 919 | s.containers = managed | |
| 920 | + | newCount := int64(len(managed)) | |
| 921 | + | delta := newCount - s.managedCount | |
| 922 | + | s.managedCount = newCount | |
| 915 | 923 | s.mu.Unlock() | |
| 916 | 924 | ||
| 925 | + | // Report initial/delta managed container count to OTel UpDownCounter. | |
| 926 | + | if delta != 0 && s.metrics != nil { | |
| 927 | + | s.metrics.ManagedContainers.Add(ctx, delta) | |
| 928 | + | } | |
| 929 | + | ||
| 917 | 930 | log.Info().Int(zerowrap.FieldCount, len(managed)).Msg("container state synchronized") | |
| 918 | 931 | return nil | |
| 919 | 932 | } | |
| @@ -76,6 +76,7 @@ type Service struct { | |||||
| 76 | metrics *telemetry.Metrics | 76 | metrics *telemetry.Metrics | ||
| 77 | containers map[string]*domain.Container | 77 | containers map[string]*domain.Container | ||
| 78 | attachments map[string][]string // ownerDomain → []containerIDs | 78 | attachments map[string][]string // ownerDomain → []containerIDs | ||
| 79 | + | managedCount int64 // tracks UpDownCounter value for delta computation | |||
| 79 | mu sync.RWMutex | 80 | mu sync.RWMutex | ||
| 80 | deployMu sync.Map // per-domain deploy locks (domain → *domainDeployLock) | 81 | deployMu sync.Map // per-domain deploy locks (domain → *domainDeployLock) | ||
| 81 | monitor *Monitor | 82 | monitor *Monitor | ||
| @@ -456,6 +457,9 @@ func (s *Service) activateDeployedContainer(ctx context.Context, domainName stri | |||||
| 456 | s.mu.Lock() | 457 | s.mu.Lock() | ||
| 457 | _, wasTracked := s.containers[domainName] | 458 | _, wasTracked := s.containers[domainName] | ||
| 458 | s.containers[domainName] = container | 459 | s.containers[domainName] = container | ||
| 460 | + | if !wasTracked { | |||
| 461 | + | s.managedCount++ | |||
| 462 | + | } | |||
| 459 | s.mu.Unlock() | 463 | s.mu.Unlock() | ||
| 460 | 464 | ||||
| 461 | // Track managed container count (only increment for new domains, not replacements) | 465 | // Track managed container count (only increment for new domains, not replacements) | ||
| @@ -679,6 +683,7 @@ func (s *Service) Remove(ctx context.Context, containerID string, force bool) er | |||||
| 679 | if c.ID == containerID { | 683 | if c.ID == containerID { | ||
| 680 | delete(s.containers, d) | 684 | delete(s.containers, d) | ||
| 681 | removedDomain = d | 685 | removedDomain = d | ||
| 686 | + | s.managedCount-- | |||
| 682 | log.Info().Str("domain", d).Msg("container removed") | 687 | log.Info().Str("domain", d).Msg("container removed") | ||
| 683 | break | 688 | break | ||
| 684 | } | 689 | } | ||
| @@ -912,8 +917,16 @@ func (s *Service) SyncContainers(ctx context.Context) error { | |||||
| 912 | 917 | ||||
| 913 | s.mu.Lock() | 918 | s.mu.Lock() | ||
| 914 | s.containers = managed | 919 | s.containers = managed | ||
| 920 | + | newCount := int64(len(managed)) | |||
| 921 | + | delta := newCount - s.managedCount | |||
| 922 | + | s.managedCount = newCount | |||
| 915 | s.mu.Unlock() | 923 | s.mu.Unlock() | ||
| 916 | 924 | ||||
| 925 | + | // Report initial/delta managed container count to OTel UpDownCounter. | |||
| 926 | + | if delta != 0 && s.metrics != nil { | |||
| 927 | + | s.metrics.ManagedContainers.Add(ctx, delta) | |||
| 928 | + | } | |||
| 929 | + | ||||
| 917 | log.Info().Int(zerowrap.FieldCount, len(managed)).Msg("container state synchronized") | 930 | log.Info().Int(zerowrap.FieldCount, len(managed)).Msg("container state synchronized") | ||
| 918 | return nil | 931 | return nil | ||
| 919 | } | 932 | } | ||