Skip to content

Commit 830202d

Browse files
author
AWS SDK for Go v2 automation user
committed
Merge customizations for service s3
1 parent 2de0027 commit 830202d

File tree

184 files changed

+17179
-4825
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

184 files changed

+17179
-4825
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"id": "51dc2b23-49b5-45ba-a702-46b6e1d54dd9",
3+
"type": "feature",
4+
"description": "Add S3Express support.",
5+
"modules": [
6+
"feature/s3/manager",
7+
"service/s3"
8+
]
9+
}

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ LINT_IGNORE_S3MANAGER_INPUT='feature/s3/manager/upload.go:.+struct field SSEKMSK
44
# Names of these are tied to endpoint rules and they're internal so ignore them
55
LINT_IGNORE_AWSRULESFN_ARN='internal/endpoints/awsrulesfn/arn.go'
66
LINT_IGNORE_AWSRULESFN_PARTITION='internal/endpoints/awsrulesfn/partition.go'
7+
LINT_IGNORE_PRIVATE_METRICS='aws/middleware/private/metrics'
78

89
UNIT_TEST_TAGS=
910
BUILD_TAGS=-tags "example,codegen,integration,ec2env,perftest"
@@ -472,7 +473,8 @@ lint:
472473
-e ${LINT_IGNORE_S3MANAGER_INPUT} \
473474
-e ${LINTIGNORESINGLEFIGHT} \
474475
-e ${LINT_IGNORE_AWSRULESFN_ARN} \
475-
-e ${LINT_IGNORE_AWSRULESFN_PARTITION}`; \
476+
-e ${LINT_IGNORE_AWSRULESFN_PARTITION} \
477+
-e ${LINT_IGNORE_PRIVATE_METRICS}`; \
476478
echo "$$dolint"; \
477479
if [ "$$dolint" != "" ]; then exit 1; fi
478480

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Package emf implements an EMF metrics publisher.
2+
//
3+
// This package is designated as private and is intended for use only by the
4+
// smithy client runtime. The exported API therein is not considered stable and
5+
// is subject to breaking changes without notice.
6+
package emf
7+
8+
import (
9+
"github.com/aws/aws-sdk-go-v2/aws/middleware/private/metrics"
10+
"github.com/aws/aws-sdk-go-v2/internal/sdk"
11+
)
12+
13+
const (
14+
emfIdentifier = "_aws"
15+
timestampKey = "Timestamp"
16+
cloudWatchMetricsKey = "CloudWatchMetrics"
17+
namespaceKey = "Namespace"
18+
dimensionsKey = "Dimensions"
19+
metricsKey = "Metrics"
20+
)
21+
22+
// Entry represents a log entry in the EMF format.
23+
type Entry struct {
24+
namespace string
25+
serializer metrics.Serializer
26+
metrics []metric
27+
dimensions [][]string
28+
fields map[string]interface{}
29+
}
30+
31+
type metric struct {
32+
Name string
33+
}
34+
35+
// NewEntry creates a new Entry with the specified namespace and serializer.
36+
func NewEntry(namespace string, serializer metrics.Serializer) Entry {
37+
return Entry{
38+
namespace: namespace,
39+
serializer: serializer,
40+
metrics: []metric{},
41+
dimensions: [][]string{{}},
42+
fields: map[string]interface{}{},
43+
}
44+
}
45+
46+
// Build constructs the EMF log entry as a JSON string.
47+
func (e *Entry) Build() (string, error) {
48+
49+
entry := map[string]interface{}{}
50+
51+
entry[emfIdentifier] = map[string]interface{}{
52+
timestampKey: sdk.NowTime().UnixNano() / 1e6,
53+
cloudWatchMetricsKey: []map[string]interface{}{
54+
{
55+
namespaceKey: e.namespace,
56+
dimensionsKey: e.dimensions,
57+
metricsKey: e.metrics,
58+
},
59+
},
60+
}
61+
62+
for k, v := range e.fields {
63+
entry[k] = v
64+
}
65+
66+
jsonEntry, err := e.serializer.Serialize(entry)
67+
if err != nil {
68+
return "", err
69+
}
70+
return jsonEntry, nil
71+
}
72+
73+
// AddDimension adds a CW Dimension to the EMF entry.
74+
func (e *Entry) AddDimension(key string, value string) {
75+
// Dimensions are a list of lists. We only support a single list.
76+
e.dimensions[0] = append(e.dimensions[0], key)
77+
e.fields[key] = value
78+
}
79+
80+
// AddMetric adds a CW Metric to the EMF entry.
81+
func (e *Entry) AddMetric(key string, value float64) {
82+
e.metrics = append(e.metrics, metric{key})
83+
e.fields[key] = value
84+
}
85+
86+
// AddProperty adds a CW Property to the EMF entry.
87+
// Properties are not published as metrics, but they are available in logs and in CW insights.
88+
func (e *Entry) AddProperty(key string, value interface{}) {
89+
e.fields[key] = value
90+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// This package is designated as private and is intended for use only by the
2+
// smithy client runtime. The exported API therein is not considered stable and
3+
// is subject to breaking changes without notice.
4+
5+
package emf
6+
7+
import (
8+
"fmt"
9+
"reflect"
10+
"testing"
11+
"time"
12+
13+
"github.com/aws/aws-sdk-go-v2/aws/middleware/private/metrics"
14+
"github.com/aws/aws-sdk-go-v2/internal/sdk"
15+
)
16+
17+
type TestSerializerWithError struct{}
18+
19+
func (TestSerializerWithError) Serialize(obj interface{}) (string, error) {
20+
return "", fmt.Errorf("serialization error")
21+
}
22+
23+
func TestCreateNewEntry(t *testing.T) {
24+
25+
sdk.NowTime = func() time.Time {
26+
return time.Unix(1234, 0)
27+
}
28+
29+
cases := map[string]struct {
30+
Namespace string
31+
ExpectedEntry Entry
32+
}{
33+
"success": {
34+
Namespace: "testNamespace",
35+
ExpectedEntry: Entry{
36+
namespace: "testNamespace",
37+
serializer: metrics.DefaultSerializer{},
38+
metrics: []metric{},
39+
dimensions: [][]string{{}},
40+
fields: map[string]interface{}{},
41+
},
42+
},
43+
}
44+
45+
for name, c := range cases {
46+
t.Run(name, func(t *testing.T) {
47+
actualEntry := NewEntry(c.Namespace, metrics.DefaultSerializer{})
48+
if !reflect.DeepEqual(actualEntry, c.ExpectedEntry) {
49+
t.Errorf("Entry contained unexpected values")
50+
}
51+
})
52+
}
53+
}
54+
55+
func TestBuild(t *testing.T) {
56+
57+
sdk.NowTime = func() time.Time {
58+
return time.Unix(1234, 0)
59+
}
60+
61+
cases := map[string]struct {
62+
Namespace string
63+
Configure func(entry *Entry)
64+
Serializer metrics.Serializer
65+
ExpectedError error
66+
ExpectedResult string
67+
}{
68+
"completeEntry": {
69+
Namespace: "testNamespace",
70+
Serializer: metrics.DefaultSerializer{},
71+
Configure: func(entry *Entry) {
72+
entry.AddMetric("testMetric1", 1)
73+
entry.AddMetric("testMetric2", 2)
74+
entry.AddDimension("testDimension1", "dim1")
75+
entry.AddDimension("testDimension2", "dim2")
76+
entry.AddProperty("testProperty1", "prop1")
77+
entry.AddProperty("testProperty2", "prop2")
78+
},
79+
ExpectedError: nil,
80+
ExpectedResult: completeEntry,
81+
},
82+
"noMetrics": {
83+
Namespace: "testNamespace",
84+
Serializer: metrics.DefaultSerializer{},
85+
Configure: func(entry *Entry) {
86+
entry.AddDimension("testDimension1", "dim1")
87+
entry.AddDimension("testDimension2", "dim2")
88+
entry.AddProperty("testProperty1", "prop1")
89+
entry.AddProperty("testProperty2", "prop2")
90+
},
91+
ExpectedError: nil,
92+
ExpectedResult: noMetrics,
93+
},
94+
"noDimensions": {
95+
Namespace: "testNamespace",
96+
Serializer: metrics.DefaultSerializer{},
97+
Configure: func(entry *Entry) {
98+
entry.AddMetric("testMetric1", 1)
99+
entry.AddMetric("testMetric2", 2)
100+
entry.AddProperty("testProperty1", "prop1")
101+
entry.AddProperty("testProperty2", "prop2")
102+
},
103+
ExpectedError: nil,
104+
ExpectedResult: noDimensions,
105+
},
106+
"noProperties": {
107+
Namespace: "testNamespace",
108+
Serializer: metrics.DefaultSerializer{},
109+
Configure: func(entry *Entry) {
110+
entry.AddMetric("testMetric1", 1)
111+
entry.AddMetric("testMetric2", 2)
112+
entry.AddDimension("testDimension1", "dim1")
113+
entry.AddDimension("testDimension2", "dim2")
114+
},
115+
ExpectedError: nil,
116+
ExpectedResult: noProperties,
117+
},
118+
"serializationError": {
119+
Namespace: "testNamespace",
120+
Serializer: TestSerializerWithError{},
121+
Configure: func(entry *Entry) {
122+
},
123+
ExpectedError: fmt.Errorf("serialization error"),
124+
ExpectedResult: "",
125+
},
126+
}
127+
128+
for name, c := range cases {
129+
t.Run(name, func(t *testing.T) {
130+
entry := NewEntry(c.Namespace, c.Serializer)
131+
132+
c.Configure(&entry)
133+
134+
result, err := entry.Build()
135+
136+
if !reflect.DeepEqual(err, c.ExpectedError) {
137+
t.Errorf("Unexpected error, should be '%s' but was '%s'", c.ExpectedError, err)
138+
}
139+
140+
if !reflect.DeepEqual(result, c.ExpectedResult) {
141+
t.Errorf("Unexpected result, should be '%s' but was '%s'", c.ExpectedResult, result)
142+
}
143+
})
144+
}
145+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// This package is designated as private and is intended for use only by the
2+
// smithy client runtime. The exported API therein is not considered stable and
3+
// is subject to breaking changes without notice.
4+
5+
package emf
6+
7+
import "strings"
8+
9+
func stripString(str string) string {
10+
str = strings.Replace(str, " ", "", -1)
11+
str = strings.Replace(str, "\t", "", -1)
12+
str = strings.Replace(str, "\n", "", -1)
13+
return str
14+
}
15+
16+
var completeEntry = stripString(`
17+
{
18+
"_aws": {
19+
"CloudWatchMetrics": [{
20+
"Dimensions": [
21+
["testDimension1", "testDimension2"]
22+
],
23+
"Metrics": [{
24+
"Name": "testMetric1"
25+
}, {
26+
"Name": "testMetric2"
27+
}],
28+
"Namespace": "testNamespace"
29+
}],
30+
"Timestamp": 1234000
31+
},
32+
"testDimension1": "dim1",
33+
"testDimension2": "dim2",
34+
"testMetric1": 1,
35+
"testMetric2": 2,
36+
"testProperty1": "prop1",
37+
"testProperty2": "prop2"
38+
}
39+
`)
40+
41+
var noMetrics = stripString(`
42+
{
43+
"_aws": {
44+
"CloudWatchMetrics": [{
45+
"Dimensions": [
46+
["testDimension1", "testDimension2"]
47+
],
48+
"Metrics": [],
49+
"Namespace": "testNamespace"
50+
}],
51+
"Timestamp": 1234000
52+
},
53+
"testDimension1": "dim1",
54+
"testDimension2": "dim2",
55+
"testProperty1": "prop1",
56+
"testProperty2": "prop2"
57+
}
58+
`)
59+
60+
var noProperties = stripString(`
61+
{
62+
"_aws": {
63+
"CloudWatchMetrics": [{
64+
"Dimensions": [
65+
["testDimension1", "testDimension2"]
66+
],
67+
"Metrics": [{
68+
"Name": "testMetric1"
69+
}, {
70+
"Name": "testMetric2"
71+
}],
72+
"Namespace": "testNamespace"
73+
}],
74+
"Timestamp": 1234000
75+
},
76+
"testDimension1": "dim1",
77+
"testDimension2": "dim2",
78+
"testMetric1": 1,
79+
"testMetric2": 2
80+
}
81+
`)
82+
83+
var noDimensions = stripString(`
84+
{
85+
"_aws": {
86+
"CloudWatchMetrics": [{
87+
"Dimensions": [
88+
[]
89+
],
90+
"Metrics": [{
91+
"Name": "testMetric1"
92+
}, {
93+
"Name": "testMetric2"
94+
}],
95+
"Namespace": "testNamespace"
96+
}],
97+
"Timestamp": 1234000
98+
},
99+
"testMetric1": 1,
100+
"testMetric2": 2,
101+
"testProperty1": "prop1",
102+
"testProperty2": "prop2"
103+
}
104+
`)

0 commit comments

Comments
 (0)