Skip to content

Commit 8057cbf

Browse files
committed
Add B3 trace IDs to cf cli commands
1 parent dfe2201 commit 8057cbf

File tree

7 files changed

+222
-0
lines changed

7 files changed

+222
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package wrapper
2+
3+
import (
4+
"code.cloudfoundry.org/cli/api/cloudcontroller"
5+
)
6+
7+
// TODO
8+
// 1. tests
9+
// 2. do not overwrite headers if explicitly set (cf curl)
10+
// 3. headers should go on other clients (uaa/routing) as well (with same value)
11+
// 4. environment variable override
12+
13+
const (
14+
// B3TraceIDHeader is the header key for the b3 trace id.
15+
B3TraceIDHeader = "X-B3-Traceid"
16+
17+
// B3SpanIDHeader is the header key for the b3 span id.
18+
B3SpanIDHeader = "X-B3-Spanid"
19+
)
20+
21+
// TraceHeaderRequest is a wrapper that adds b3 trace headers to requests.
22+
type TraceHeaderRequest struct {
23+
b3trace string
24+
b3span string
25+
connection cloudcontroller.Connection
26+
}
27+
28+
// NewTraceHeaderRequest returns a pointer to a TraceHeaderRequest wrapper.
29+
func NewTraceHeaderRequest(trace, span string) *TraceHeaderRequest {
30+
return &TraceHeaderRequest{
31+
b3trace: trace,
32+
b3span: span,
33+
}
34+
}
35+
36+
// Add tracing headers if they are not already set.
37+
func (t *TraceHeaderRequest) Make(request *cloudcontroller.Request, passedResponse *cloudcontroller.Response) error {
38+
39+
// todo
40+
// only override the trace headers if they are not already set (e.g. already explicitly set by cf curl)
41+
if request.Header.Get(B3TraceIDHeader) != "" {
42+
request.Header.Add(B3TraceIDHeader, t.b3trace)
43+
}
44+
if request.Header.Get(B3SpanIDHeader) != "" {
45+
request.Header.Add(B3SpanIDHeader, t.b3span)
46+
}
47+
return t.connection.Make(request, passedResponse)
48+
}
49+
50+
// Wrap sets the connection in the TraceHeaderRequest and returns itself.
51+
func (t *TraceHeaderRequest) Wrap(innerconnection cloudcontroller.Connection) cloudcontroller.Connection {
52+
t.connection = innerconnection
53+
return t
54+
}

command/commandfakes/fake_config.go

Lines changed: 130 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

command/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ type Config interface {
1515
AddPluginRepository(name string, url string)
1616
AuthorizationEndpoint() string
1717
APIVersion() string
18+
B3TraceID() string
19+
B3SpanID() string
1820
BinaryName() string
1921
BinaryVersion() string
2022
CFPassword() string

command/v7/shared/new_clients.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func NewWrappedCloudControllerClient(config command.Config, ui command.UI, extra
4646
ccWrappers = append(ccWrappers, ccWrapper.NewRequestLogger(ui.RequestLoggerFileWriter(location)))
4747
}
4848

49+
ccWrappers = append(ccWrappers, ccWrapper.NewTraceHeaderRequest(config.B3TraceID(), config.B3SpanID()))
4950
ccWrappers = append(ccWrappers, extraWrappers...)
5051
ccWrappers = append(ccWrappers, ccWrapper.NewRetryRequest(config.RequestRetryCount()))
5152

util/configv3/env.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"strconv"
66
"strings"
77
"time"
8+
9+
"code.cloudfoundry.org/cli/util/random"
810
)
911

1012
// EnvOverride represents all the environment variables read by the CF CLI
@@ -20,6 +22,8 @@ type EnvOverride struct {
2022
CFStartupTimeout string
2123
CFTrace string
2224
CFUsername string
25+
CFB3TraceID string
26+
CFB3SpanID string
2327
DockerPassword string
2428
CNBCredentials string
2529
Experimental string
@@ -160,3 +164,17 @@ func (config *Config) StartupTimeout() time.Duration {
160164

161165
return DefaultStartupTimeout
162166
}
167+
168+
func (config *Config) B3TraceID() string {
169+
if config.ENV.CFB3TraceID == "" {
170+
return random.GenerateHex(32)
171+
}
172+
return config.ENV.CFB3TraceID
173+
}
174+
175+
func (config *Config) B3SpanID() string {
176+
if config.ENV.CFB3SpanID == "" {
177+
return random.GenerateHex(16)
178+
}
179+
return config.ENV.CFB3SpanID
180+
}

util/configv3/load_config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ func LoadConfig(flags ...FlagOverride) (*Config, error) {
127127
CFStartupTimeout: os.Getenv("CF_STARTUP_TIMEOUT"),
128128
CFTrace: os.Getenv("CF_TRACE"),
129129
CFUsername: os.Getenv("CF_USERNAME"),
130+
CFB3TraceID: os.Getenv("CF_B3_TRACE_ID"),
131+
CFB3SpanID: os.Getenv("CF_B3_SPAN_ID"),
130132
DockerPassword: os.Getenv("CF_DOCKER_PASSWORD"),
131133
CNBCredentials: os.Getenv("CNB_REGISTRY_CREDS"),
132134
Experimental: os.Getenv("CF_CLI_EXPERIMENTAL"),

util/random/hex.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package random
2+
3+
import (
4+
"crypto/rand"
5+
"encoding/hex"
6+
)
7+
8+
func GenerateHex(length int) string {
9+
b := make([]byte, length/2)
10+
if _, err := rand.Read(b); err != nil {
11+
panic(err)
12+
}
13+
14+
return hex.EncodeToString(b)
15+
}

0 commit comments

Comments
 (0)