Skip to content

Commit e6f1b51

Browse files
authored
Add guard to hot logging location in associator (#1623)
Signed-off-by: Pablo Balbi <pablo.l.balbi@gmail.com>
1 parent 15f1631 commit e6f1b51

File tree

2 files changed

+64
-8
lines changed

2 files changed

+64
-8
lines changed

pkg/job/maxdimassociator/associator.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ package maxdimassociator
1414

1515
import (
1616
"cmp"
17+
"context"
1718
"fmt"
1819
"log/slog"
1920
"slices"
@@ -36,7 +37,8 @@ type Associator struct {
3637
// mappings is a slice of dimensions-based mappings, one for each regex of a given namespace
3738
mappings []*dimensionsRegexpMapping
3839

39-
logger *slog.Logger
40+
logger *slog.Logger
41+
debugEnabled bool
4042
}
4143

4244
type dimensionsRegexpMapping struct {
@@ -70,8 +72,9 @@ func (rm dimensionsRegexpMapping) toString() string {
7072
// NewAssociator builds all mappings for the given dimensions regexps and list of resources.
7173
func NewAssociator(logger *slog.Logger, dimensionsRegexps []model.DimensionsRegexp, resources []*model.TaggedResource) Associator {
7274
assoc := Associator{
73-
mappings: []*dimensionsRegexpMapping{},
74-
logger: logger,
75+
mappings: []*dimensionsRegexpMapping{},
76+
logger: logger,
77+
debugEnabled: logger.Handler().Enabled(context.Background(), slog.LevelDebug), // caching if debug is enabled
7578
}
7679

7780
// Keep track of resources that have already been mapped.
@@ -114,7 +117,9 @@ func NewAssociator(logger *slog.Logger, dimensionsRegexps []model.DimensionsRege
114117
// example when we define multiple regexps (to capture sibling
115118
// or sub-resources) and one of them doesn't match any resource.
116119
// This behaviour is ok, we just want to debug log to keep track of it.
117-
logger.Debug("unable to define a regex mapping", "regex", dr.Regexp.String())
120+
if assoc.debugEnabled {
121+
logger.Debug("unable to define a regex mapping", "regex", dr.Regexp.String())
122+
}
118123
}
119124

120125
// sort all mappings by decreasing number of dimensions names
@@ -124,8 +129,10 @@ func NewAssociator(logger *slog.Logger, dimensionsRegexps []model.DimensionsRege
124129
return -1 * cmp.Compare(len(a.dimensions), len(b.dimensions))
125130
})
126131

127-
for idx, regexpMapping := range assoc.mappings {
128-
logger.Debug("associator mapping", "mapping_idx", idx, "mapping", regexpMapping.toString())
132+
if assoc.debugEnabled {
133+
for idx, regexpMapping := range assoc.mappings {
134+
logger.Debug("associator mapping", "mapping_idx", idx, "mapping", regexpMapping.toString())
135+
}
129136
}
130137

131138
return assoc
@@ -150,7 +157,9 @@ func (assoc Associator) AssociateMetricToResource(cwMetric *model.Metric) (*mode
150157
dimensions = append(dimensions, dimension.Name)
151158
}
152159

153-
logger.Debug("associate loop start", "dimensions", strings.Join(dimensions, ","))
160+
if assoc.debugEnabled {
161+
logger.Debug("associate loop start", "dimensions", strings.Join(dimensions, ","))
162+
}
154163

155164
// Attempt to find the regex mapping which contains the most
156165
// (but not necessarily all) the metric's dimensions names.
@@ -159,7 +168,9 @@ func (assoc Associator) AssociateMetricToResource(cwMetric *model.Metric) (*mode
159168
mappingFound := false
160169
for idx, regexpMapping := range assoc.mappings {
161170
if containsAll(dimensions, regexpMapping.dimensions) {
162-
logger.Debug("found mapping", "mapping_idx", idx, "mapping", regexpMapping.toString())
171+
if assoc.debugEnabled {
172+
logger.Debug("found mapping", "mapping_idx", idx, "mapping", regexpMapping.toString())
173+
}
163174

164175
// A regex mapping has been found. The metric has all (and possibly more)
165176
// the dimensions computed for the mapping. Now compute a signature
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package maxdimassociator
2+
3+
import (
4+
"bytes"
5+
"log/slog"
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
10+
"github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/config"
11+
"github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/model"
12+
)
13+
14+
func TestAssociatorLogging(t *testing.T) {
15+
type testcase struct {
16+
level slog.Level
17+
}
18+
for name, tc := range map[string]testcase{
19+
"debug enabled": {level: slog.LevelDebug},
20+
"debug disabled": {level: slog.LevelInfo},
21+
} {
22+
t.Run(name, func(t *testing.T) {
23+
buf := &bytes.Buffer{}
24+
logger := slog.New(slog.NewTextHandler(buf, &slog.HandlerOptions{
25+
Level: tc.level,
26+
}))
27+
associator := NewAssociator(logger, config.SupportedServices.GetService("AWS/Logs").ToModelDimensionsRegexp(), logGroupResources)
28+
res, skip := associator.AssociateMetricToResource(&model.Metric{
29+
MetricName: "DeliveryThrottling",
30+
Namespace: "AWS/Logs",
31+
Dimensions: []model.Dimension{
32+
{Name: "LogGroupName", Value: "/aws/lambda/log-group-1"},
33+
},
34+
})
35+
require.NotNil(t, res)
36+
require.False(t, skip)
37+
38+
assertion := require.NotContains
39+
if tc.level == slog.LevelDebug {
40+
assertion = require.Contains
41+
}
42+
assertion(t, buf.String(), "found mapping")
43+
})
44+
}
45+
}

0 commit comments

Comments
 (0)