Skip to content

Commit 9fe0bae

Browse files
cameronmeissnerCameron Meissner
andauthored
feat(client): store logger on the context, logging improvements for gRPC timeouts (#139)
Co-authored-by: Cameron Meissner <[email protected]>
1 parent 27fd0ad commit 9fe0bae

File tree

21 files changed

+403
-299
lines changed

21 files changed

+403
-299
lines changed

client/cmd/client/main.go

Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,13 @@ import (
1010
"fmt"
1111
"os"
1212
"os/signal"
13-
"path/filepath"
1413
"syscall"
1514
"time"
1615

1716
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/bootstrap"
17+
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/log"
1818
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/telemetry"
1919
"go.uber.org/zap"
20-
"go.uber.org/zap/zapcore"
2120
)
2221

2322
var bootstrapConfig = new(bootstrap.Config)
@@ -67,14 +66,16 @@ func main() {
6766
}
6867

6968
func run(ctx context.Context) int {
70-
logger, finalErr := configureLogging(logFile, verbose)
69+
logger, flush, finalErr := log.NewProductionLogger(logFile, verbose)
7170
if finalErr != nil {
7271
fmt.Printf("unable to construct zap logger: %s\n", finalErr)
7372
return 1
7473
}
75-
defer flush(logger)
74+
defer flush()
7675

77-
bootstrapClient, finalErr := bootstrap.NewClient(logger)
76+
ctx = log.WithLogger(telemetry.WithTracing(ctx), logger)
77+
78+
bootstrapClient, finalErr := bootstrap.NewClient(ctx)
7879
if finalErr != nil {
7980
fmt.Printf("unable to construct bootstrap client: %s\n", finalErr)
8081
return 1
@@ -84,8 +85,7 @@ func run(ctx context.Context) int {
8485
bootstrapDeadline := bootstrapStartTime.Add(bootstrapConfig.Deadline)
8586
logger.Info("set bootstrap deadline", zap.Time("deadline", bootstrapDeadline))
8687

87-
bootstrapCtx := telemetry.WithTracer(ctx, telemetry.NewTracer())
88-
bootstrapCtx, cancel := context.WithDeadline(bootstrapCtx, bootstrapDeadline)
88+
bootstrapCtx, cancel := context.WithDeadline(ctx, bootstrapDeadline)
8989
defer cancel()
9090

9191
finalErr, errLog, traces := bootstrap.Bootstrap(bootstrapCtx, bootstrapClient, bootstrapConfig)
@@ -137,44 +137,3 @@ func run(ctx context.Context) int {
137137

138138
return exitCode
139139
}
140-
141-
func configureLogging(logFile string, verbose bool) (*zap.Logger, error) {
142-
encoderConfig := zap.NewProductionEncoderConfig()
143-
encoderConfig.TimeKey = "timestamp"
144-
encoderConfig.EncodeTime = zapcore.RFC3339NanoTimeEncoder
145-
146-
level := zap.InfoLevel
147-
if verbose {
148-
level = zap.DebugLevel
149-
}
150-
151-
cores := []zapcore.Core{
152-
zapcore.NewCore(
153-
zapcore.NewConsoleEncoder(encoderConfig),
154-
zapcore.AddSync(os.Stdout),
155-
level,
156-
),
157-
}
158-
159-
if logFile != "" {
160-
if err := os.MkdirAll(filepath.Dir(logFile), 0755); err != nil {
161-
return nil, fmt.Errorf("failed to create log directory: %w", err)
162-
}
163-
logFileHandle, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
164-
if err != nil {
165-
return nil, fmt.Errorf("failed to open log file: %w", err)
166-
}
167-
cores = append(cores, zapcore.NewCore(
168-
zapcore.NewJSONEncoder(encoderConfig),
169-
zapcore.AddSync(logFileHandle),
170-
level,
171-
))
172-
}
173-
174-
return zap.New(zapcore.NewTee(cores...)), nil
175-
}
176-
177-
func flush(logger *zap.Logger) {
178-
// per guidance from: https://github.com/uber-go/zap/issues/328
179-
_ = logger.Sync()
180-
}

client/internal/bootstrap/auth.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strings"
1111

1212
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/cloud"
13+
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/log"
1314
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/telemetry"
1415
"github.com/Azure/go-autorest/autorest/adal"
1516
"github.com/Azure/go-autorest/autorest/azure"
@@ -41,18 +42,18 @@ func extractAccessToken(token *adal.ServicePrincipalToken) (string, error) {
4142
// getAccessToken retrieves an AAD access token (JWT) using the specified custom client ID, resource, and cloud provider config.
4243
// MSI access tokens are retrieved from IMDS, while service principal tokens are retrieved directly from AAD.
4344
func (c *Client) getAccessToken(ctx context.Context, customClientID, resource string, cloudProviderConfig *cloud.ProviderConfig) (string, error) {
44-
spanName := "GetAccessToken"
45-
tracer := telemetry.MustGetTracer(ctx)
46-
tracer.StartSpan(spanName)
47-
defer tracer.EndSpan(spanName)
45+
endSpan := telemetry.StartSpan(ctx, "GetAccessToken")
46+
defer endSpan()
47+
48+
logger := log.MustGetLogger(ctx)
4849

4950
userAssignedID := cloudProviderConfig.UserAssignedIdentityID
5051
if customClientID != "" {
5152
userAssignedID = customClientID
5253
}
5354

5455
if userAssignedID != "" {
55-
c.logger.Info("generating MSI access token", zap.String("clientId", userAssignedID))
56+
logger.Info("generating MSI access token", zap.String("clientId", userAssignedID))
5657
token, err := adal.NewServicePrincipalTokenFromManagedIdentity(resource, &adal.ManagedIdentityOptions{
5758
ClientID: userAssignedID,
5859
})
@@ -79,15 +80,15 @@ func (c *Client) getAccessToken(ctx context.Context, customClientID, resource st
7980
}
8081

8182
if !strings.HasPrefix(cloudProviderConfig.ClientSecret, certificateSecretPrefix) {
82-
c.logger.Info("generating SPN access token with username and password", zap.String("clientId", cloudProviderConfig.ClientID))
83+
logger.Info("generating SPN access token with username and password", zap.String("clientId", cloudProviderConfig.ClientID))
8384
token, err := adal.NewServicePrincipalToken(*oauthConfig, cloudProviderConfig.ClientID, cloudProviderConfig.ClientSecret, resource)
8485
if err != nil {
8586
return "", fmt.Errorf("generating SPN access token with username and password: %w", err)
8687
}
8788
return c.extractAccessTokenFunc(token)
8889
}
8990

90-
c.logger.Info("client secret contains certificate data, using certificate to generate SPN access token", zap.String("clientId", cloudProviderConfig.ClientID))
91+
logger.Info("client secret contains certificate data, using certificate to generate SPN access token", zap.String("clientId", cloudProviderConfig.ClientID))
9192

9293
certData, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(cloudProviderConfig.ClientSecret, certificateSecretPrefix))
9394
if err != nil {
@@ -98,7 +99,7 @@ func (c *Client) getAccessToken(ctx context.Context, customClientID, resource st
9899
return "", fmt.Errorf("decoding pfx certificate data in client secret: %w", err)
99100
}
100101

101-
c.logger.Info("generating SPN access token with certificate", zap.String("clientId", cloudProviderConfig.ClientID))
102+
logger.Info("generating SPN access token with certificate", zap.String("clientId", cloudProviderConfig.ClientID))
102103
token, err := adal.NewServicePrincipalTokenFromCertificate(*oauthConfig, cloudProviderConfig.ClientID, certificate, privateKey, resource)
103104
if err != nil {
104105
return "", fmt.Errorf("generating SPN access token with certificate: %w", err)

client/internal/bootstrap/auth_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import (
99
"time"
1010

1111
"github.com/stretchr/testify/assert"
12-
"go.uber.org/zap"
1312

1413
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/cloud"
14+
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/log"
1515
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/telemetry"
1616
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/testutil"
1717
"github.com/Azure/go-autorest/autorest/adal"
@@ -193,15 +193,13 @@ func TestGetAccessToken(t *testing.T) {
193193
},
194194
}
195195

196-
logger, _ := zap.NewDevelopment()
197196
testTenantID := "d87a2c3e-0c0c-42b2-a883-e48cd8723e22"
198197
testResource := "resource"
199198

200199
for _, c := range cases {
201200
t.Run(c.name, func(t *testing.T) {
202-
ctx := telemetry.NewContext()
201+
ctx := telemetry.WithTracing(log.NewTestContext())
203202
client := &Client{
204-
logger: logger,
205203
extractAccessTokenFunc: c.setupExtractAccessTokenFunc(t),
206204
}
207205
providerCfg := &cloud.ProviderConfig{

client/internal/bootstrap/bootstrap.go

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import (
77
"context"
88
"errors"
99
"fmt"
10-
"os"
11-
"path/filepath"
1210
"time"
1311

1412
"github.com/Azure/aks-secure-tls-bootstrap/client/internal/telemetry"
@@ -30,7 +28,7 @@ func Bootstrap(ctx context.Context, client *Client, config *Config) (finalErr er
3028
finalErr = retry.Do(
3129
func() error {
3230
defer func() {
33-
traces.Add(telemetry.MustGetTracer(ctx).GetTrace())
31+
traces.Add(telemetry.GetTrace(ctx))
3432
}()
3533

3634
kubeconfigData, err := client.BootstrapKubeletClientCredential(ctx, config)
@@ -66,17 +64,8 @@ func Bootstrap(ctx context.Context, client *Client, config *Config) (finalErr er
6664
}
6765

6866
func writeKubeconfig(ctx context.Context, config *clientcmdapi.Config, path string) error {
69-
traceName := "WriteKubeconfig"
70-
tracer := telemetry.MustGetTracer(ctx)
71-
tracer.StartSpan(traceName)
72-
defer tracer.EndSpan(traceName)
73-
74-
if err := os.MkdirAll(filepath.Dir(path), 0600); err != nil {
75-
return &BootstrapError{
76-
errorType: ErrorTypeWriteKubeconfigFailure,
77-
inner: fmt.Errorf("creating parent directories for kubeconfig path: %w", err),
78-
}
79-
}
67+
endSpan := telemetry.StartSpan(ctx, "WriteKubeconfig")
68+
defer endSpan()
8069

8170
if err := clientcmd.WriteToFile(*config, path); err != nil {
8271
return &BootstrapError{

0 commit comments

Comments
 (0)