Skip to content

Commit

Permalink
feat: include Go version, GOOS, & GOARCH in user-agent (#207)
Browse files Browse the repository at this point in the history
## Which problem is this PR solving?

It helps Honeycomb support customers to know what operating systems
and CPU architectures instrumentation is running upon. OpenTelemetry
has added this to the Collector and the spec for Exporters and we have
[prior art for this in
libhoney-rb](honeycombio/libhoney-rb#105).

## Short description of the changes

- Updated the user-agent to include Go version, GOOS, and GOARCH

- Makefile addition with a test target to bring the CI test execution
  mechanism up-to-date with what we're doing in other Go codebases
  to make it easy to run the tests, make it each to read the test output,
  and give CI the data it needs to helps us see test failures more clearly.

- Moved our libhoney version declaration out of the parent libhoney
  package and into version so that other packages (transmission) can
  reference it. That allows the usual user-agent to be pre-computed.

- User-agent assertions updated to use testify because the failure
  output for diffs is so much friendlier.
  • Loading branch information
robbkidd authored Oct 28, 2022
1 parent ba1eb97 commit 2f4d796
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 19 deletions.
5 changes: 3 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ jobs:
- buildevents/with_job_span:
steps:
- checkout
- run: go get -v -t -d ./...
- run: go test -race -v ./...
- run: make test
- store_test_results:
path: ./unit-tests.xml
- buildevents/add_context:
field_name: go_version
field_value: << parameters.goversion >>
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Example artifacts
examples/wiki-manual-tracing/*.txt

# Test report
unit-tests.xml

# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
Expand Down
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.PHONY: test
#: run the tests!
test:
ifeq (, $(shell which gotestsum))
@echo " ***"
@echo "Running with standard go test because gotestsum was not found on PATH. Consider installing gotestsum for friendlier test output!"
@echo " ***"
go test -race -v ./...
else
gotestsum --junitfile unit-tests.xml --format testname -- -race ./...
endif
2 changes: 1 addition & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Creating a new release

1. Update the version string in `libhoney.go`.
1. Update the Version string in `version/version.go`.
2. Add new release notes to the Changelog.
3. Open a PR with above changes.
4. Once the above PR is merged, tag `main` with the new version, e.g. `v0.1.1`. Push the tags. This will kick off a CI workflow, which will publish a draft GitHub release.
Expand Down
2 changes: 0 additions & 2 deletions libhoney.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,13 @@ import (

func init() {
rand.Seed(time.Now().UnixNano())
transmission.Version = version
}

const (
defaultSampleRate = 1
defaultAPIHost = "https://api.honeycomb.io/"
defaultClassicDataset = "libhoney-go dataset"
defaultDataset = "unknown_dataset"
version = "1.17.1"

// DefaultMaxBatchSize how many events to collect in a batch
DefaultMaxBatchSize = 50
Expand Down
29 changes: 20 additions & 9 deletions transmission/transmission.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ import (
"net/http"
"net/url"
"path"
"runtime"
"strings"
"sync"
"time"

"github.com/facebookgo/muster"
"github.com/honeycombio/libhoney-go/version"
"github.com/klauspost/compress/zstd"
"github.com/vmihailenco/msgpack/v5"
)
Expand All @@ -39,8 +41,23 @@ const (
defaultSendTimeout = time.Second * 60
)

// Version is the build version, set by libhoney
var Version string
var (
// Libhoney's portion of the User-Agent header, e.g. "libhoney/1.2.3"
baseUserAgent = fmt.Sprintf("libhoney-go/%s", version.Version)
// Information about the runtime environment for inclusion in User-Agent
runtimeInfo = fmt.Sprintf("%s (%s/%s)", strings.Replace(runtime.Version(), "go", "go/", 1), runtime.GOOS, runtime.GOARCH)
// The default User-Agent when no additions have been given
defaultUserAgent = fmt.Sprintf("%s %s", baseUserAgent, runtimeInfo)
)

// Return a user-agent value including any additions made in the configuration
func fmtUserAgent(addition string) string {
if addition != "" {
return fmt.Sprintf("%s %s %s", baseUserAgent, strings.TrimSpace(addition), runtimeInfo)
} else {
return defaultUserAgent
}
}

type Honeycomb struct {
// How many events to collect into a batch before sending. A
Expand Down Expand Up @@ -407,12 +424,6 @@ func (b *batchAgg) fireBatch(events []*Event) {
// build the HTTP request
url.Path = path.Join(url.Path, "/1/batch", dataset)

// sigh. dislike
userAgent := fmt.Sprintf("libhoney-go/%s", Version)
if b.userAgentAddition != "" {
userAgent = fmt.Sprintf("%s %s", userAgent, strings.TrimSpace(b.userAgentAddition))
}

// One retry allowed for connection timeouts.
var resp *http.Response
for try := 0; try < 2; try++ {
Expand All @@ -435,7 +446,7 @@ func (b *batchAgg) fireBatch(events []*Event) {
req.Header.Set("Content-Encoding", "zstd")
}

req.Header.Set("User-Agent", userAgent)
req.Header.Set("User-Agent", fmtUserAgent(b.userAgentAddition))
req.Header.Add("X-Honeycomb-Team", writeKey)
// send off batch!
resp, err = b.httpClient.Do(req)
Expand Down
11 changes: 6 additions & 5 deletions transmission/transmission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
// convincing testing.
"github.com/DataDog/zstd"
"github.com/facebookgo/muster"
"github.com/honeycombio/libhoney-go/version"
"github.com/stretchr/testify/assert"
"github.com/vmihailenco/msgpack/v5"
)

Expand Down Expand Up @@ -201,7 +203,6 @@ func TestTxSendSingle(t *testing.T) {
metrics: &nullMetrics{},
enableMsgpackEncoding: doMsgpack,
}
Version = "1.2.3"
reset := func(b *batchAgg, frt *FakeRoundTripper, statusCode int, body string, err error) {
if body == "" {
frt.resp = nil
Expand Down Expand Up @@ -229,8 +230,8 @@ func TestTxSendSingle(t *testing.T) {
b.Fire(&testNotifier{})
expectedURL := fmt.Sprintf("%s/1/batch/%s", e.APIHost, e.Dataset)
testEquals(t, frt.req.URL.String(), expectedURL)
versionedUserAgent := fmt.Sprintf("libhoney-go/%s", Version)
testEquals(t, frt.req.Header.Get("User-Agent"), versionedUserAgent)
versionedUserAgent := fmt.Sprintf("libhoney-go/%s %s", version.Version, runtimeInfo)
assert.Equal(t, versionedUserAgent, frt.req.Header.Get("User-Agent"))
testEquals(t, frt.req.Header.Get("X-Honeycomb-Team"), e.APIKey)
buf := &bytes.Buffer{}
g := zstd.NewWriter(buf)
Expand Down Expand Up @@ -269,11 +270,11 @@ func TestTxSendSingle(t *testing.T) {
// test UserAgentAddition
b.userAgentAddition = " fancyApp/3 "
expectedUserAgentAddition := "fancyApp/3"
longUserAgent := fmt.Sprintf("%s %s", versionedUserAgent, expectedUserAgentAddition)
longUserAgent := fmt.Sprintf("libhoney-go/%s %s %s", version.Version, expectedUserAgentAddition, runtimeInfo)
reset(b, frt, 200, `[{"status":202}]`, nil)
b.Add(e)
b.Fire(&testNotifier{})
testEquals(t, frt.req.Header.Get("User-Agent"), longUserAgent)
assert.Equal(t, longUserAgent, frt.req.Header.Get("User-Agent"))
rsp = testGetResponse(t, b.responses)
testEquals(t, rsp.StatusCode, 202)
testOK(t, rsp.Err)
Expand Down
5 changes: 5 additions & 0 deletions version/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package version

const (
Version string = "1.17.1"
)

0 comments on commit 2f4d796

Please sign in to comment.