Skip to content

Commit 9bc14f7

Browse files
authored
feat: add opentelemtry integration in filter flag (#5247)
* feat: add opentelemtry integration * chore: filter tests cleanup * chore: telemetry fixes * telemetry simplification
1 parent 5e9e25a commit 9bc14f7

5 files changed

Lines changed: 749 additions & 136 deletions

File tree

internal/discovery/worktreediscovery.go

Lines changed: 123 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/gruntwork-io/terragrunt/internal/worktrees"
2222
"github.com/gruntwork-io/terragrunt/options"
2323
"github.com/gruntwork-io/terragrunt/pkg/log"
24+
"github.com/gruntwork-io/terragrunt/telemetry"
2425
"golang.org/x/sync/errgroup"
2526
)
2627

@@ -69,75 +70,117 @@ func (wd *WorktreeDiscovery) Discover(
6970
return component.Components{}, nil
7071
}
7172

72-
discoveredComponents := component.NewThreadSafeComponents(component.Components{})
73-
74-
// Run from and to discovery concurrently for each expression
75-
discoveryGroup, discoveryCtx := errgroup.WithContext(ctx)
76-
discoveryGroup.SetLimit(wd.numWorkers)
73+
var result component.Components
74+
75+
// Wrap entire worktree discovery with telemetry
76+
err := filter.TraceGitWorktreeDiscovery(ctx, len(w.WorktreePairs), func(ctx context.Context) error {
77+
discoveredComponents := component.NewThreadSafeComponents(component.Components{})
78+
79+
// Run from and to discovery concurrently for each expression
80+
discoveryGroup, discoveryCtx := errgroup.WithContext(ctx)
81+
discoveryGroup.SetLimit(wd.numWorkers)
82+
83+
for _, pair := range w.WorktreePairs {
84+
discoveryGroup.Go(func() error {
85+
// Track filter expansion with telemetry
86+
var fromFilters, toFilters filter.Filters
87+
88+
diffs := pair.Diffs
89+
90+
expandErr := filter.TraceGitFilterExpand(
91+
discoveryCtx,
92+
pair.GitExpression.FromRef,
93+
pair.GitExpression.ToRef,
94+
len(diffs.Added),
95+
len(diffs.Removed),
96+
len(diffs.Changed),
97+
func(ctx context.Context) error {
98+
fromFilters, toFilters = pair.Expand()
99+
return nil
100+
},
101+
)
102+
if expandErr != nil {
103+
return expandErr
104+
}
105+
106+
// Run from and to discovery concurrently
107+
fromToG, fromToCtx := errgroup.WithContext(discoveryCtx)
108+
109+
// We only kick off from/to discovery if there any filters expanded from the git expression.
110+
// This ensures that we don't discover anything when using a Git filter that doesn't match anything.
111+
112+
if len(fromFilters) > 0 {
113+
fromToG.Go(func() error {
114+
components, err := wd.discoverInWorktree(fromToCtx, l, opts, pair.FromWorktree, fromFilters, fromWorktreeKind)
115+
if err != nil {
116+
return err
117+
}
118+
119+
for _, c := range components {
120+
discoveredComponents.EnsureComponent(c)
121+
}
122+
123+
return nil
124+
})
125+
}
126+
127+
if len(toFilters) > 0 {
128+
fromToG.Go(func() error {
129+
components, err := wd.discoverInWorktree(fromToCtx, l, opts, pair.ToWorktree, toFilters, toWorktreeKind)
130+
if err != nil {
131+
return err
132+
}
133+
134+
for _, c := range components {
135+
discoveredComponents.EnsureComponent(c)
136+
}
137+
138+
return nil
139+
})
140+
}
141+
142+
return fromToG.Wait()
143+
})
144+
}
77145

78-
for _, pair := range w.WorktreePairs {
79146
discoveryGroup.Go(func() error {
80-
fromFilters, toFilters := pair.Expand()
81-
82-
// Run from and to discovery concurrently
83-
fromToG, fromToCtx := errgroup.WithContext(discoveryCtx)
84-
85-
// We only kick off from/to discovery if there any filters expanded from the git expression.
86-
// This ensures that we don't discover anything when using a Git filter that doesn't match anything.
87-
88-
if len(fromFilters) > 0 {
89-
fromToG.Go(func() error {
90-
components, err := wd.discoverInWorktree(fromToCtx, l, opts, pair.FromWorktree, fromFilters, fromWorktreeKind)
91-
if err != nil {
92-
return err
93-
}
94-
95-
for _, c := range components {
96-
discoveredComponents.EnsureComponent(c)
97-
}
98-
99-
return nil
100-
})
147+
components, err := wd.discoverChangesInWorktreeStacks(ctx, l, opts, w)
148+
if err != nil {
149+
return err
101150
}
102151

103-
if len(toFilters) > 0 {
104-
fromToG.Go(func() error {
105-
components, err := wd.discoverInWorktree(fromToCtx, l, opts, pair.ToWorktree, toFilters, toWorktreeKind)
106-
if err != nil {
107-
return err
108-
}
109-
110-
for _, c := range components {
111-
discoveredComponents.EnsureComponent(c)
112-
}
113-
114-
return nil
115-
})
152+
// Run directly in worktree paths - no translation needed
153+
for _, c := range components {
154+
discoveredComponents.EnsureComponent(c)
116155
}
117156

118-
return fromToG.Wait()
157+
return nil
119158
})
120-
}
121159

122-
discoveryGroup.Go(func() error {
123-
components, err := wd.discoverChangesInWorktreeStacks(ctx, l, opts, w)
124-
if err != nil {
160+
if err := discoveryGroup.Wait(); err != nil {
125161
return err
126162
}
127163

128-
// Run directly in worktree paths - no translation needed
129-
for _, c := range components {
130-
discoveredComponents.EnsureComponent(c)
131-
}
164+
result = discoveredComponents.ToComponents()
165+
166+
// Record result count metric
167+
recordWorktreeDiscoveryMetrics(ctx, len(w.WorktreePairs), len(result))
132168

133169
return nil
134170
})
135171

136-
if err := discoveryGroup.Wait(); err != nil {
137-
return nil, err
172+
return result, err
173+
}
174+
175+
// recordWorktreeDiscoveryMetrics records telemetry metrics for worktree discovery.
176+
func recordWorktreeDiscoveryMetrics(ctx context.Context, pairCount, componentCount int) {
177+
telemeter := telemetry.TelemeterFromContext(ctx)
178+
if telemeter == nil || telemeter.Meter == nil {
179+
return
138180
}
139181

140-
return discoveredComponents.ToComponents(), nil
182+
telemeter.Count(ctx, "git_worktree_discovery_worktree_pairs", int64(pairCount))
183+
telemeter.Count(ctx, "git_worktree_discovery_components", int64(componentCount))
141184
}
142185

143186
// discoverInWorktree discovers components in a single worktree.
@@ -252,6 +295,34 @@ func (wd *WorktreeDiscovery) walkChangedStack(
252295
originalDiscovery *Discovery,
253296
fromStack *component.Stack,
254297
toStack *component.Stack,
298+
) (component.Components, error) {
299+
var result component.Components
300+
301+
// Wrap stack walking with telemetry
302+
err := filter.TraceGitWorktreeStackWalk(
303+
ctx,
304+
fromStack.DiscoveryContext().Ref,
305+
toStack.DiscoveryContext().Ref,
306+
func(ctx context.Context) error {
307+
var walkErr error
308+
309+
result, walkErr = wd.walkChangedStackInternal(ctx, l, opts, originalDiscovery, fromStack, toStack)
310+
311+
return walkErr
312+
},
313+
)
314+
315+
return result, err
316+
}
317+
318+
// walkChangedStackInternal is the internal implementation of walkChangedStack.
319+
func (wd *WorktreeDiscovery) walkChangedStackInternal(
320+
ctx context.Context,
321+
l log.Logger,
322+
opts *options.TerragruntOptions,
323+
originalDiscovery *Discovery,
324+
fromStack *component.Stack,
325+
toStack *component.Stack,
255326
) (component.Components, error) {
256327
fromDiscovery := *originalDiscovery
257328

0 commit comments

Comments
 (0)