Skip to content

Commit 893b508

Browse files
sagemaker: additional InferenceComponent support (#1686)
Signed-off-by: Tristan Burgess <[email protected]>
1 parent 92e1910 commit 893b508

File tree

4 files changed

+134
-3
lines changed

4 files changed

+134
-3
lines changed

pkg/config/services.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,9 +950,11 @@ var SupportedServices = serviceConfigs{
950950
Alias: "sagemaker",
951951
ResourceFilters: []*string{
952952
aws.String("sagemaker:endpoint"),
953+
aws.String("sagemaker:inference-component"),
953954
},
954955
DimensionRegexps: []*regexp.Regexp{
955956
regexp.MustCompile(":endpoint/(?P<EndpointName>[^/]+)$"),
957+
regexp.MustCompile(":inference-component/(?P<InferenceComponentName>[^/]+)$"),
956958
},
957959
},
958960
{
@@ -965,6 +967,16 @@ var SupportedServices = serviceConfigs{
965967
regexp.MustCompile(":endpoint/(?P<EndpointName>[^/]+)$"),
966968
},
967969
},
970+
{
971+
Namespace: "/aws/sagemaker/InferenceComponents",
972+
Alias: "sagemaker-inference-components",
973+
ResourceFilters: []*string{
974+
aws.String("sagemaker:inference-component"),
975+
},
976+
DimensionRegexps: []*regexp.Regexp{
977+
regexp.MustCompile(":inference-component/(?P<InferenceComponentName>[^/]+)$"),
978+
},
979+
},
968980
{
969981
Namespace: "/aws/sagemaker/TrainingJobs",
970982
Alias: "sagemaker-training",

pkg/job/maxdimassociator/associator.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,10 @@ func fixDimension(namespace string, dim model.Dimension) (model.Dimension, bool)
255255
}
256256
}
257257

258-
// AWS Sagemaker endpoint name may have upper case characters
258+
// AWS Sagemaker endpoint name and inference component name may have upper case characters
259259
// Resource ARN is only in lower case, hence transforming
260-
// endpoint name value to be able to match the resource ARN
261-
if namespace == "AWS/SageMaker" && dim.Name == "EndpointName" {
260+
// name value to be able to match the resource ARN
261+
if namespace == "AWS/SageMaker" && (dim.Name == "EndpointName" || dim.Name == "InferenceComponentName") {
262262
dim.Value = strings.ToLower(dim.Value)
263263
return dim, true
264264
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2024 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
package maxdimassociator
14+
15+
import (
16+
"testing"
17+
18+
"github.com/prometheus/common/promslog"
19+
"github.com/stretchr/testify/require"
20+
21+
"github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/config"
22+
"github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/model"
23+
)
24+
25+
var sagemakerInfComponentJobOne = &model.TaggedResource{
26+
ARN: "arn:aws:sagemaker:us-west-2:123456789012:inference-component/example-inference-component-one",
27+
Namespace: "/aws/sagemaker/InferenceComponents",
28+
}
29+
30+
var sagemakerInfComponentJobResources = []*model.TaggedResource{
31+
sagemakerInfComponentJobOne,
32+
}
33+
34+
func TestAssociatorSagemakerInfComponentJob(t *testing.T) {
35+
type args struct {
36+
dimensionRegexps []model.DimensionsRegexp
37+
resources []*model.TaggedResource
38+
metric *model.Metric
39+
}
40+
41+
type testCase struct {
42+
name string
43+
args args
44+
expectedSkip bool
45+
expectedResource *model.TaggedResource
46+
}
47+
48+
testcases := []testCase{
49+
{
50+
name: "1 dimension should not match but not skip",
51+
args: args{
52+
dimensionRegexps: config.SupportedServices.GetService("/aws/sagemaker/InferenceComponents").ToModelDimensionsRegexp(),
53+
resources: sagemakerInfComponentJobResources,
54+
metric: &model.Metric{
55+
MetricName: "CPUUtilizationNormalized",
56+
Namespace: "/aws/sagemaker/InferenceComponents",
57+
Dimensions: []model.Dimension{
58+
{Name: "InferenceComponentName", Value: "example-inference-component-one"},
59+
},
60+
},
61+
},
62+
expectedSkip: false,
63+
expectedResource: sagemakerInfComponentJobOne,
64+
},
65+
}
66+
67+
for _, tc := range testcases {
68+
t.Run(tc.name, func(t *testing.T) {
69+
associator := NewAssociator(promslog.NewNopLogger(), tc.args.dimensionRegexps, tc.args.resources)
70+
res, skip := associator.AssociateMetricToResource(tc.args.metric)
71+
require.Equal(t, tc.expectedSkip, skip)
72+
require.Equal(t, tc.expectedResource, res)
73+
})
74+
}
75+
}

pkg/job/maxdimassociator/associator_sagemaker_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,22 @@ var sagemakerEndpointInvocationUpper = &model.TaggedResource{
3737
Namespace: "AWS/SageMaker",
3838
}
3939

40+
var sagemakerInferenceComponentInvocationOne = &model.TaggedResource{
41+
ARN: "arn:aws:sagemaker:us-west-2:123456789012:inference-component/example-inference-component-one",
42+
Namespace: "AWS/SageMaker",
43+
}
44+
45+
var sagemakerInferenceComponentInvocationUpper = &model.TaggedResource{
46+
ARN: "arn:aws:sagemaker:us-west-2:123456789012:inference-component/example-inference-component-upper",
47+
Namespace: "AWS/SageMaker",
48+
}
49+
4050
var sagemakerInvocationResources = []*model.TaggedResource{
4151
sagemakerEndpointInvocationOne,
4252
sagemakerEndpointInvocationTwo,
4353
sagemakerEndpointInvocationUpper,
54+
sagemakerInferenceComponentInvocationOne,
55+
sagemakerInferenceComponentInvocationUpper,
4456
}
4557

4658
func TestAssociatorSagemaker(t *testing.T) {
@@ -127,6 +139,38 @@ func TestAssociatorSagemaker(t *testing.T) {
127139
expectedSkip: false,
128140
expectedResource: sagemakerEndpointInvocationUpper,
129141
},
142+
{
143+
name: "inference component match",
144+
args: args{
145+
dimensionRegexps: config.SupportedServices.GetService("AWS/SageMaker").ToModelDimensionsRegexp(),
146+
resources: sagemakerInvocationResources,
147+
metric: &model.Metric{
148+
MetricName: "ModelLatency",
149+
Namespace: "AWS/SageMaker",
150+
Dimensions: []model.Dimension{
151+
{Name: "InferenceComponentName", Value: "example-inference-component-one"},
152+
},
153+
},
154+
},
155+
expectedSkip: false,
156+
expectedResource: sagemakerInferenceComponentInvocationOne,
157+
},
158+
{
159+
name: "inference component match in Upper case",
160+
args: args{
161+
dimensionRegexps: config.SupportedServices.GetService("AWS/SageMaker").ToModelDimensionsRegexp(),
162+
resources: sagemakerInvocationResources,
163+
metric: &model.Metric{
164+
MetricName: "ModelLatency",
165+
Namespace: "AWS/SageMaker",
166+
Dimensions: []model.Dimension{
167+
{Name: "InferenceComponentName", Value: "Example-Inference-Component-Upper"},
168+
},
169+
},
170+
},
171+
expectedSkip: false,
172+
expectedResource: sagemakerInferenceComponentInvocationUpper,
173+
},
130174
}
131175

132176
for _, tc := range testcases {

0 commit comments

Comments
 (0)