Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
Signed-off-by: Remy Chantenay <[email protected]>
  • Loading branch information
remychantenay committed Nov 11, 2024
1 parent b03f7d6 commit 1113715
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 30 deletions.
8 changes: 2 additions & 6 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
go-version: '1.23'

- name: Install golangci-lint
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.2
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.61.0

- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
Expand All @@ -33,7 +33,3 @@ jobs:
- name: Testing
run: make test

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
66 changes: 60 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,66 @@
Simple package that extracts OpenTelemetry span attributes from a struct based on tags.

## Shortcomings
- Do not support embedded structs.
- Does not support embedded structs.

## Usage
### Span Attributes
```go
package main

import (
"context"

"go.opentelemetry.io/otel/trace"

oteltag "github.com/remychantenay/otel-tag"
)

type User struct {
ID string `otel:"app.user.id"`
Username string `otel:"app.user.username"`
IsPremium bool `otel:"app.user.premium"`
Website string `otel:"app.user.website,omitempty"`
Bio string `otel:"-"`
}

func main() {
_, span := tracer.Start(context.Background(), "someOperation",
trace.WithAttributes(oteltag.SpanAttributes(m)...),
)
defer span.End()
}
```

### Baggage Members
```go
package main

import (
"context"

"go.opentelemetry.io/otel/baggage"

oteltag "github.com/remychantenay/otel-tag"
)

type User struct {
ID string `otel:"app.user.id"`
Username string `otel:"app.user.username"`
IsPremium bool `otel:"app.user.premium"`
Website string `otel:"app.user.website,omitempty"`
Bio string `otel:"-"`
}

func main() {
members := oteltag.BaggageMembers(m)
bag, _ := baggage.New(members...)
ctx := baggage.ContextWithBaggage(context.Background(), bag)

_, span := tracer.Start(ctx, "someOperation")
defer span.End()
}
```

## License
Apache License Version 2.0

TODO
- Shit! What about attribute name prefix???! Init?
- Remove t.Log() calls in tests
- Complete README.md with example
4 changes: 2 additions & 2 deletions baggage.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ func BaggageMembers(res any) []baggage.Member {
for i := 0; i < fieldCount; i++ {
tag := internal.ExtractTag(structValue, i)

if len(tag) == 0 || tag == valIgnore {
if len(tag) == 0 || tag == flagIgnore {
continue
}

var omitEmpty bool
before, after, found := strings.Cut(tag, ",")
if found {
tag = before
if after == valOmitEmpty {
if after == flagOmitEmpty {
omitEmpty = true
}
}
Expand Down
24 changes: 18 additions & 6 deletions baggage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ func TestBaggageMembers(t *testing.T) {
if memberCount != wantMemberCount {
t.Errorf("\ngot %d members\nwant %d", memberCount, wantMemberCount)
}

for i := range bag.Members() {
t.Log(bag.Members()[i].Key())
}
})

t.Run("when zero values and omitted - should not add members to baggage", func(t *testing.T) {
Expand Down Expand Up @@ -77,9 +73,25 @@ func TestBaggageMembers(t *testing.T) {
if memberCount != wantMemberCount {
t.Errorf("\ngot %d members\nwant %d", memberCount, wantMemberCount)
}
})

t.Run("when fields are ignored - should not add members to baggage", func(t *testing.T) {
const wantMemberCount = 0

m := struct {
ValStrIgnored string `otel:"-"`
}{
ValStrIgnored: "a_string",
}

for i := range bag.Members() {
t.Log(bag.Members()[i].Key())
members := oteltag.BaggageMembers(m)
bag, _ := baggage.New(members...)
ctx := baggage.ContextWithBaggage(context.Background(), bag)
bag = baggage.FromContext(ctx)

memberCount := len(bag.Members())
if memberCount != wantMemberCount {
t.Errorf("\ngot %d members\nwant %d", memberCount, wantMemberCount)
}
})
}
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package oteltag

const (
valIgnore = "-"
valOmitEmpty = "omitempty"
flagIgnore = "-"
flagOmitEmpty = "omitempty"
)
4 changes: 2 additions & 2 deletions span.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ func SpanAttributes(res any) []attribute.KeyValue {
for i := 0; i < fieldCount; i++ {
tag := internal.ExtractTag(structValue, i)

if len(tag) == 0 || tag == valIgnore {
if len(tag) == 0 || tag == flagIgnore {
continue
}

var omitEmpty bool
before, after, found := strings.Cut(tag, ",")
if found {
tag = before
if after == valOmitEmpty {
if after == flagOmitEmpty {
omitEmpty = true
}
}
Expand Down
38 changes: 32 additions & 6 deletions span_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ func TestSpanAttributes(t *testing.T) {
if attrCount != expectedAttributeCount {
t.Errorf("\ngot %d attributes\nwant %d", attrCount, expectedAttributeCount)
}

// for i := range spans[0].Attributes() {
// t.Log(spans[0].Attributes()[i].Value)
// }
})

t.Run("when zero values and omitted - should not add attributes to span", func(t *testing.T) {
Expand Down Expand Up @@ -131,9 +127,39 @@ func TestSpanAttributes(t *testing.T) {
if attrCount != expectedAttributeCount {
t.Errorf("\ngot %d attributes\nwant %d", attrCount, expectedAttributeCount)
}
})

t.Run("when fields are ignored - should not add attributes to span", func(t *testing.T) {
const (
wantSpanCount = 1
expectedAttributeCount = 0
)

spanRecorder, tracer := setupTracer()

for i := range spans[0].Attributes() {
t.Log(spans[0].Attributes()[i].Key)
m := struct {
ValStrIgnored string `otel:"-"`
}{
ValStrIgnored: "a_string",
}

func() {
_, span := tracer.Start(
context.Background(),
testOperationName,
trace.WithAttributes(oteltag.SpanAttributes(m)...),
)
defer span.End()
}()

spans := spanRecorder.Ended()
if len(spans) != wantSpanCount {
t.Errorf("\ngot %d spans\nwant %d", len(spans), wantSpanCount)
}

attrCount := len(spans[0].Attributes())
if attrCount != expectedAttributeCount {
t.Errorf("\ngot %d attributes\nwant %d", attrCount, expectedAttributeCount)
}
})
}

0 comments on commit 1113715

Please sign in to comment.