Skip to content

Commit

Permalink
Use HTTP gzip compression for the Agent telemetry payloads
Browse files Browse the repository at this point in the history
  • Loading branch information
iglendd committed Dec 21, 2024
1 parent f5d99e9 commit f615a0a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 7 deletions.
35 changes: 28 additions & 7 deletions comp/core/agenttelemetry/impl/sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ type senderImpl struct {
cfgComp config.Reader
logComp log.Component

client client
compress bool
compressionLevel int
client client

endpoints *logconfig.Endpoints

Expand Down Expand Up @@ -207,9 +209,12 @@ func newSenderImpl(
cfgComp: cfgComp,
logComp: logComp,

client: client,
endpoints: endpoints,
agentVersion: agentVersion.GetNumberAndPre(),
compress: cfgComp.GetBool("agent_telemetry.use_compression"),
compressionLevel: cfgComp.GetInt("agent_telemetry.compression_level"),
client: client,
endpoints: endpoints,
agentVersion: agentVersion.GetNumberAndPre(),

// pre-fill parts of payload which are not changing during run-time
payloadTemplate: Payload{
APIVersion: "v2",
Expand Down Expand Up @@ -321,11 +326,23 @@ func (s *senderImpl) flushSession(ss *senderSession) error {
return fmt.Errorf("failed to marshal agent telemetry payload: %w", err)
}

reqBody, err := scrubber.ScrubJSON(payloadJSON)
reqBodyRaw, err := scrubber.ScrubJSON(payloadJSON)
if err != nil {
return fmt.Errorf("failed to scrubl agent telemetry payload: %w", err)
}

// Try to compress the payload if needed
reqBody := reqBodyRaw
gzipCompressed := s.compress
if s.compress {
reqBody, err = gzipCompress(reqBodyRaw, s.compressionLevel)
if err != nil {
gzipCompressed = false
reqBody = reqBodyRaw
s.logComp.Errorf("Failed to compress agent telemetry payload: %v", err)
}
}

// Send the payload to all endpoints
var errs error
reqType := payloads.RequestType
Expand All @@ -337,7 +354,7 @@ func (s *senderImpl) flushSession(ss *senderSession) error {
errs = errors.Join(errs, err)
continue
}
s.addHeaders(req, reqType, ep.GetAPIKey(), bodyLen)
s.addHeaders(req, reqType, ep.GetAPIKey(), bodyLen, gzipCompressed)
resp, err := s.client.Do(req.WithContext(ss.cancelCtx))
if err != nil {
errs = errors.Join(errs, err)
Expand Down Expand Up @@ -387,7 +404,7 @@ func (s *senderImpl) sendAgentMetricPayloads(ss *senderSession, metrics []*agent
}
}

func (s *senderImpl) addHeaders(req *http.Request, requesttype, apikey, bodylen string) {
func (s *senderImpl) addHeaders(req *http.Request, requesttype, apikey, bodylen string, gzipCompressed bool) {
req.Header.Add("DD-Api-Key", apikey)
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Content-Length", bodylen)
Expand All @@ -397,4 +414,8 @@ func (s *senderImpl) addHeaders(req *http.Request, requesttype, apikey, bodylen
req.Header.Add("DD-Telemetry-Product-Version", s.agentVersion)
// Not clear how to acquire that. Appears that EVP adds it automatically
req.Header.Add("datadog-container-id", "")

if gzipCompressed {
req.Header.Set("Content-Encoding", "gzip")
}
}
24 changes: 24 additions & 0 deletions comp/core/agenttelemetry/impl/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package agenttelemetryimpl

import (
"bytes"
"compress/gzip"
"fmt"
"sort"

Expand Down Expand Up @@ -123,3 +125,25 @@ func cloneLabelsSorted(labels []*dto.LabelPair) []*dto.LabelPair {
func makeLabelPairKey(l *dto.LabelPair) string {
return fmt.Sprintf("%s:%s:", l.GetName(), l.GetValue())
}

// Compresses payload via gzip
func gzipCompress(payload []byte, compressionLevel int) ([]byte, error) {
var payloadCompressed bytes.Buffer
gzipWriter, err := gzip.NewWriterLevel(&payloadCompressed, compressionLevel)
if err != nil {
return nil, err
}
_, err = gzipWriter.Write(payload)
if err != nil {
return nil, err
}
err = gzipWriter.Flush()
if err != nil {
return nil, err
}
err = gzipWriter.Close()
if err != nil {
return nil, err
}
return payloadCompressed.Bytes(), nil
}
11 changes: 11 additions & 0 deletions releasenotes/notes/agent-tel-gzip-bba8a51c1aa3ba2f.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Each section from every release note are combined when the
# CHANGELOG.rst is rendered. So the text needs to be worded so that
# it does not depend on any information only available in another
# section. This may mean repeating some details, but each section
# must be readable independently of the other.
#
# Each section note must be formatted as reStructuredText.
---
enhancements:
- |
Use HTTP gzip compression for the Agent telemetry payloads.

0 comments on commit f615a0a

Please sign in to comment.