Skip to content

Commit c8cc40b

Browse files
authored
Add context and info to logging interface (#237)
Allow the logging interface to propagate context where possible. This will let logging sinks contain richer information about potential opamp IO errors.
1 parent d0205c5 commit c8cc40b

19 files changed

+185
-150
lines changed

client/internal/httpsender.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func (h *HTTPSender) SetRequestHeader(header http.Header) {
134134
func (h *HTTPSender) makeOneRequestRoundtrip(ctx context.Context) {
135135
resp, err := h.sendRequestWithRetries(ctx)
136136
if err != nil {
137-
h.logger.Errorf("%v", err)
137+
h.logger.Errorf(ctx, "%v", err)
138138
return
139139
}
140140
if resp == nil {
@@ -148,9 +148,9 @@ func (h *HTTPSender) sendRequestWithRetries(ctx context.Context) (*http.Response
148148
req, err := h.prepareRequest(ctx)
149149
if err != nil {
150150
if errors.Is(err, context.Canceled) {
151-
h.logger.Debugf("Client is stopped, will not try anymore.")
151+
h.logger.Debugf(ctx, "Client is stopped, will not try anymore.")
152152
} else {
153-
h.logger.Errorf("Failed prepare request (%v), will not try anymore.", err)
153+
h.logger.Errorf(ctx, "Failed prepare request (%v), will not try anymore.", err)
154154
}
155155
return nil, err
156156
}
@@ -190,16 +190,16 @@ func (h *HTTPSender) sendRequestWithRetries(ctx context.Context) (*http.Response
190190
return nil, fmt.Errorf("invalid response from server: %d", resp.StatusCode)
191191
}
192192
} else if errors.Is(err, context.Canceled) {
193-
h.logger.Debugf("Client is stopped, will not try anymore.")
193+
h.logger.Debugf(ctx, "Client is stopped, will not try anymore.")
194194
return nil, err
195195
}
196196

197-
h.logger.Errorf("Failed to do HTTP request (%v), will retry", err)
197+
h.logger.Errorf(ctx, "Failed to do HTTP request (%v), will retry", err)
198198
h.callbacks.OnConnectFailed(err)
199199
}
200200

201201
case <-ctx.Done():
202-
h.logger.Debugf("Client is stopped, will not try anymore.")
202+
h.logger.Debugf(ctx, "Client is stopped, will not try anymore.")
203203
return nil, ctx.Err()
204204
}
205205
}
@@ -239,11 +239,11 @@ func (h *HTTPSender) prepareRequest(ctx context.Context) (*requestWrapper, error
239239
var buf bytes.Buffer
240240
g := gzip.NewWriter(&buf)
241241
if _, err = g.Write(data); err != nil {
242-
h.logger.Errorf("Failed to compress message: %v", err)
242+
h.logger.Errorf(ctx, "Failed to compress message: %v", err)
243243
return nil, err
244244
}
245245
if err = g.Close(); err != nil {
246-
h.logger.Errorf("Failed to close the writer: %v", err)
246+
h.logger.Errorf(ctx, "Failed to close the writer: %v", err)
247247
return nil, err
248248
}
249249
req.bodyReader = bodyReader(buf.Bytes())
@@ -262,14 +262,14 @@ func (h *HTTPSender) receiveResponse(ctx context.Context, resp *http.Response) {
262262
msgBytes, err := io.ReadAll(resp.Body)
263263
if err != nil {
264264
_ = resp.Body.Close()
265-
h.logger.Errorf("cannot read response body: %v", err)
265+
h.logger.Errorf(ctx, "cannot read response body: %v", err)
266266
return
267267
}
268268
_ = resp.Body.Close()
269269

270270
var response protobufs.ServerToAgent
271271
if err := proto.Unmarshal(msgBytes, &response); err != nil {
272-
h.logger.Errorf("cannot unmarshal response: %v", err)
272+
h.logger.Errorf(ctx, "cannot unmarshal response: %v", err)
273273
return
274274
}
275275

client/internal/packagessyncer.go

+22-25
Original file line numberDiff line numberDiff line change
@@ -101,25 +101,25 @@ func (s *packagesSyncer) initStatuses() error {
101101
func (s *packagesSyncer) doSync(ctx context.Context) {
102102
hash, err := s.localState.AllPackagesHash()
103103
if err != nil {
104-
s.logger.Errorf("Package syncing failed: %V", err)
104+
s.logger.Errorf(ctx, "Package syncing failed: %V", err)
105105
return
106106
}
107107
if bytes.Compare(hash, s.available.AllPackagesHash) == 0 {
108-
s.logger.Debugf("All packages are already up to date.")
108+
s.logger.Debugf(ctx, "All packages are already up to date.")
109109
return
110110
}
111111

112112
failed := false
113-
if err := s.deleteUnneededLocalPackages(); err != nil {
114-
s.logger.Errorf("Cannot delete unneeded packages: %v", err)
113+
if err := s.deleteUnneededLocalPackages(ctx); err != nil {
114+
s.logger.Errorf(ctx, "Cannot delete unneeded packages: %v", err)
115115
failed = true
116116
}
117117

118118
// Iterate through offered packages and sync them all from server.
119119
for name, pkg := range s.available.Packages {
120120
err := s.syncPackage(ctx, name, pkg)
121121
if err != nil {
122-
s.logger.Errorf("Cannot sync package %s: %v", name, err)
122+
s.logger.Errorf(ctx, "Cannot sync package %s: %v", name, err)
123123
failed = true
124124
}
125125
}
@@ -128,15 +128,15 @@ func (s *packagesSyncer) doSync(ctx context.Context) {
128128
// Update the "all" hash on success, so that next time Sync() does not thing,
129129
// unless a new hash is received from the Server.
130130
if err := s.localState.SetAllPackagesHash(s.available.AllPackagesHash); err != nil {
131-
s.logger.Errorf("SetAllPackagesHash failed: %v", err)
131+
s.logger.Errorf(ctx, "SetAllPackagesHash failed: %v", err)
132132
} else {
133-
s.logger.Debugf("All packages are synced and up to date.")
133+
s.logger.Debugf(ctx, "All packages are synced and up to date.")
134134
}
135135
} else {
136-
s.logger.Errorf("Package syncing was not successful.")
136+
s.logger.Errorf(ctx, "Package syncing was not successful.")
137137
}
138138

139-
_ = s.reportStatuses(true)
139+
_ = s.reportStatuses(ctx, true)
140140
}
141141

142142
// syncPackage downloads the package from the server and installs it.
@@ -165,7 +165,7 @@ func (s *packagesSyncer) syncPackage(
165165
mustCreate := !pkgLocal.Exists
166166
if pkgLocal.Exists {
167167
if bytes.Equal(pkgLocal.Hash, pkgAvail.Hash) {
168-
s.logger.Debugf("Package %s hash is unchanged, skipping", pkgName)
168+
s.logger.Debugf(ctx, "Package %s hash is unchanged, skipping", pkgName)
169169
return nil
170170
}
171171
if pkgLocal.Type != pkgAvail.Type {
@@ -183,7 +183,7 @@ func (s *packagesSyncer) syncPackage(
183183

184184
// Report that we are beginning to install it.
185185
status.Status = protobufs.PackageStatusEnum_PackageStatusEnum_Installing
186-
_ = s.reportStatuses(true)
186+
_ = s.reportStatuses(ctx, true)
187187

188188
if mustCreate {
189189
// Make sure the package exists.
@@ -213,7 +213,7 @@ func (s *packagesSyncer) syncPackage(
213213
status.Status = protobufs.PackageStatusEnum_PackageStatusEnum_InstallFailed
214214
status.ErrorMessage = err.Error()
215215
}
216-
_ = s.reportStatuses(true)
216+
_ = s.reportStatuses(ctx, true)
217217

218218
return err
219219
}
@@ -224,7 +224,7 @@ func (s *packagesSyncer) syncPackage(
224224
func (s *packagesSyncer) syncPackageFile(
225225
ctx context.Context, pkgName string, file *protobufs.DownloadableFile,
226226
) error {
227-
shouldDownload, err := s.shouldDownloadFile(pkgName, file)
227+
shouldDownload, err := s.shouldDownloadFile(ctx, pkgName, file)
228228
if err == nil && shouldDownload {
229229
err = s.downloadFile(ctx, pkgName, file)
230230
}
@@ -233,21 +233,18 @@ func (s *packagesSyncer) syncPackageFile(
233233
}
234234

235235
// shouldDownloadFile returns true if the file should be downloaded.
236-
func (s *packagesSyncer) shouldDownloadFile(
237-
packageName string,
238-
file *protobufs.DownloadableFile,
239-
) (bool, error) {
236+
func (s *packagesSyncer) shouldDownloadFile(ctx context.Context, packageName string, file *protobufs.DownloadableFile) (bool, error) {
240237
fileContentHash, err := s.localState.FileContentHash(packageName)
241238

242239
if err != nil {
243240
err := fmt.Errorf("cannot calculate checksum of %s: %v", packageName, err)
244-
s.logger.Errorf(err.Error())
241+
s.logger.Errorf(ctx, err.Error())
245242
return true, nil
246243
} else {
247244
// Compare the checksum of the file we have with what
248245
// we are offered by the server.
249246
if bytes.Compare(fileContentHash, file.ContentHash) != 0 {
250-
s.logger.Debugf("Package %s: file hash mismatch, will download.", packageName)
247+
s.logger.Debugf(ctx, "Package %s: file hash mismatch, will download.", packageName)
251248
return true, nil
252249
}
253250
}
@@ -256,7 +253,7 @@ func (s *packagesSyncer) shouldDownloadFile(
256253

257254
// downloadFile downloads the file from the server.
258255
func (s *packagesSyncer) downloadFile(ctx context.Context, pkgName string, file *protobufs.DownloadableFile) error {
259-
s.logger.Debugf("Downloading package %s file from %s", pkgName, file.DownloadUrl)
256+
s.logger.Debugf(ctx, "Downloading package %s file from %s", pkgName, file.DownloadUrl)
260257

261258
req, err := http.NewRequestWithContext(ctx, "GET", file.DownloadUrl, nil)
262259
if err != nil {
@@ -286,7 +283,7 @@ func (s *packagesSyncer) downloadFile(ctx context.Context, pkgName string, file
286283
// deleteUnneededLocalPackages deletes local packages that are not
287284
// needed anymore. This is done by comparing the local package state
288285
// with the server's package state.
289-
func (s *packagesSyncer) deleteUnneededLocalPackages() error {
286+
func (s *packagesSyncer) deleteUnneededLocalPackages(ctx context.Context) error {
290287
// Read the list of packages we have locally.
291288
localPackages, err := s.localState.Packages()
292289
if err != nil {
@@ -297,7 +294,7 @@ func (s *packagesSyncer) deleteUnneededLocalPackages() error {
297294
for _, localPkg := range localPackages {
298295
// Do we have a package that is not offered?
299296
if _, offered := s.available.Packages[localPkg]; !offered {
300-
s.logger.Debugf("Package %s is no longer needed, deleting.", localPkg)
297+
s.logger.Debugf(ctx, "Package %s is no longer needed, deleting.", localPkg)
301298
err := s.localState.DeletePackage(localPkg)
302299
if err != nil {
303300
lastErr = err
@@ -318,16 +315,16 @@ func (s *packagesSyncer) deleteUnneededLocalPackages() error {
318315
// reportStatuses saves the last reported statuses to provider and client state.
319316
// If sendImmediately is true, the statuses are scheduled to be
320317
// sent to the server.
321-
func (s *packagesSyncer) reportStatuses(sendImmediately bool) error {
318+
func (s *packagesSyncer) reportStatuses(ctx context.Context, sendImmediately bool) error {
322319
// Save it in the user-supplied state provider.
323320
if err := s.localState.SetLastReportedStatuses(s.statuses); err != nil {
324-
s.logger.Errorf("Cannot save last reported statuses: %v", err)
321+
s.logger.Errorf(ctx, "Cannot save last reported statuses: %v", err)
325322
return err
326323
}
327324

328325
// Also save it in our internal state (will be needed if the Server asks for it).
329326
if err := s.clientSyncedState.SetPackageStatuses(s.statuses); err != nil {
330-
s.logger.Errorf("Cannot save client state: %v", err)
327+
s.logger.Errorf(ctx, "Cannot save client state: %v", err)
331328
return err
332329
}
333330
s.sender.NextMessage().Update(

client/internal/receivedprocessor.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ func (r *receivedProcessor) ProcessReceivedMessage(ctx context.Context, msg *pro
6060
// If a command message exists, other messages will be ignored
6161
return
6262
} else {
63-
r.logger.Debugf("Ignoring Command, agent does not have AcceptsCommands capability")
63+
r.logger.Debugf(ctx, "Ignoring Command, agent does not have AcceptsCommands capability")
6464
}
6565
}
6666

6767
scheduled, err := r.rcvFlags(ctx, protobufs.ServerToAgentFlags(msg.Flags))
6868
if err != nil {
69-
r.logger.Errorf("cannot processed received flags:%v", err)
69+
r.logger.Errorf(ctx, "cannot processed received flags:%v", err)
7070
}
7171

7272
msgData := &types.MessageData{}
@@ -75,7 +75,7 @@ func (r *receivedProcessor) ProcessReceivedMessage(ctx context.Context, msg *pro
7575
if r.hasCapability(protobufs.AgentCapabilities_AgentCapabilities_AcceptsRemoteConfig) {
7676
msgData.RemoteConfig = msg.RemoteConfig
7777
} else {
78-
r.logger.Debugf("Ignoring RemoteConfig, agent does not have AcceptsRemoteConfig capability")
78+
r.logger.Debugf(ctx, "Ignoring RemoteConfig, agent does not have AcceptsRemoteConfig capability")
7979
}
8080
}
8181

@@ -84,31 +84,31 @@ func (r *receivedProcessor) ProcessReceivedMessage(ctx context.Context, msg *pro
8484
if r.hasCapability(protobufs.AgentCapabilities_AgentCapabilities_ReportsOwnMetrics) {
8585
msgData.OwnMetricsConnSettings = msg.ConnectionSettings.OwnMetrics
8686
} else {
87-
r.logger.Debugf("Ignoring OwnMetrics, agent does not have ReportsOwnMetrics capability")
87+
r.logger.Debugf(ctx, "Ignoring OwnMetrics, agent does not have ReportsOwnMetrics capability")
8888
}
8989
}
9090

9191
if msg.ConnectionSettings.OwnTraces != nil {
9292
if r.hasCapability(protobufs.AgentCapabilities_AgentCapabilities_ReportsOwnTraces) {
9393
msgData.OwnTracesConnSettings = msg.ConnectionSettings.OwnTraces
9494
} else {
95-
r.logger.Debugf("Ignoring OwnTraces, agent does not have ReportsOwnTraces capability")
95+
r.logger.Debugf(ctx, "Ignoring OwnTraces, agent does not have ReportsOwnTraces capability")
9696
}
9797
}
9898

9999
if msg.ConnectionSettings.OwnLogs != nil {
100100
if r.hasCapability(protobufs.AgentCapabilities_AgentCapabilities_ReportsOwnLogs) {
101101
msgData.OwnLogsConnSettings = msg.ConnectionSettings.OwnLogs
102102
} else {
103-
r.logger.Debugf("Ignoring OwnLogs, agent does not have ReportsOwnLogs capability")
103+
r.logger.Debugf(ctx, "Ignoring OwnLogs, agent does not have ReportsOwnLogs capability")
104104
}
105105
}
106106

107107
if msg.ConnectionSettings.OtherConnections != nil {
108108
if r.hasCapability(protobufs.AgentCapabilities_AgentCapabilities_AcceptsOtherConnectionSettings) {
109109
msgData.OtherConnSettings = msg.ConnectionSettings.OtherConnections
110110
} else {
111-
r.logger.Debugf("Ignoring OtherConnections, agent does not have AcceptsOtherConnectionSettings capability")
111+
r.logger.Debugf(ctx, "Ignoring OtherConnections, agent does not have AcceptsOtherConnectionSettings capability")
112112
}
113113
}
114114
}
@@ -124,7 +124,7 @@ func (r *receivedProcessor) ProcessReceivedMessage(ctx context.Context, msg *pro
124124
r.packagesStateProvider,
125125
)
126126
} else {
127-
r.logger.Debugf("Ignoring PackagesAvailable, agent does not have AcceptsPackages capability")
127+
r.logger.Debugf(ctx, "Ignoring PackagesAvailable, agent does not have AcceptsPackages capability")
128128
}
129129
}
130130

@@ -164,7 +164,7 @@ func (r *receivedProcessor) rcvFlags(
164164
if flags&protobufs.ServerToAgentFlags_ServerToAgentFlags_ReportFullState != 0 {
165165
cfg, err := r.callbacks.GetEffectiveConfig(ctx)
166166
if err != nil {
167-
r.logger.Errorf("Cannot GetEffectiveConfig: %v", err)
167+
r.logger.Errorf(ctx, "Cannot GetEffectiveConfig: %v", err)
168168
cfg = nil
169169
}
170170

@@ -199,25 +199,25 @@ func (r *receivedProcessor) rcvOpampConnectionSettings(ctx context.Context, sett
199199
r.callbacks.OnOpampConnectionSettingsAccepted(settings.Opamp)
200200
}
201201
} else {
202-
r.logger.Debugf("Ignoring Opamp, agent does not have AcceptsOpAMPConnectionSettings capability")
202+
r.logger.Debugf(ctx, "Ignoring Opamp, agent does not have AcceptsOpAMPConnectionSettings capability")
203203
}
204204
}
205205

206206
func (r *receivedProcessor) processErrorResponse(body *protobufs.ServerErrorResponse) {
207207
// TODO: implement this.
208-
r.logger.Errorf("received an error from server: %s", body.ErrorMessage)
208+
r.logger.Errorf(context.Background(), "received an error from server: %s", body.ErrorMessage)
209209
}
210210

211211
func (r *receivedProcessor) rcvAgentIdentification(agentId *protobufs.AgentIdentification) error {
212212
if agentId.NewInstanceUid == "" {
213213
err := errors.New("empty instance uid is not allowed")
214-
r.logger.Debugf(err.Error())
214+
r.logger.Debugf(context.Background(), err.Error())
215215
return err
216216
}
217217

218218
err := r.sender.SetInstanceUid(agentId.NewInstanceUid)
219219
if err != nil {
220-
r.logger.Errorf("Error while setting instance uid: %v", err)
220+
r.logger.Errorf(context.Background(), "Error while setting instance uid: %v", err)
221221
return err
222222
}
223223

client/internal/wsreceiver.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ out:
5050
var message protobufs.ServerToAgent
5151
if err := r.receiveMessage(&message); err != nil {
5252
if ctx.Err() == nil && !websocket.IsCloseError(err, websocket.CloseNormalClosure) {
53-
r.logger.Errorf("Unexpected error while receiving: %v", err)
53+
r.logger.Errorf(ctx, "Unexpected error while receiving: %v", err)
5454
}
5555
break out
5656
} else {

client/internal/wsreceiver_test.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,20 @@ import (
1414
"github.com/open-telemetry/opamp-go/protobufs"
1515
)
1616

17+
var _ types.Logger = &TestLogger{}
18+
1719
type TestLogger struct {
1820
*testing.T
1921
}
2022

21-
func (logger TestLogger) Debugf(format string, v ...interface{}) {
23+
func (logger TestLogger) Debugf(ctx context.Context, format string, v ...interface{}) {
2224
logger.Logf(format, v...)
2325
}
2426

27+
func (logger TestLogger) Errorf(ctx context.Context, format string, v ...interface{}) {
28+
logger.Fatalf(format, v...)
29+
}
30+
2531
type commandAction int
2632

2733
const (

0 commit comments

Comments
 (0)