Skip to content

Commit a8f95d9

Browse files
[confighttp] Add support for configuring compression levels (#11805)
#### Description Add the option of configuring compression levels. This is not intended to be a breaking change for the user. #### Link to tracking issue Issue - #10467 #### Testing Unit tests were added/changed
1 parent 87b146a commit a8f95d9

File tree

10 files changed

+334
-57
lines changed

10 files changed

+334
-57
lines changed
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: 'enhancement'
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
7+
component: confighttp
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Added support for configuring compression levels.
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [10467]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: A new configuration option called CompressionParams has been added to confighttp. |
19+
This allows users to configure the compression levels for the confighttp client.
20+
21+
# Optional: The change log or logs in which this entry should be included.
22+
# e.g. '[user]' or '[user, api]'
23+
# Include 'user' if the change is relevant to end users.
24+
# Include 'api' if there is a change to a library API.
25+
# Default: '[user]'
26+
change_logs: [user, api]

config/configcompression/compressiontype.go

+39-9
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,30 @@
33

44
package configcompression // import "go.opentelemetry.io/collector/config/configcompression"
55

6-
import "fmt"
6+
import (
7+
"compress/zlib"
8+
"fmt"
9+
)
710

811
// Type represents a compression method
912
type Type string
1013

14+
type Level int
15+
16+
type CompressionParams struct {
17+
Level Level `mapstructure:"level"`
18+
}
19+
1120
const (
12-
TypeGzip Type = "gzip"
13-
TypeZlib Type = "zlib"
14-
TypeDeflate Type = "deflate"
15-
TypeSnappy Type = "snappy"
16-
TypeZstd Type = "zstd"
17-
TypeLz4 Type = "lz4"
18-
typeNone Type = "none"
19-
typeEmpty Type = ""
21+
TypeGzip Type = "gzip"
22+
TypeZlib Type = "zlib"
23+
TypeDeflate Type = "deflate"
24+
TypeSnappy Type = "snappy"
25+
TypeZstd Type = "zstd"
26+
TypeLz4 Type = "lz4"
27+
typeNone Type = "none"
28+
typeEmpty Type = ""
29+
DefaultCompressionLevel = zlib.DefaultCompression
2030
)
2131

2232
// IsCompressed returns false if CompressionType is nil, none, or empty.
@@ -40,3 +50,23 @@ func (ct *Type) UnmarshalText(in []byte) error {
4050
}
4151
return fmt.Errorf("unsupported compression type %q", typ)
4252
}
53+
54+
func (ct *Type) ValidateParams(p CompressionParams) error {
55+
switch *ct {
56+
case TypeGzip, TypeZlib, TypeDeflate:
57+
if p.Level == zlib.DefaultCompression ||
58+
p.Level == zlib.HuffmanOnly ||
59+
p.Level == zlib.NoCompression ||
60+
(p.Level >= zlib.BestSpeed && p.Level <= zlib.BestCompression) {
61+
return nil
62+
}
63+
case TypeZstd:
64+
// Supports arbitrary levels: zstd will map any given
65+
// level to the nearest internally supported level.
66+
return nil
67+
}
68+
if p.Level != 0 {
69+
return fmt.Errorf("unsupported parameters %+v for compression type %q", p, *ct)
70+
}
71+
return nil
72+
}

config/configcompression/compressiontype_test.go

+91
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package configcompression
55

66
import (
7+
"compress/zlib"
78
"testing"
89

910
"github.com/stretchr/testify/assert"
@@ -84,3 +85,93 @@ func TestUnmarshalText(t *testing.T) {
8485
})
8586
}
8687
}
88+
89+
func TestValidateParams(t *testing.T) {
90+
tests := []struct {
91+
name string
92+
compressionName []byte
93+
compressionLevel Level
94+
shouldError bool
95+
}{
96+
{
97+
name: "ValidGzip",
98+
compressionName: []byte("gzip"),
99+
compressionLevel: zlib.DefaultCompression,
100+
shouldError: false,
101+
},
102+
{
103+
name: "InvalidGzip",
104+
compressionName: []byte("gzip"),
105+
compressionLevel: 99,
106+
shouldError: true,
107+
},
108+
{
109+
name: "ValidZlib",
110+
compressionName: []byte("zlib"),
111+
compressionLevel: zlib.DefaultCompression,
112+
shouldError: false,
113+
},
114+
{
115+
name: "ValidDeflate",
116+
compressionName: []byte("deflate"),
117+
compressionLevel: zlib.DefaultCompression,
118+
shouldError: false,
119+
},
120+
{
121+
name: "ValidSnappy",
122+
compressionName: []byte("snappy"),
123+
shouldError: false,
124+
},
125+
{
126+
name: "InvalidSnappy",
127+
compressionName: []byte("snappy"),
128+
compressionLevel: 1,
129+
shouldError: true,
130+
},
131+
{
132+
name: "ValidZstd",
133+
compressionName: []byte("zstd"),
134+
compressionLevel: zlib.DefaultCompression,
135+
shouldError: false,
136+
},
137+
{
138+
name: "ValidEmpty",
139+
compressionName: []byte(""),
140+
shouldError: false,
141+
},
142+
{
143+
name: "ValidNone",
144+
compressionName: []byte("none"),
145+
shouldError: false,
146+
},
147+
{
148+
name: "ValidLz4",
149+
compressionName: []byte("lz4"),
150+
shouldError: false,
151+
},
152+
{
153+
name: "InvalidLz4",
154+
compressionName: []byte("lz4"),
155+
compressionLevel: 1,
156+
shouldError: true,
157+
},
158+
{
159+
name: "Invalid",
160+
compressionName: []byte("ggip"),
161+
compressionLevel: zlib.DefaultCompression,
162+
shouldError: true,
163+
},
164+
}
165+
for _, tt := range tests {
166+
t.Run(tt.name, func(t *testing.T) {
167+
compressionParams := CompressionParams{Level: tt.compressionLevel}
168+
temp := Type(tt.compressionName)
169+
err := temp.ValidateParams(compressionParams)
170+
if tt.shouldError {
171+
assert.Error(t, err)
172+
return
173+
}
174+
require.NoError(t, err)
175+
})
176+
}
177+
}

config/confighttp/README.md

+25-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,28 @@ README](../configtls/README.md).
2626
- `compression`: Compression type to use among `gzip`, `zstd`, `snappy`, `zlib`, `deflate`, and `lz4`.
2727
- look at the documentation for the server-side of the communication.
2828
- `none` will be treated as uncompressed, and any other inputs will cause an error.
29+
- `compression_params` : Configure advanced compression options
30+
- `level`: Configure compression level for `compression` type
31+
- The following are valid combinations of `compression` and `level`
32+
- `gzip`
33+
- BestSpeed: `1`
34+
- BestCompression: `9`
35+
- DefaultCompression: `-1`
36+
- `zlib`
37+
- BestSpeed: `1`
38+
- BestCompression: `9`
39+
- DefaultCompression: `-1`
40+
- `deflate`
41+
- BestSpeed: `1`
42+
- BestCompression: `9`
43+
- DefaultCompression: `-1`
44+
- `zstd`
45+
- SpeedFastest: `1`
46+
- SpeedDefault: `3`
47+
- SpeedBetterCompression: `6`
48+
- SpeedBestCompression: `11`
49+
- `snappy`
50+
No compression levels supported yet
2951
- [`max_idle_conns`](https://golang.org/pkg/net/http/#Transport)
3052
- [`max_idle_conns_per_host`](https://golang.org/pkg/net/http/#Transport)
3153
- [`max_conns_per_host`](https://golang.org/pkg/net/http/#Transport)
@@ -52,7 +74,9 @@ exporter:
5274
headers:
5375
test1: "value1"
5476
"test 2": "value 2"
55-
compression: zstd
77+
compression: gzip
78+
compression_params:
79+
level: 1
5680
cookies:
5781
enabled: true
5882
```

config/confighttp/compression.go

+16-8
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ import (
2121
)
2222

2323
type compressRoundTripper struct {
24-
rt http.RoundTripper
25-
compressionType configcompression.Type
26-
compressor *compressor
24+
rt http.RoundTripper
25+
compressionType configcompression.Type
26+
compressionParams configcompression.CompressionParams
27+
compressor *compressor
2728
}
2829

2930
var availableDecoders = map[string]func(body io.ReadCloser) (io.ReadCloser, error){
@@ -76,15 +77,22 @@ var availableDecoders = map[string]func(body io.ReadCloser) (io.ReadCloser, erro
7677
},
7778
}
7879

79-
func newCompressRoundTripper(rt http.RoundTripper, compressionType configcompression.Type) (*compressRoundTripper, error) {
80-
encoder, err := newCompressor(compressionType)
80+
func newCompressionParams(level configcompression.Level) configcompression.CompressionParams {
81+
return configcompression.CompressionParams{
82+
Level: level,
83+
}
84+
}
85+
86+
func newCompressRoundTripper(rt http.RoundTripper, compressionType configcompression.Type, compressionParams configcompression.CompressionParams) (*compressRoundTripper, error) {
87+
encoder, err := newCompressor(compressionType, compressionParams)
8188
if err != nil {
8289
return nil, err
8390
}
8491
return &compressRoundTripper{
85-
rt: rt,
86-
compressionType: compressionType,
87-
compressor: encoder,
92+
rt: rt,
93+
compressionType: compressionType,
94+
compressionParams: compressionParams,
95+
compressor: encoder,
8896
}, nil
8997
}
9098

0 commit comments

Comments
 (0)