From 472d211b53b6c4da79f9fd5a3647243c99d3fb2e Mon Sep 17 00:00:00 2001 From: Hamza El-Saawy Date: Wed, 16 Feb 2022 16:22:42 -0500 Subject: [PATCH 1/2] Span sampling and export; logging context integration Updated span export to: * include span kind * log if span attributes were dropped * format time as string instead Added `log.S()` to set the log entry stored in the context with provided fields. `log.G()` now checks the context for a stored context. Added `log.Copy()` to add log entry and trace span from source context to destination, allowing for duplicating contexts but not cancellation. Added `log.U()` to update the context an entry (in the context) points to, allowing it to reference the latest span and other information. Added `oc.StartSpan` to set the context log-entries reference to the newly created valaue. Added helper `log.Format*` functions to format Time and other structs to JSON, but only if the logging level is high enough that the information would be logged. Set span kind to client/server, as required, for bridge RPC calls. Updated internal/cmd to use spans within `.Start()` and `.Wait()` Reduced the number of `INFO` level logs printed, downgrading to `DEBUG`. Moved traces and spans from inside `Once.Do()`, so that they are always logged, even if the `Once` does not execute. Signed-off-by: Hamza El-Saawy --- cmd/containerd-shim-runhcs-v1/delete.go | 3 +- cmd/containerd-shim-runhcs-v1/events.go | 6 +- cmd/containerd-shim-runhcs-v1/exec_clone.go | 11 +- cmd/containerd-shim-runhcs-v1/exec_hcs.go | 64 ++++++-- .../exec_wcow_podsandbox.go | 29 +++- cmd/containerd-shim-runhcs-v1/main.go | 7 +- cmd/containerd-shim-runhcs-v1/pod.go | 22 ++- cmd/containerd-shim-runhcs-v1/serve.go | 46 ++++-- cmd/containerd-shim-runhcs-v1/service.go | 57 +++---- cmd/containerd-shim-runhcs-v1/task_hcs.go | 152 +++++++++++++---- .../task_wcow_podsandbox.go | 61 +++++-- cmd/gcs/main.go | 2 + cmd/ncproxy/ncproxy.go | 39 +++-- cmd/ncproxy/run.go | 2 +- cmd/ncproxy/server.go | 6 +- cmd/runhcs/create-scratch.go | 3 +- cmd/runhcs/prepare-disk.go | 3 +- computestorage/attach.go | 4 +- computestorage/destroy.go | 4 +- computestorage/detach.go | 4 +- computestorage/export.go | 4 +- computestorage/format.go | 5 +- computestorage/import.go | 4 +- computestorage/initialize.go | 4 +- computestorage/mount.go | 5 +- computestorage/setup.go | 8 +- container.go | 2 +- hcn/hcnsupport.go | 13 +- internal/cmd/cmd.go | 74 ++++++--- internal/cmd/diag.go | 7 + internal/cmd/io.go | 24 ++- internal/cmd/io_binary.go | 26 ++- internal/cmd/io_npipe.go | 16 +- internal/copyfile/copyfile.go | 2 +- internal/devices/assigned_devices.go | 2 +- internal/gcs/bridge.go | 8 +- internal/gcs/container.go | 31 ++-- internal/gcs/guestconnection.go | 12 +- internal/gcs/guestconnection_test.go | 4 +- internal/gcs/iochannel.go | 4 + internal/gcs/process.go | 16 +- internal/gcs/protocol.go | 73 +++++---- internal/guest/bridge/bridge.go | 24 ++- internal/guest/bridge/bridge_v2.go | 26 +-- internal/guest/kmsg/kmsg.go | 2 +- internal/guest/network/network.go | 6 +- internal/guest/runtime/hcsv2/container.go | 5 +- internal/guest/runtime/hcsv2/network.go | 14 +- internal/guest/runtime/hcsv2/process.go | 9 +- .../guest/runtime/hcsv2/sandbox_container.go | 2 +- .../runtime/hcsv2/standalone_container.go | 2 +- .../guest/runtime/hcsv2/workload_container.go | 2 +- .../guest/storage/devicemapper/targets.go | 4 +- internal/guest/storage/mount.go | 2 +- internal/guest/storage/overlay/overlay.go | 4 +- internal/guest/storage/plan9/plan9.go | 2 +- internal/guest/storage/pmem/pmem.go | 4 +- internal/guest/storage/scsi/scsi.go | 8 +- internal/guest/transport/vsock.go | 16 +- internal/hcs/errors.go | 2 + internal/hcs/process.go | 50 ++++-- internal/hcs/system.go | 53 +++--- internal/hcsoci/create.go | 32 ++-- internal/hcsoci/devices.go | 2 +- internal/hcsoci/hcsdoc_lcow.go | 3 +- internal/hcsoci/hcsdoc_wcow.go | 12 +- internal/hcsoci/network.go | 18 +-- internal/hcsoci/resources.go | 2 +- internal/hcsoci/resources_lcow.go | 8 +- internal/hcsoci/resources_wcow.go | 11 +- internal/layers/layers.go | 43 +++-- internal/log/context.go | 127 +++++++++++++++ internal/log/format.go | 74 +++++++++ internal/log/g.go | 23 --- internal/log/hook.go | 153 ++++++++++++++++++ internal/log/scrub.go | 28 ++-- internal/logfields/fields.go | 33 +++- internal/oc/errors.go | 58 +++++++ internal/oc/exporter.go | 72 +++++++-- internal/oc/span.go | 47 +++++- internal/resources/resources.go | 12 +- internal/uvm/computeagent.go | 21 ++- internal/uvm/create.go | 2 +- internal/uvm/create_lcow.go | 7 +- internal/uvm/create_wcow.go | 12 +- internal/uvm/network.go | 14 +- internal/uvm/plan9.go | 27 +++- internal/uvm/start.go | 2 +- internal/uvm/vsmb.go | 36 ++++- internal/vmcompute/vmcompute.go | 57 +++---- internal/wclayer/activatelayer.go | 2 +- internal/wclayer/createlayer.go | 2 +- internal/wclayer/createscratchlayer.go | 2 +- internal/wclayer/deactivatelayer.go | 2 +- internal/wclayer/destroylayer.go | 2 +- internal/wclayer/expandscratchsize.go | 2 +- internal/wclayer/exportlayer.go | 4 +- internal/wclayer/getlayermountpath.go | 2 +- internal/wclayer/getsharedbaseimages.go | 2 +- internal/wclayer/grantvmaccess.go | 2 +- internal/wclayer/importlayer.go | 4 +- internal/wclayer/layerexists.go | 2 +- internal/wclayer/layerid.go | 2 +- internal/wclayer/nametoguid.go | 2 +- internal/wclayer/preparelayer.go | 2 +- internal/wclayer/processimage.go | 4 +- internal/wclayer/unpreparelayer.go | 2 +- pkg/octtrpc/interceptor.go | 7 +- .../hcsshim/computestorage/attach.go | 4 +- .../hcsshim/computestorage/destroy.go | 4 +- .../hcsshim/computestorage/detach.go | 4 +- .../hcsshim/computestorage/export.go | 4 +- .../hcsshim/computestorage/format.go | 5 +- .../hcsshim/computestorage/import.go | 4 +- .../hcsshim/computestorage/initialize.go | 4 +- .../Microsoft/hcsshim/computestorage/mount.go | 5 +- .../Microsoft/hcsshim/computestorage/setup.go | 8 +- .../github.com/Microsoft/hcsshim/container.go | 2 +- .../Microsoft/hcsshim/hcn/hcnsupport.go | 13 +- .../Microsoft/hcsshim/internal/cmd/cmd.go | 74 ++++++--- .../Microsoft/hcsshim/internal/cmd/diag.go | 7 + .../Microsoft/hcsshim/internal/cmd/io.go | 24 ++- .../hcsshim/internal/cmd/io_binary.go | 26 ++- .../hcsshim/internal/cmd/io_npipe.go | 16 +- .../hcsshim/internal/copyfile/copyfile.go | 2 +- .../internal/devices/assigned_devices.go | 2 +- .../Microsoft/hcsshim/internal/gcs/bridge.go | 8 +- .../hcsshim/internal/gcs/container.go | 31 ++-- .../hcsshim/internal/gcs/guestconnection.go | 12 +- .../hcsshim/internal/gcs/iochannel.go | 4 + .../Microsoft/hcsshim/internal/gcs/process.go | 16 +- .../hcsshim/internal/gcs/protocol.go | 73 +++++---- .../Microsoft/hcsshim/internal/hcs/errors.go | 2 + .../Microsoft/hcsshim/internal/hcs/process.go | 50 ++++-- .../Microsoft/hcsshim/internal/hcs/system.go | 53 +++--- .../hcsshim/internal/hcsoci/create.go | 34 ++-- .../hcsshim/internal/hcsoci/devices.go | 3 +- .../hcsshim/internal/hcsoci/hcsdoc_lcow.go | 3 +- .../hcsshim/internal/hcsoci/hcsdoc_wcow.go | 12 +- .../hcsshim/internal/hcsoci/network.go | 18 +-- .../hcsshim/internal/hcsoci/resources.go | 2 +- .../hcsshim/internal/hcsoci/resources_lcow.go | 9 +- .../hcsshim/internal/hcsoci/resources_wcow.go | 12 +- .../hcsshim/internal/layers/layers.go | 43 +++-- .../Microsoft/hcsshim/internal/log/context.go | 139 ++++++++++++++++ .../Microsoft/hcsshim/internal/log/format.go | 89 ++++++++++ .../Microsoft/hcsshim/internal/log/g.go | 23 --- .../Microsoft/hcsshim/internal/log/scrub.go | 8 - .../hcsshim/internal/logfields/fields.go | 33 +++- .../Microsoft/hcsshim/internal/oc/errors.go | 58 +++++++ .../Microsoft/hcsshim/internal/oc/exporter.go | 61 ++++--- .../Microsoft/hcsshim/internal/oc/span.go | 35 +++- .../hcsshim/internal/resources/resources.go | 12 +- .../hcsshim/internal/uvm/computeagent.go | 21 ++- .../Microsoft/hcsshim/internal/uvm/create.go | 2 +- .../hcsshim/internal/uvm/create_lcow.go | 7 +- .../hcsshim/internal/uvm/create_wcow.go | 12 +- .../Microsoft/hcsshim/internal/uvm/network.go | 14 +- .../Microsoft/hcsshim/internal/uvm/plan9.go | 27 +++- .../Microsoft/hcsshim/internal/uvm/start.go | 2 +- .../Microsoft/hcsshim/internal/uvm/vsmb.go | 36 ++++- .../hcsshim/internal/vmcompute/vmcompute.go | 57 +++---- .../hcsshim/internal/wclayer/activatelayer.go | 2 +- .../hcsshim/internal/wclayer/createlayer.go | 2 +- .../internal/wclayer/createscratchlayer.go | 2 +- .../internal/wclayer/deactivatelayer.go | 2 +- .../hcsshim/internal/wclayer/destroylayer.go | 2 +- .../internal/wclayer/expandscratchsize.go | 2 +- .../hcsshim/internal/wclayer/exportlayer.go | 4 +- .../internal/wclayer/getlayermountpath.go | 2 +- .../internal/wclayer/getsharedbaseimages.go | 2 +- .../hcsshim/internal/wclayer/grantvmaccess.go | 2 +- .../hcsshim/internal/wclayer/importlayer.go | 4 +- .../hcsshim/internal/wclayer/layerexists.go | 2 +- .../hcsshim/internal/wclayer/layerid.go | 2 +- .../hcsshim/internal/wclayer/nametoguid.go | 2 +- .../hcsshim/internal/wclayer/preparelayer.go | 2 +- .../hcsshim/internal/wclayer/processimage.go | 4 +- .../internal/wclayer/unpreparelayer.go | 2 +- .../hcsshim/pkg/octtrpc/interceptor.go | 6 +- 180 files changed, 2462 insertions(+), 902 deletions(-) create mode 100644 internal/log/context.go create mode 100644 internal/log/format.go delete mode 100644 internal/log/g.go create mode 100644 internal/log/hook.go create mode 100644 internal/oc/errors.go create mode 100644 test/vendor/github.com/Microsoft/hcsshim/internal/log/context.go create mode 100644 test/vendor/github.com/Microsoft/hcsshim/internal/log/format.go delete mode 100644 test/vendor/github.com/Microsoft/hcsshim/internal/log/g.go create mode 100644 test/vendor/github.com/Microsoft/hcsshim/internal/oc/errors.go diff --git a/cmd/containerd-shim-runhcs-v1/delete.go b/cmd/containerd-shim-runhcs-v1/delete.go index 3fc4447c68..cb8d5075dd 100644 --- a/cmd/containerd-shim-runhcs-v1/delete.go +++ b/cmd/containerd-shim-runhcs-v1/delete.go @@ -18,7 +18,6 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli" - "go.opencensus.io/trace" ) // LimitedRead reads at max `readLimitBytes` bytes from the file at path `filePath`. If the file has @@ -56,7 +55,7 @@ The delete command will be executed in the container's bundle as its cwd. // task.DeleteResponse by protocol. We can write to stderr which will be // logged as a warning in containerd. - ctx, span := trace.StartSpan(gcontext.Background(), "delete") + ctx, span := oc.StartSpan(gcontext.Background(), "delete") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/cmd/containerd-shim-runhcs-v1/events.go b/cmd/containerd-shim-runhcs-v1/events.go index 71ec3efdc6..b603afe38c 100644 --- a/cmd/containerd-shim-runhcs-v1/events.go +++ b/cmd/containerd-shim-runhcs-v1/events.go @@ -4,8 +4,8 @@ package main import ( "context" - "fmt" + "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/oc" "github.com/containerd/containerd/namespaces" shim "github.com/containerd/containerd/runtime/v2/shim" @@ -39,12 +39,12 @@ func (e *eventPublisher) close() error { } func (e *eventPublisher) publishEvent(ctx context.Context, topic string, event interface{}) (err error) { - ctx, span := trace.StartSpan(ctx, "publishEvent") + ctx, span := oc.StartSpan(ctx, "publishEvent") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( trace.StringAttribute("topic", topic), - trace.StringAttribute("event", fmt.Sprintf("%+v", event))) + trace.StringAttribute("event", log.Format(ctx, event))) if e == nil { return nil diff --git a/cmd/containerd-shim-runhcs-v1/exec_clone.go b/cmd/containerd-shim-runhcs-v1/exec_clone.go index f2c2ce03ff..57f61ac832 100644 --- a/cmd/containerd-shim-runhcs-v1/exec_clone.go +++ b/cmd/containerd-shim-runhcs-v1/exec_clone.go @@ -8,9 +8,12 @@ import ( "github.com/Microsoft/hcsshim/internal/cmd" "github.com/Microsoft/hcsshim/internal/cow" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/uvm" "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" ) func newClonedExec( @@ -27,7 +30,7 @@ func newClonedExec( "tid": tid, "eid": id, // Init exec ID is always same as Task ID "bundle": bundle, - }).Debug("newClonedExec") + }).Trace("newClonedExec") he := &hcsExec{ events: events, @@ -63,6 +66,12 @@ type clonedExec struct { } func (ce *clonedExec) Start(ctx context.Context) (err error) { + ctx, span := oc.StartSpan(ctx, "clonedExec::Start") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, ce.tid), + trace.StringAttribute(logfields.ExecID, ce.id)) + // A cloned exec should never initialize the container as it should // already be running. return ce.startInternal(ctx, false) diff --git a/cmd/containerd-shim-runhcs-v1/exec_hcs.go b/cmd/containerd-shim-runhcs-v1/exec_hcs.go index ffad91cb5a..911fafb21b 100644 --- a/cmd/containerd-shim-runhcs-v1/exec_hcs.go +++ b/cmd/containerd-shim-runhcs-v1/exec_hcs.go @@ -20,6 +20,8 @@ import ( "github.com/Microsoft/hcsshim/internal/cmd" "github.com/Microsoft/hcsshim/internal/cow" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" "github.com/Microsoft/hcsshim/internal/signals" "github.com/Microsoft/hcsshim/internal/uvm" @@ -45,7 +47,7 @@ func newHcsExec( "eid": id, // Init exec ID is always same as Task ID "bundle": bundle, "wcow": isWCOW, - }).Debug("newHcsExec") + }).Trace("newHcsExec") he := &hcsExec{ events: events, @@ -251,12 +253,24 @@ func (he *hcsExec) startInternal(ctx context.Context, initializeContainer bool) } func (he *hcsExec) Start(ctx context.Context) (err error) { + ctx, span := oc.StartSpan(ctx, "hcsExec::Start") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, he.tid), + trace.StringAttribute(logfields.ExecID, he.id)) + // If he.id == he.tid then this is the init exec. // We need to initialize the container itself before starting this exec. return he.startInternal(ctx, he.id == he.tid) } -func (he *hcsExec) Kill(ctx context.Context, signal uint32) error { +func (he *hcsExec) Kill(ctx context.Context, signal uint32) (err error) { + ctx, span := oc.StartSpan(ctx, "hcsExec::Kill") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, he.tid), + trace.StringAttribute(logfields.ExecID, he.id)) + he.sl.Lock() defer he.sl.Unlock() switch he.state { @@ -269,7 +283,6 @@ func (he *hcsExec) Kill(ctx context.Context, signal uint32) error { supported = he.host == nil || he.host.SignalProcessSupported() } var options interface{} - var err error if he.isWCOW { var opt *guestresource.SignalProcessOptionsWCOW opt, err = signals.ValidateWCOW(int(signal), supported) @@ -309,6 +322,14 @@ func (he *hcsExec) Kill(ctx context.Context, signal uint32) error { } func (he *hcsExec) ResizePty(ctx context.Context, width, height uint32) error { + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.TaskID: he.tid, + logfields.ExecID: he.id, + "width": width, + "height": height, + }) + etr.Trace("hcsExec::ResizePty") + he.sl.Lock() defer he.sl.Unlock() if !he.io.Terminal() { @@ -322,6 +343,11 @@ func (he *hcsExec) ResizePty(ctx context.Context, width, height uint32) error { } func (he *hcsExec) CloseIO(ctx context.Context, stdin bool) error { + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.TaskID: he.tid, + logfields.ExecID: he.id, + }) + etr.Trace("hcsExec::CloseIO") // If we have any upstream IO we close the upstream connection. This will // unblock the `io.Copy` in the `Start()` call which will signal // `he.p.CloseStdin()`. If `he.io.Stdin()` is already closed this is safe to @@ -336,6 +362,13 @@ func (he *hcsExec) Wait() *task.StateResponse { } func (he *hcsExec) ForceExit(ctx context.Context, status int) { + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.TaskID: he.tid, + logfields.ExecID: he.id, + "status": status, + }) + etr.Trace("hcsExec::ForceExit") + he.sl.Lock() defer he.sl.Unlock() if he.state != shimExecStateExited { @@ -371,10 +404,15 @@ func (he *hcsExec) ForceExit(ctx context.Context, status int) { // We DO NOT send the async `TaskExit` event because we never would have sent // the `TaskStart`/`TaskExecStarted` event. func (he *hcsExec) exitFromCreatedL(ctx context.Context, status int) { - if he.state != shimExecStateExited { - // Avoid logging the force if we already exited gracefully - log.G(ctx).WithField("status", status).Debug("hcsExec::exitFromCreatedL") + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.TaskID: he.tid, + logfields.ExecID: he.id, + "status": status, + "state": he.state, + }) + etr.Trace("hcsExec::exitFromCreatedL") + if he.state != shimExecStateExited { // Unblock the container exit goroutine he.processDoneOnce.Do(func() { close(he.processDone) }) // Transition this exec @@ -416,13 +454,15 @@ func (he *hcsExec) exitFromCreatedL(ctx context.Context, status int) { // // 7. Finally, save the UVM and this container as a template if specified. func (he *hcsExec) waitForExit() { - ctx, span := trace.StartSpan(context.Background(), "hcsExec::waitForExit") + ctx, span := oc.StartSpan(context.Background(), "hcsExec::waitForExit") + var err error // this will only save the last error, since we dont return early on error defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( trace.StringAttribute("tid", he.tid), trace.StringAttribute("eid", he.id)) - err := he.p.Process.Wait() + err = he.p.Process.Wait() if err != nil { log.G(ctx).WithError(err).Error("failed process Wait") } @@ -433,9 +473,11 @@ func (he *hcsExec) waitForExit() { code, err := he.p.Process.ExitCode() if err != nil { - log.G(ctx).WithError(err).Error("failed to get ExitCode") + log.G(ctx).WithError(err).WithField(logfields.ExecID, he.id).Error("failed to get hcsExec ExitCode") } else { - log.G(ctx).WithField("exitCode", code).Debug("exited") + log.G(ctx).WithFields(logrus.Fields{ + "exitCode": code, + logfields.ExecID: he.id}).Debug("hcsExec exited") } he.sl.Lock() @@ -478,7 +520,7 @@ func (he *hcsExec) waitForExit() { // // This MUST be called via a goroutine at exec create. func (he *hcsExec) waitForContainerExit() { - ctx, span := trace.StartSpan(context.Background(), "hcsExec::waitForContainerExit") + ctx, span := oc.StartSpan(context.Background(), "hcsExec::waitForContainerExit") defer span.End() span.AddAttributes( trace.StringAttribute("tid", he.tid), diff --git a/cmd/containerd-shim-runhcs-v1/exec_wcow_podsandbox.go b/cmd/containerd-shim-runhcs-v1/exec_wcow_podsandbox.go index 466cdb8b91..a47b25d23e 100644 --- a/cmd/containerd-shim-runhcs-v1/exec_wcow_podsandbox.go +++ b/cmd/containerd-shim-runhcs-v1/exec_wcow_podsandbox.go @@ -8,6 +8,7 @@ import ( "time" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" eventstypes "github.com/containerd/containerd/api/events" containerd_v1_types "github.com/containerd/containerd/api/types/task" "github.com/containerd/containerd/errdefs" @@ -22,7 +23,7 @@ func newWcowPodSandboxExec(ctx context.Context, events publisher, tid, bundle st "tid": tid, "eid": tid, // Init exec ID is always same as Task ID "bundle": bundle, - }).Debug("newWcowPodSandboxExec") + }).Trace("newWcowPodSandboxExec") wpse := &wcowPodSandboxExec{ events: events, @@ -123,6 +124,11 @@ func (wpse *wcowPodSandboxExec) Status() *task.StateResponse { } func (wpse *wcowPodSandboxExec) Start(ctx context.Context) error { + log.G(ctx).WithFields(logrus.Fields{ + logfields.TaskID: wpse.tid, + logfields.ExecID: wpse.tid, + }).Trace("wcowPodSandboxExec::Start") + wpse.sl.Lock() defer wpse.sl.Unlock() if wpse.state != shimExecStateCreated { @@ -144,6 +150,12 @@ func (wpse *wcowPodSandboxExec) Start(ctx context.Context) error { } func (wpse *wcowPodSandboxExec) Kill(ctx context.Context, signal uint32) error { + log.G(ctx).WithFields(logrus.Fields{ + logfields.TaskID: wpse.tid, + logfields.ExecID: wpse.tid, + "signal": signal, + }).Trace("wcowPodSandboxExec::Kill") + wpse.sl.Lock() defer wpse.sl.Unlock() switch wpse.state { @@ -172,6 +184,12 @@ func (wpse *wcowPodSandboxExec) Kill(ctx context.Context, signal uint32) error { } func (wpse *wcowPodSandboxExec) ResizePty(ctx context.Context, width, height uint32) error { + // useless function, but trace could help track down who is calling it + log.G(ctx).WithFields(logrus.Fields{ + logfields.TaskID: wpse.tid, + logfields.ExecID: wpse.tid, + }).Trace("wcowPodSandboxExec::ResizePty") + wpse.sl.Lock() defer wpse.sl.Unlock() // We will never have IO for a sandbox container so we wont have a tty @@ -189,11 +207,18 @@ func (wpse *wcowPodSandboxExec) Wait() *task.StateResponse { } func (wpse *wcowPodSandboxExec) ForceExit(ctx context.Context, status int) { + ctx, etr := log.S(ctx, logrus.Fields{ //nolint:ineffassign,staticcheck + logfields.TaskID: wpse.tid, + logfields.ExecID: wpse.tid, + "status": status, + }) + etr.Trace("wcowPodSandboxExec::ForceExit") + wpse.sl.Lock() defer wpse.sl.Unlock() if wpse.state != shimExecStateExited { // Avoid logging the force if we already exited gracefully - log.G(ctx).WithField("status", status).Debug("wcowPodSandboxExec::ForceExit") + etr.WithField("status", status).Debug("forcing exit") wpse.state = shimExecStateExited wpse.exitStatus = 1 diff --git a/cmd/containerd-shim-runhcs-v1/main.go b/cmd/containerd-shim-runhcs-v1/main.go index f64d93ec30..1f7870b702 100644 --- a/cmd/containerd-shim-runhcs-v1/main.go +++ b/cmd/containerd-shim-runhcs-v1/main.go @@ -13,6 +13,7 @@ import ( "github.com/Microsoft/go-winio/pkg/etw" "github.com/Microsoft/go-winio/pkg/etwlogrus" "github.com/Microsoft/go-winio/pkg/guid" + "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/shimdiag" specs "github.com/opencontainers/runtime-spec/specs-go" @@ -64,13 +65,15 @@ func etwCallback(sourceID guid.GUID, state etw.ProviderState, level etw.Level, m } func main() { + logrus.AddHook(log.NewHook()) + // Provider ID: 0b52781f-b24d-5685-ddf6-69830ed40ec3 // Provider and hook aren't closed explicitly, as they will exist until process exit. provider, err := etw.NewProvider("Microsoft.Virtualization.RunHCS", etwCallback) if err != nil { logrus.Error(err) } else { - if hook, err := etwlogrus.NewHookFromProvider(provider); err == nil { + if hook, err := etwlogrus.NewHookFromProvider(provider, etwlogrus.WithGetName(oc.GetSpanName)); err == nil { logrus.AddHook(hook) } else { logrus.Error(err) @@ -86,7 +89,7 @@ func main() { ) // Register our OpenCensus logrus exporter - trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) + trace.ApplyConfig(trace.Config{DefaultSampler: oc.DefaultSampler}) trace.RegisterExporter(&oc.LogrusExporter{}) app := cli.NewApp() diff --git a/cmd/containerd-shim-runhcs-v1/pod.go b/cmd/containerd-shim-runhcs-v1/pod.go index 5069f4014b..8461696f7b 100644 --- a/cmd/containerd-shim-runhcs-v1/pod.go +++ b/cmd/containerd-shim-runhcs-v1/pod.go @@ -10,6 +10,8 @@ import ( "sync" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/oci" "github.com/Microsoft/hcsshim/internal/uvm" "github.com/Microsoft/hcsshim/osversion" @@ -20,6 +22,7 @@ import ( "github.com/containerd/containerd/runtime/v2/task" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" + "go.opencensus.io/trace" "golang.org/x/sync/errgroup" ) @@ -64,7 +67,10 @@ type shimPod interface { } func createPod(ctx context.Context, events publisher, req *task.CreateTaskRequest, s *specs.Spec) (_ shimPod, err error) { - log.G(ctx).WithField("tid", req.ID).Debug("createPod") + ctx, span := oc.StartSpan(ctx, "createPod") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute("tid", req.ID)) if osversion.Build() < osversion.RS5 { return nil, errors.Wrapf(errdefs.ErrFailedPrecondition, "pod support is not available on Windows versions previous to RS5 (%d)", osversion.RS5) @@ -288,6 +294,8 @@ func (p *pod) ID() string { } func (p *pod) GetCloneAnnotations(ctx context.Context, s *specs.Spec) (bool, string, error) { + log.G(ctx).WithField(logfields.TaskID, p.id).Trace("pod::GetCloneAnnotations") + isTemplate, templateID, err := oci.ParseCloneAnnotations(ctx, s) if err != nil { return false, "", err @@ -298,6 +306,11 @@ func (p *pod) GetCloneAnnotations(ctx context.Context, s *specs.Spec) (bool, str } func (p *pod) CreateTask(ctx context.Context, req *task.CreateTaskRequest, s *specs.Spec) (_ shimTask, err error) { + ctx, span := oc.StartSpan(ctx, "pod::CreateTask") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, p.id)) + if req.ID == p.id { return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "task with id: '%s' already exists", req.ID) } @@ -373,7 +386,12 @@ func (p *pod) GetTask(tid string) (shimTask, error) { return raw.(shimTask), nil } -func (p *pod) KillTask(ctx context.Context, tid, eid string, signal uint32, all bool) error { +func (p *pod) KillTask(ctx context.Context, tid, eid string, signal uint32, all bool) (err error) { + ctx, span := oc.StartSpan(ctx, "pod::KillTask") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, p.id)) + t, err := p.GetTask(tid) if err != nil { return err diff --git a/cmd/containerd-shim-runhcs-v1/serve.go b/cmd/containerd-shim-runhcs-v1/serve.go index 9b1213b087..214ae5fdf9 100644 --- a/cmd/containerd-shim-runhcs-v1/serve.go +++ b/cmd/containerd-shim-runhcs-v1/serve.go @@ -23,11 +23,14 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli" + "go.opencensus.io/trace" "golang.org/x/sys/windows" runhcsopts "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options" "github.com/Microsoft/hcsshim/internal/extendedtask" hcslog "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/shimdiag" "github.com/Microsoft/hcsshim/pkg/octtrpc" ) @@ -48,7 +51,7 @@ var serveCommand = cli.Command{ Usage: "is the task id a Kubernetes sandbox id", }, }, - Action: func(ctx *cli.Context) error { + Action: func(ctx *cli.Context) (err error) { // On Windows the serve command is internally used to actually create // the process that hosts the containerd/ttrpc entrypoint to the Runtime // V2 API's. The model requires this 2nd invocation of the shim process @@ -71,6 +74,20 @@ var serveCommand = cli.Command{ // the events. var lerrs chan error + // TODO: use a context WithCancel() context and defer the cancellation + // after verying that canceling context/service won't prematurely bring + // down service and cleanup in background go-routines + cctx, span := oc.StartSpan(context.Background(), ctx.App.Name+"::serve") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.BoolAttribute("isSandbox", ctx.Bool("is-sandbox")), + trace.StringAttribute("namespace", namespaceFlag), + trace.StringAttribute("address", addressFlag), + trace.StringAttribute("binary", containerdBinaryFlag), + trace.StringAttribute("socket", ctx.String("socket")), + trace.StringAttribute("id", idFlag), + ) // Default values for shim options. shimOpts := &runhcsopts.Options{ @@ -79,6 +96,7 @@ var serveCommand = cli.Command{ } // containerd passes the shim options protobuf via stdin. + // todo: merge defaults, above, with passed in opts newShimOpts, err := readOptions(os.Stdin) if err != nil { return errors.Wrap(err, "failed to read shim options from stdin") @@ -88,24 +106,24 @@ var serveCommand = cli.Command{ } if shimOpts.Debug && shimOpts.LogLevel != "" { - logrus.Warning("Both Debug and LogLevel specified, Debug will be overridden") + hcslog.G(cctx).Warning("Both 'Debug' and 'LogLevel' specified; 'Debug' will be overridden") } + lvl := logrus.GetLevel() // For now keep supporting the debug option, this used to be the only way to specify a different logging // level for the shim. if shimOpts.Debug { - logrus.SetLevel(logrus.DebugLevel) + lvl = logrus.DebugLevel } - // If log level is specified, set the corresponding logrus logging level. This overrides the debug option // (unless the level being asked for IS debug also, then this doesn't do much). if shimOpts.LogLevel != "" { - lvl, err := logrus.ParseLevel(shimOpts.LogLevel) + lvl, err = logrus.ParseLevel(shimOpts.LogLevel) if err != nil { return errors.Wrapf(err, "failed to parse shim log level %q", shimOpts.LogLevel) } - logrus.SetLevel(lvl) } + logrus.SetLevel(lvl) switch shimOpts.DebugType { case runhcsopts.Options_NPIPE: @@ -166,6 +184,9 @@ var serveCommand = cli.Command{ if shimOpts.ScrubLogs { hcslog.SetScrubbing(true) } + hcslog.G(cctx). + WithField(logfields.Options, shimOpts). + Debug("shim options") // Force the cli.ErrWriter to be os.Stdout for this. We use stderr for // the panic.log attached via start. @@ -216,7 +237,7 @@ var serveCommand = cli.Command{ // Serve loops infinitely unless s.Shutdown or s.Close are called. // Passed in context is used as parent context for handling requests, // but canceliing does not bring down ttrpc service. - if err := trapClosedConnErr(s.Serve(context.Background(), sl)); err != nil { + if err := trapClosedConnErr(s.Serve(cctx, sl)); err != nil { logrus.WithError(err).Fatal("containerd-shim: ttrpc server failure") serrs <- err return @@ -231,12 +252,11 @@ var serveCommand = cli.Command{ return err case <-time.After(2 * time.Millisecond): // TODO: Contribute a change to ttrpc so that you can: - // - // go func () { errs <- s.Serve() } - // select { - // case <-errs: - // case <-s.Ready(): - // } + // go func () { errs <- s.Serve() } + // select { + // case <-errs: + // case <-s.Ready(): + // } // This is our best indication that we have not errored on creation // and are successfully serving the API. diff --git a/cmd/containerd-shim-runhcs-v1/service.go b/cmd/containerd-shim-runhcs-v1/service.go index 92abc70a5c..26169881d3 100644 --- a/cmd/containerd-shim-runhcs-v1/service.go +++ b/cmd/containerd-shim-runhcs-v1/service.go @@ -12,6 +12,7 @@ import ( "time" "github.com/Microsoft/hcsshim/internal/extendedtask" + "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/shimdiag" "github.com/containerd/containerd/errdefs" @@ -98,14 +99,14 @@ func NewService(o ...ServiceOption) (svc *service, err error) { } func (s *service) State(ctx context.Context, req *task.StateRequest) (resp *task.StateResponse, err error) { - ctx, span := trace.StartSpan(ctx, "State") + ctx, span := oc.StartSpan(ctx, "State") defer span.End() defer func() { if resp != nil { span.AddAttributes( trace.StringAttribute("status", resp.Status.String()), trace.Int64Attribute("exitStatus", int64(resp.ExitStatus)), - trace.StringAttribute("exitedAt", resp.ExitedAt.String())) + trace.StringAttribute("exitedAt", resp.ExitedAt.Format(time.RFC3339Nano))) } oc.SetSpanStatus(span, err) }() @@ -123,7 +124,7 @@ func (s *service) State(ctx context.Context, req *task.StateRequest) (resp *task } func (s *service) Create(ctx context.Context, req *task.CreateTaskRequest) (resp *task.CreateTaskResponse, err error) { - ctx, span := trace.StartSpan(ctx, "Create") + ctx, span := oc.StartSpan(ctx, "Create") defer span.End() defer func() { if resp != nil { @@ -135,8 +136,7 @@ func (s *service) Create(ctx context.Context, req *task.CreateTaskRequest) (resp span.AddAttributes( trace.StringAttribute("tid", req.ID), trace.StringAttribute("bundle", req.Bundle), - // trace.StringAttribute("rootfs", req.Rootfs), TODO: JTERRY75 - - // OpenCensus doesnt support slice like our logrus hook + trace.StringAttribute("rootfs", log.Format(ctx, req.Rootfs)), trace.BoolAttribute("terminal", req.Terminal), trace.StringAttribute("stdin", req.Stdin), trace.StringAttribute("stdout", req.Stdout), @@ -153,7 +153,7 @@ func (s *service) Create(ctx context.Context, req *task.CreateTaskRequest) (resp } func (s *service) Start(ctx context.Context, req *task.StartRequest) (resp *task.StartResponse, err error) { - ctx, span := trace.StartSpan(ctx, "Start") + ctx, span := oc.StartSpan(ctx, "Start") defer span.End() defer func() { if resp != nil { @@ -175,14 +175,14 @@ func (s *service) Start(ctx context.Context, req *task.StartRequest) (resp *task } func (s *service) Delete(ctx context.Context, req *task.DeleteRequest) (resp *task.DeleteResponse, err error) { - ctx, span := trace.StartSpan(ctx, "Delete") + ctx, span := oc.StartSpan(ctx, "Delete") defer span.End() defer func() { if resp != nil { span.AddAttributes( trace.Int64Attribute("pid", int64(resp.Pid)), trace.Int64Attribute("exitStatus", int64(resp.ExitStatus)), - trace.StringAttribute("exitedAt", resp.ExitedAt.String())) + trace.StringAttribute("exitedAt", resp.ExitedAt.Format(time.RFC3339Nano))) } oc.SetSpanStatus(span, err) }() @@ -200,7 +200,7 @@ func (s *service) Delete(ctx context.Context, req *task.DeleteRequest) (resp *ta } func (s *service) Pids(ctx context.Context, req *task.PidsRequest) (_ *task.PidsResponse, err error) { - ctx, span := trace.StartSpan(ctx, "Pids") + ctx, span := oc.StartSpan(ctx, "Pids") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -215,7 +215,7 @@ func (s *service) Pids(ctx context.Context, req *task.PidsRequest) (_ *task.Pids } func (s *service) Pause(ctx context.Context, req *task.PauseRequest) (_ *google_protobuf1.Empty, err error) { - ctx, span := trace.StartSpan(ctx, "Pause") + ctx, span := oc.StartSpan(ctx, "Pause") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -230,7 +230,7 @@ func (s *service) Pause(ctx context.Context, req *task.PauseRequest) (_ *google_ } func (s *service) Resume(ctx context.Context, req *task.ResumeRequest) (_ *google_protobuf1.Empty, err error) { - ctx, span := trace.StartSpan(ctx, "Resume") + ctx, span := oc.StartSpan(ctx, "Resume") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -245,7 +245,7 @@ func (s *service) Resume(ctx context.Context, req *task.ResumeRequest) (_ *googl } func (s *service) Checkpoint(ctx context.Context, req *task.CheckpointTaskRequest) (_ *google_protobuf1.Empty, err error) { - ctx, span := trace.StartSpan(ctx, "Checkpoint") + ctx, span := oc.StartSpan(ctx, "Checkpoint") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -262,7 +262,7 @@ func (s *service) Checkpoint(ctx context.Context, req *task.CheckpointTaskReques } func (s *service) Kill(ctx context.Context, req *task.KillRequest) (_ *google_protobuf1.Empty, err error) { - ctx, span := trace.StartSpan(ctx, "Kill") + ctx, span := oc.StartSpan(ctx, "Kill") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -281,7 +281,7 @@ func (s *service) Kill(ctx context.Context, req *task.KillRequest) (_ *google_pr } func (s *service) Exec(ctx context.Context, req *task.ExecProcessRequest) (_ *google_protobuf1.Empty, err error) { - ctx, span := trace.StartSpan(ctx, "Exec") + ctx, span := oc.StartSpan(ctx, "Exec") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -302,7 +302,7 @@ func (s *service) Exec(ctx context.Context, req *task.ExecProcessRequest) (_ *go } func (s *service) DiagExecInHost(ctx context.Context, req *shimdiag.ExecProcessRequest) (_ *shimdiag.ExecProcessResponse, err error) { - ctx, span := trace.StartSpan(ctx, "DiagExecInHost") + ctx, span := oc.StartSpan(ctx, "DiagExecInHost") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -323,7 +323,7 @@ func (s *service) DiagExecInHost(ctx context.Context, req *shimdiag.ExecProcessR } func (s *service) DiagShare(ctx context.Context, req *shimdiag.ShareRequest) (_ *shimdiag.ShareResponse, err error) { - ctx, span := trace.StartSpan(ctx, "DiagShare") + ctx, span := oc.StartSpan(ctx, "DiagShare") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -341,7 +341,7 @@ func (s *service) DiagShare(ctx context.Context, req *shimdiag.ShareRequest) (_ } func (s *service) ResizePty(ctx context.Context, req *task.ResizePtyRequest) (_ *google_protobuf1.Empty, err error) { - ctx, span := trace.StartSpan(ctx, "ResizePty") + ctx, span := oc.StartSpan(ctx, "ResizePty") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -360,7 +360,7 @@ func (s *service) ResizePty(ctx context.Context, req *task.ResizePtyRequest) (_ } func (s *service) CloseIO(ctx context.Context, req *task.CloseIORequest) (_ *google_protobuf1.Empty, err error) { - ctx, span := trace.StartSpan(ctx, "CloseIO") + ctx, span := oc.StartSpan(ctx, "CloseIO") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -378,7 +378,7 @@ func (s *service) CloseIO(ctx context.Context, req *task.CloseIORequest) (_ *goo } func (s *service) Update(ctx context.Context, req *task.UpdateTaskRequest) (_ *google_protobuf1.Empty, err error) { - ctx, span := trace.StartSpan(ctx, "Update") + ctx, span := oc.StartSpan(ctx, "Update") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -393,13 +393,13 @@ func (s *service) Update(ctx context.Context, req *task.UpdateTaskRequest) (_ *g } func (s *service) Wait(ctx context.Context, req *task.WaitRequest) (resp *task.WaitResponse, err error) { - ctx, span := trace.StartSpan(ctx, "Wait") + ctx, span := oc.StartSpan(ctx, "Wait") defer span.End() defer func() { if resp != nil { span.AddAttributes( trace.Int64Attribute("exitStatus", int64(resp.ExitStatus)), - trace.StringAttribute("exitedAt", resp.ExitedAt.String())) + trace.StringAttribute("exitedAt", resp.ExitedAt.Format(time.RFC3339Nano))) } oc.SetSpanStatus(span, err) }() @@ -417,7 +417,7 @@ func (s *service) Wait(ctx context.Context, req *task.WaitRequest) (resp *task.W } func (s *service) Stats(ctx context.Context, req *task.StatsRequest) (_ *task.StatsResponse, err error) { - ctx, span := trace.StartSpan(ctx, "Stats") + ctx, span := oc.StartSpan(ctx, "Stats") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -432,7 +432,7 @@ func (s *service) Stats(ctx context.Context, req *task.StatsRequest) (_ *task.St } func (s *service) Connect(ctx context.Context, req *task.ConnectRequest) (resp *task.ConnectResponse, err error) { - ctx, span := trace.StartSpan(ctx, "Connect") + ctx, span := oc.StartSpan(ctx, "Connect") defer span.End() defer func() { if resp != nil { @@ -455,11 +455,12 @@ func (s *service) Connect(ctx context.Context, req *task.ConnectRequest) (resp * } func (s *service) Shutdown(ctx context.Context, req *task.ShutdownRequest) (_ *google_protobuf1.Empty, err error) { - ctx, span := trace.StartSpan(ctx, "Shutdown") + ctx, span := oc.StartSpan(ctx, "Shutdown") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("tid", req.ID)) + span.AddAttributes(trace.StringAttribute("tid", req.ID), + trace.BoolAttribute("now", req.Now)) if s.isSandbox { span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) @@ -473,7 +474,7 @@ func (s *service) DiagStacks(ctx context.Context, req *shimdiag.StacksRequest) ( if s == nil { return nil, nil } - ctx, span := trace.StartSpan(ctx, "DiagStacks") + ctx, span := oc.StartSpan(ctx, "DiagStacks") defer span.End() span.AddAttributes(trace.StringAttribute("tid", s.tid)) @@ -505,7 +506,7 @@ func (s *service) DiagPid(ctx context.Context, req *shimdiag.PidRequest) (*shimd if s == nil { return nil, nil } - ctx, span := trace.StartSpan(ctx, "DiagPid") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "DiagPid") //nolint:ineffassign,staticcheck defer span.End() span.AddAttributes(trace.StringAttribute("tid", s.tid)) @@ -516,7 +517,7 @@ func (s *service) DiagPid(ctx context.Context, req *shimdiag.PidRequest) (*shimd } func (s *service) ComputeProcessorInfo(ctx context.Context, req *extendedtask.ComputeProcessorInfoRequest) (*extendedtask.ComputeProcessorInfoResponse, error) { - ctx, span := trace.StartSpan(ctx, "ComputeProcessorInfo") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "ComputeProcessorInfo") //nolint:ineffassign,staticcheck defer span.End() span.AddAttributes(trace.StringAttribute("tid", s.tid)) diff --git a/cmd/containerd-shim-runhcs-v1/task_hcs.go b/cmd/containerd-shim-runhcs-v1/task_hcs.go index 32f6a2055f..6b7a5dbc48 100644 --- a/cmd/containerd-shim-runhcs-v1/task_hcs.go +++ b/cmd/containerd-shim-runhcs-v1/task_hcs.go @@ -31,7 +31,9 @@ import ( "github.com/Microsoft/hcsshim/internal/hcsoci" "github.com/Microsoft/hcsshim/internal/jobcontainers" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/memory" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/oci" "github.com/Microsoft/hcsshim/internal/processorinfo" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" @@ -43,8 +45,9 @@ import ( "github.com/Microsoft/hcsshim/pkg/annotations" ) -func newHcsStandaloneTask(ctx context.Context, events publisher, req *task.CreateTaskRequest, s *specs.Spec) (shimTask, error) { - log.G(ctx).WithField("tid", req.ID).Debug("newHcsStandaloneTask") +func newHcsStandaloneTask(ctx context.Context, events publisher, req *task.CreateTaskRequest, s *specs.Spec) (_ shimTask, err error) { + ctx, entry := log.S(ctx, logrus.Fields{logfields.TaskID: req.ID}) + entry.Debug("newHcsStandaloneTask") ct, _, err := oci.GetSandboxTypeAndID(s.Annotations) if err != nil { @@ -117,12 +120,27 @@ func newHcsStandaloneTask(ctx context.Context, events publisher, req *task.Creat // createContainer is a generic call to return either a process/hypervisor isolated container, or a job container // based on what is set in the OCI spec. -func createContainer(ctx context.Context, id, owner, netNS string, s *specs.Spec, parent *uvm.UtilityVM, shimOpts *runhcsopts.Options) (cow.Container, *resources.Resources, error) { - var ( - err error - container cow.Container - resources *resources.Resources - ) +func createContainer( + ctx context.Context, + id, owner, netNS string, + s *specs.Spec, + parent *uvm.UtilityVM, + shimOpts *runhcsopts.Options) (container cow.Container, resources *resources.Resources, err error) { + ctx, span := oc.StartSpan(ctx, "createContainer") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute(logfields.ID, id), + trace.StringAttribute("owner", owner), + trace.StringAttribute("netNS", netNS)) + if parent != nil { + span.AddAttributes(trace.StringAttribute("parent", parent.ID())) + } + + log.G(ctx).WithFields(logrus.Fields{ + "spec": s, + "shimOptions": shimOpts, + }).Debug("createContainer options") if oci.IsJobContainer(s) { container, resources, err = jobcontainers.Create(ctx, id, s) @@ -159,10 +177,14 @@ func newHcsTask( ownsParent bool, req *task.CreateTaskRequest, s *specs.Spec) (_ shimTask, err error) { - log.G(ctx).WithFields(logrus.Fields{ - "tid": req.ID, - "ownsParent": ownsParent, - }).Debug("newHcsTask") + ctx, span := oc.StartSpan(ctx, "newHcsTask") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, req.ID), + trace.BoolAttribute("ownParent", ownsParent)) + if parent != nil { + span.AddAttributes(trace.StringAttribute("parent", parent.ID())) + } owner := filepath.Base(os.Args[0]) isTemplate := oci.ParseAnnotationsSaveAsTemplate(ctx, s) @@ -274,11 +296,15 @@ func newClonedHcsTask( req *task.CreateTaskRequest, s *specs.Spec, templateID string) (_ shimTask, err error) { - log.G(ctx).WithFields(logrus.Fields{ - "tid": req.ID, - "ownsParent": ownsParent, - "templateid": templateID, - }).Debug("newClonedHcsTask") + ctx, span := oc.StartSpan(ctx, "newClonedHcsTask") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, req.ID), + trace.BoolAttribute("ownParent", ownsParent), + trace.StringAttribute("templateID", templateID)) + if parent != nil { + span.AddAttributes(trace.StringAttribute("parent", parent.ID())) + } owner := filepath.Base(os.Args[0]) @@ -311,7 +337,14 @@ func newClonedHcsTask( netNS = s.Windows.Network.NetworkNamespace } - // This is a cloned task. Use the templateid as the ID of the container here + // cloneHcsTask doesnt rely on createContainer, so it doesnt log spec and shim options + log.G(ctx).WithFields(logrus.Fields{ + "netNS": netNS, + "spec": s, + "shimOptions": shimOpts, + }).Debug("newClonedHcsTask options") + + // This is a cloned task. Use the templateID as the ID of the container here // because that's the ID of this container inside the UVM. opts := hcsoci.CreateOptions{ ID: templateID, @@ -463,7 +496,13 @@ func (ht *hcsTask) ID() string { return ht.id } -func (ht *hcsTask) CreateExec(ctx context.Context, req *task.ExecProcessRequest, spec *specs.Process) error { +func (ht *hcsTask) CreateExec(ctx context.Context, req *task.ExecProcessRequest, spec *specs.Process) (err error) { + ctx, span := oc.StartSpan(ctx, "hcsTask::CreateExec") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, ht.id), + trace.StringAttribute(logfields.ExecID, req.ExecID)) + ht.ecl.Lock() defer ht.ecl.Unlock() @@ -518,7 +557,15 @@ func (ht *hcsTask) GetExec(eid string) (shimExec, error) { return raw.(shimExec), nil } -func (ht *hcsTask) KillExec(ctx context.Context, eid string, signal uint32, all bool) error { +func (ht *hcsTask) KillExec(ctx context.Context, eid string, signal uint32, all bool) (err error) { + ctx, span := oc.StartSpan(ctx, "hcsTask::KillExec") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, ht.id), + trace.StringAttribute(logfields.ExecID, eid), + trace.Int64Attribute("signal", int64(signal)), + trace.BoolAttribute("all", all)) + e, err := ht.GetExec(eid) if err != nil { return err @@ -567,7 +614,13 @@ func (ht *hcsTask) KillExec(ctx context.Context, eid string, signal uint32, all return e.Kill(ctx, signal) } -func (ht *hcsTask) DeleteExec(ctx context.Context, eid string) (int, uint32, time.Time, error) { +func (ht *hcsTask) DeleteExec(ctx context.Context, eid string) (_ int, _ uint32, _ time.Time, err error) { + ctx, span := oc.StartSpan(ctx, "hcsTask::DeleteExec") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, ht.id), + trace.StringAttribute(logfields.ExecID, eid)) + e, err := ht.GetExec(eid) if err != nil { return 0, 0, time.Time{}, err @@ -649,6 +702,9 @@ func (ht *hcsTask) DeleteExec(ctx context.Context, eid string) (int, uint32, tim } func (ht *hcsTask) Pids(ctx context.Context) ([]runhcsopts.ProcessDetails, error) { + ctx, etr := log.S(ctx, logrus.Fields{logfields.TaskID: ht.id}) + etr.Trace("hcsTask::Pids") + // Map all user created exec's to pid/exec-id pidMap := make(map[int]string) ht.execs.Range(func(key, value interface{}) bool { @@ -692,9 +748,10 @@ func (ht *hcsTask) Wait() *task.StateResponse { } func (ht *hcsTask) waitInitExit(destroyContainer bool) { - ctx, span := trace.StartSpan(context.Background(), "hcsTask::waitInitExit") + ctx, span := oc.StartSpan(context.Background(), "hcsTask::waitInitExit") defer span.End() - span.AddAttributes(trace.StringAttribute("tid", ht.id)) + span.AddAttributes(trace.StringAttribute("tid", ht.id), + trace.BoolAttribute("destroyContainer", destroyContainer)) // Wait for it to exit on its own ht.init.Wait() @@ -723,7 +780,7 @@ func (ht *hcsTask) waitInitExit(destroyContainer bool) { // Note: For Windows process isolated containers there is no host virtual // machine so this should not be called. func (ht *hcsTask) waitForHostExit() { - ctx, span := trace.StartSpan(context.Background(), "hcsTask::waitForHostExit") + ctx, span := oc.StartSpan(context.Background(), "hcsTask::waitForHostExit") defer span.End() span.AddAttributes(trace.StringAttribute("tid", ht.id)) @@ -752,9 +809,13 @@ func (ht *hcsTask) waitForHostExit() { // NOTE: For Windows process isolated containers `ht.ownsHost==true && ht.host // == nil`. func (ht *hcsTask) close(ctx context.Context) { - ht.closeOnce.Do(func() { - log.G(ctx).Debug("hcsTask::closeOnce") + ctx, span := oc.StartSpan(ctx, "hcsTask::closeOnce") + var err error // this will only save the last error, since we dont return early on error + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, ht.id)) + ht.closeOnce.Do(func() { // ht.c should never be nil for a real task but in testing we stub // this to avoid a nil dereference. We really should introduce a // method or interface for ht.c operations that we can stub for @@ -767,7 +828,7 @@ func (ht *hcsTask) close(ctx context.Context) { werr = ht.c.Wait() close(ch) }() - err := ht.c.Shutdown(ctx) + err = ht.c.Shutdown(ctx) if err != nil { log.G(ctx).WithError(err).Error("failed to shutdown container") } else { @@ -804,12 +865,12 @@ func (ht *hcsTask) close(ctx context.Context) { } // Release any resources associated with the container. - if err := resources.ReleaseResources(ctx, ht.cr, ht.host, true); err != nil { + if err = resources.ReleaseResources(ctx, ht.cr, ht.host, true); err != nil { log.G(ctx).WithError(err).Error("failed to release container resources") } // Close the container handle invalidating all future access. - if err := ht.c.Close(); err != nil { + if err = ht.c.Close(); err != nil { log.G(ctx).WithError(err).Error("failed to close container") } } @@ -825,18 +886,22 @@ func (ht *hcsTask) close(ctx context.Context) { // // This call is idempotent and safe to call multiple times. func (ht *hcsTask) closeHost(ctx context.Context) { - ht.closeHostOnce.Do(func() { - log.G(ctx).Debug("hcsTask::closeHostOnce") + ctx, span := oc.StartSpan(ctx, "hcsTask::closeHostOnce") + var err error // this will only save the last error, since we dont return early on error + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, ht.id)) + ht.closeHostOnce.Do(func() { if ht.ownsHost && ht.host != nil { - if err := ht.host.Close(); err != nil { + if err = ht.host.Close(); err != nil { log.G(ctx).WithError(err).Error("failed host vm shutdown") } } // Send the `init` exec exit notification always. exit := ht.init.Status() - if err := ht.events.publishEvent( + if err = ht.events.publishEvent( ctx, runtime.TaskExitEventTopic, &eventstypes.TaskExit{ @@ -853,6 +918,9 @@ func (ht *hcsTask) closeHost(ctx context.Context) { } func (ht *hcsTask) ExecInHost(ctx context.Context, req *shimdiag.ExecProcessRequest) (int, error) { + ctx, etr := log.S(ctx, logrus.Fields{logfields.TaskID: ht.id}) + etr.Trace("hcsTask::ExecInHost") + cmdReq := &cmd.CmdProcessRequest{ Args: req.Args, Workdir: req.Workdir, @@ -869,10 +937,13 @@ func (ht *hcsTask) ExecInHost(ctx context.Context, req *shimdiag.ExecProcessRequ } func (ht *hcsTask) DumpGuestStacks(ctx context.Context) string { + ctx, etr := log.S(ctx, logrus.Fields{logfields.TaskID: ht.id}) + etr.Trace("hcsTask::DumpGuestStacks") + if ht.host != nil { stacks, err := ht.host.DumpStacks(ctx) if err != nil { - log.G(ctx).WithError(err).Warn("failed to capture guest stacks") + etr.WithError(err).Warn("failed to capture guest stacks") } else { return stacks } @@ -881,6 +952,9 @@ func (ht *hcsTask) DumpGuestStacks(ctx context.Context) string { } func (ht *hcsTask) Share(ctx context.Context, req *shimdiag.ShareRequest) error { + ctx, etr := log.S(ctx, logrus.Fields{logfields.TaskID: ht.id}) + etr.Trace("hcsTask::Share") + if ht.host == nil { return errTaskNotIsolated } @@ -920,6 +994,9 @@ func hcsPropertiesToWindowsStats(props *hcsschema.Properties) *stats.Statistics_ } func (ht *hcsTask) Stats(ctx context.Context) (*stats.Statistics, error) { + ctx, etr := log.S(ctx, logrus.Fields{logfields.TaskID: ht.id}) + etr.Trace("hcsTask::Stats") + s := &stats.Statistics{} props, err := ht.c.PropertiesV2(ctx, hcsschema.PTStatistics) if err != nil { @@ -946,7 +1023,12 @@ func (ht *hcsTask) Stats(ctx context.Context) (*stats.Statistics, error) { return s, nil } -func (ht *hcsTask) Update(ctx context.Context, req *task.UpdateTaskRequest) error { +func (ht *hcsTask) Update(ctx context.Context, req *task.UpdateTaskRequest) (err error) { + ctx, span := oc.StartSpan(ctx, "hcsTask::Update") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, ht.id)) + resources, err := typeurl.UnmarshalAny(req.Resources) if err != nil { return errors.Wrapf(err, "failed to unmarshal resources for container %s update request", req.ID) diff --git a/cmd/containerd-shim-runhcs-v1/task_wcow_podsandbox.go b/cmd/containerd-shim-runhcs-v1/task_wcow_podsandbox.go index c99dea3483..ef611a0b2a 100644 --- a/cmd/containerd-shim-runhcs-v1/task_wcow_podsandbox.go +++ b/cmd/containerd-shim-runhcs-v1/task_wcow_podsandbox.go @@ -12,6 +12,8 @@ import ( "github.com/Microsoft/hcsshim/internal/clone" "github.com/Microsoft/hcsshim/internal/cmd" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/shimdiag" "github.com/Microsoft/hcsshim/internal/uvm" eventstypes "github.com/containerd/containerd/api/events" @@ -21,6 +23,7 @@ import ( "github.com/containerd/typeurl" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "go.opencensus.io/trace" ) @@ -33,7 +36,8 @@ import ( // `parent`. When the fake WCOW `init` process exits via `Signal` `parent` will // be forcibly closed by this task. func newWcowPodSandboxTask(ctx context.Context, events publisher, id, bundle string, parent *uvm.UtilityVM, nsid string) shimTask { - log.G(ctx).WithField("tid", id).Debug("newWcowPodSandboxTask") + ctx, etr := log.S(ctx, logrus.Fields{logfields.TaskID: id}) + etr.Trace("newWcowPodSandboxTask") wpst := &wcowPodSandboxTask{ events: events, @@ -110,7 +114,12 @@ func (wpst *wcowPodSandboxTask) GetExec(eid string) (shimExec, error) { return nil, errors.Wrapf(errdefs.ErrNotFound, "exec: '%s' in task: '%s' not found", eid, wpst.id) } -func (wpst *wcowPodSandboxTask) KillExec(ctx context.Context, eid string, signal uint32, all bool) error { +func (wpst *wcowPodSandboxTask) KillExec(ctx context.Context, eid string, signal uint32, all bool) (err error) { + ctx, span := oc.StartSpan(ctx, "wcowPodSandboxTask::KillExec") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, wpst.id)) + e, err := wpst.GetExec(eid) if err != nil { return err @@ -125,7 +134,12 @@ func (wpst *wcowPodSandboxTask) KillExec(ctx context.Context, eid string, signal return nil } -func (wpst *wcowPodSandboxTask) DeleteExec(ctx context.Context, eid string) (int, uint32, time.Time, error) { +func (wpst *wcowPodSandboxTask) DeleteExec(ctx context.Context, eid string) (_ int, _ uint32, _ time.Time, err error) { + ctx, span := oc.StartSpan(ctx, "wcowPodSandboxTask::DeleteExec") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, wpst.id)) + e, err := wpst.GetExec(eid) if err != nil { return 0, 0, time.Time{}, err @@ -156,6 +170,8 @@ func (wpst *wcowPodSandboxTask) DeleteExec(ctx context.Context, eid string) (int } func (wpst *wcowPodSandboxTask) Pids(ctx context.Context) ([]options.ProcessDetails, error) { + log.G(ctx).WithField(logfields.TaskID, wpst.id).Trace("wcowPodSandboxTask::Pids") + return []options.ProcessDetails{ { ProcessID: uint32(wpst.init.Pid()), @@ -176,26 +192,30 @@ func (wpst *wcowPodSandboxTask) Wait() *task.StateResponse { // // This call is idempotent and safe to call multiple times. func (wpst *wcowPodSandboxTask) close(ctx context.Context) { - wpst.closeOnce.Do(func() { - log.G(ctx).Debug("wcowPodSandboxTask::closeOnce") + ctx, span := oc.StartSpan(ctx, "wcowPodSandboxTask::closeOnce") + var err error // this will only save the last error, since we dont return early on error + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, wpst.id)) + wpst.closeOnce.Do(func() { if wpst.host != nil { - if err := wpst.host.TearDownNetworking(ctx, wpst.nsid); err != nil { + if err = wpst.host.TearDownNetworking(ctx, wpst.nsid); err != nil { log.G(ctx).WithError(err).Error("failed to cleanup networking for utility VM") } - if err := wpst.host.Close(); err != nil { + if err = wpst.host.Close(); err != nil { log.G(ctx).WithError(err).Error("failed host vm shutdown") } // cleanup template state if any exists - if err := clone.RemoveSavedTemplateConfig(wpst.host.ID()); err != nil { + if err = clone.RemoveSavedTemplateConfig(wpst.host.ID()); err != nil { log.G(ctx).WithError(err).Error("failed to cleanup template config state for vm") } } // Send the `init` exec exit notification always. exit := wpst.init.Status() - if err := wpst.events.publishEvent( + if err = wpst.events.publishEvent( ctx, runtime.TaskExitEventTopic, &eventstypes.TaskExit{ @@ -212,7 +232,7 @@ func (wpst *wcowPodSandboxTask) close(ctx context.Context) { } func (wpst *wcowPodSandboxTask) waitInitExit() { - ctx, span := trace.StartSpan(context.Background(), "wcowPodSandboxTask::waitInitExit") + ctx, span := oc.StartSpan(context.Background(), "wcowPodSandboxTask::waitInitExit") defer span.End() span.AddAttributes(trace.StringAttribute("tid", wpst.id)) @@ -224,7 +244,7 @@ func (wpst *wcowPodSandboxTask) waitInitExit() { } func (wpst *wcowPodSandboxTask) waitParentExit() { - ctx, span := trace.StartSpan(context.Background(), "wcowPodSandboxTask::waitParentExit") + ctx, span := oc.StartSpan(context.Background(), "wcowPodSandboxTask::waitParentExit") defer span.End() span.AddAttributes(trace.StringAttribute("tid", wpst.id)) @@ -242,6 +262,9 @@ func (wpst *wcowPodSandboxTask) waitParentExit() { } func (wpst *wcowPodSandboxTask) ExecInHost(ctx context.Context, req *shimdiag.ExecProcessRequest) (int, error) { + ctx, etr := log.S(ctx, logrus.Fields{logfields.TaskID: wpst.id}) + etr.Trace("wcowPodSandboxTask::ExecInHost") + cmdReq := &cmd.CmdProcessRequest{ Args: req.Args, Workdir: req.Workdir, @@ -257,6 +280,9 @@ func (wpst *wcowPodSandboxTask) ExecInHost(ctx context.Context, req *shimdiag.Ex } func (wpst *wcowPodSandboxTask) DumpGuestStacks(ctx context.Context) string { + ctx, etr := log.S(ctx, logrus.Fields{logfields.TaskID: wpst.id}) + etr.Trace("wcowPodSandboxTask::DumpGuestStacks") + if wpst.host != nil { stacks, err := wpst.host.DumpStacks(ctx) if err != nil { @@ -268,7 +294,12 @@ func (wpst *wcowPodSandboxTask) DumpGuestStacks(ctx context.Context) string { return "" } -func (wpst *wcowPodSandboxTask) Update(ctx context.Context, req *task.UpdateTaskRequest) error { +func (wpst *wcowPodSandboxTask) Update(ctx context.Context, req *task.UpdateTaskRequest) (err error) { + ctx, span := oc.StartSpan(ctx, "wcowPodSandboxTask::Update") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.TaskID, wpst.id)) + if wpst.host == nil { return errTaskNotIsolated } @@ -286,6 +317,9 @@ func (wpst *wcowPodSandboxTask) Update(ctx context.Context, req *task.UpdateTask } func (wpst *wcowPodSandboxTask) Share(ctx context.Context, req *shimdiag.ShareRequest) error { + ctx, etr := log.S(ctx, logrus.Fields{logfields.TaskID: wpst.id}) + etr.Trace("wcowPodSandboxTask::Share") + if wpst.host == nil { return errTaskNotIsolated } @@ -293,6 +327,9 @@ func (wpst *wcowPodSandboxTask) Share(ctx context.Context, req *shimdiag.ShareRe } func (wpst *wcowPodSandboxTask) Stats(ctx context.Context) (*stats.Statistics, error) { + ctx, etr := log.S(ctx, logrus.Fields{logfields.TaskID: wpst.id}) + etr.Trace("wcowPodSandboxTask::Stats") + stats := &stats.Statistics{} if wpst.host == nil { return stats, nil diff --git a/cmd/gcs/main.go b/cmd/gcs/main.go index 13f3201fe7..443240ed6b 100644 --- a/cmd/gcs/main.go +++ b/cmd/gcs/main.go @@ -197,6 +197,8 @@ func main() { trace.RegisterExporter(&oc.LogrusExporter{}) } + logrus.AddHook(log.NewHook()) + // Use a file instead of stdout if *logFile != "" { logFileHandle, err := os.OpenFile(*logFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) diff --git a/cmd/ncproxy/ncproxy.go b/cmd/ncproxy/ncproxy.go index f5de74c66f..20bdbd9974 100644 --- a/cmd/ncproxy/ncproxy.go +++ b/cmd/ncproxy/ncproxy.go @@ -63,7 +63,7 @@ func newGRPCService(agentCache *computeAgentCache, ncproxyNetworking *ncproxysto var _ ncproxygrpc.NetworkConfigProxyServer = &grpcService{} func (s *grpcService) AddNIC(ctx context.Context, req *ncproxygrpc.AddNICRequest) (_ *ncproxygrpc.AddNICResponse, err error) { - ctx, span := trace.StartSpan(ctx, "AddNIC") + ctx, span := oc.StartSpan(ctx, "AddNIC") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -120,7 +120,9 @@ func (s *grpcService) AddNIC(ctx context.Context, req *ncproxygrpc.AddNICRequest settings := req.EndpointSettings.GetHcnEndpoint() if settings != nil && settings.Policies != nil && settings.Policies.IovPolicySettings != nil { - log.G(ctx).WithField("iov settings", settings.Policies.IovPolicySettings).Info("AddNIC iov settings") + log.G(ctx). + WithField("iov settings", settings.Policies.IovPolicySettings). + Info("AddNIC iov settings") iovReqSettings := settings.Policies.IovPolicySettings if iovReqSettings.IovOffloadWeight != 0 { // IOV policy was set during add nic request, update the hcn endpoint @@ -158,7 +160,7 @@ func (s *grpcService) AddNIC(ctx context.Context, req *ncproxygrpc.AddNICRequest } func (s *grpcService) ModifyNIC(ctx context.Context, req *ncproxygrpc.ModifyNICRequest) (_ *ncproxygrpc.ModifyNICResponse, err error) { - ctx, span := trace.StartSpan(ctx, "ModifyNIC") + ctx, span := oc.StartSpan(ctx, "ModifyNIC") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -196,7 +198,10 @@ func (s *grpcService) ModifyNIC(ctx context.Context, req *ncproxygrpc.ModifyNICR if settings.Policies == nil || settings.Policies.IovPolicySettings == nil { return nil, status.Error(codes.InvalidArgument, "received empty field in request") } - log.G(ctx).WithField("iov settings", settings.Policies.IovPolicySettings).Info("ModifyNIC iov settings") + + log.G(ctx). + WithField("iov settings", settings.Policies.IovPolicySettings). + Debug("ModifyNIC iov settings") iovReqSettings := settings.Policies.IovPolicySettings caReq := &computeagent.ModifyNICInternalRequest{ @@ -252,7 +257,7 @@ func (s *grpcService) ModifyNIC(ctx context.Context, req *ncproxygrpc.ModifyNICR } func (s *grpcService) DeleteNIC(ctx context.Context, req *ncproxygrpc.DeleteNICRequest) (_ *ncproxygrpc.DeleteNICResponse, err error) { - ctx, span := trace.StartSpan(ctx, "DeleteNIC") + ctx, span := oc.StartSpan(ctx, "DeleteNIC") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -307,7 +312,7 @@ func (s *grpcService) DeleteNIC(ctx context.Context, req *ncproxygrpc.DeleteNICR } func (s *grpcService) CreateNetwork(ctx context.Context, req *ncproxygrpc.CreateNetworkRequest) (_ *ncproxygrpc.CreateNetworkResponse, err error) { - ctx, span := trace.StartSpan(ctx, "CreateNetwork") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "CreateNetwork") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -357,7 +362,7 @@ func (s *grpcService) CreateNetwork(ctx context.Context, req *ncproxygrpc.Create } func (s *grpcService) CreateEndpoint(ctx context.Context, req *ncproxygrpc.CreateEndpointRequest) (_ *ncproxygrpc.CreateEndpointResponse, err error) { - ctx, span := trace.StartSpan(ctx, "CreateEndpoint") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "CreateEndpoint") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -434,7 +439,7 @@ func (s *grpcService) CreateEndpoint(ctx context.Context, req *ncproxygrpc.Creat } func (s *grpcService) AddEndpoint(ctx context.Context, req *ncproxygrpc.AddEndpointRequest) (_ *ncproxygrpc.AddEndpointResponse, err error) { - ctx, span := trace.StartSpan(ctx, "AddEndpoint") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "AddEndpoint") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -472,7 +477,7 @@ func (s *grpcService) AddEndpoint(ctx context.Context, req *ncproxygrpc.AddEndpo } func (s *grpcService) DeleteEndpoint(ctx context.Context, req *ncproxygrpc.DeleteEndpointRequest) (_ *ncproxygrpc.DeleteEndpointResponse, err error) { - ctx, span := trace.StartSpan(ctx, "DeleteEndpoint") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "DeleteEndpoint") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -508,7 +513,7 @@ func (s *grpcService) DeleteEndpoint(ctx context.Context, req *ncproxygrpc.Delet } func (s *grpcService) DeleteNetwork(ctx context.Context, req *ncproxygrpc.DeleteNetworkRequest) (_ *ncproxygrpc.DeleteNetworkResponse, err error) { - ctx, span := trace.StartSpan(ctx, "DeleteNetwork") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "DeleteNetwork") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -577,7 +582,7 @@ func ncpNetworkingEndpointToEndpointResponse(ep *ncproxynetworking.Endpoint) (_ } func (s *grpcService) GetEndpoint(ctx context.Context, req *ncproxygrpc.GetEndpointRequest) (_ *ncproxygrpc.GetEndpointResponse, err error) { - ctx, span := trace.StartSpan(ctx, "GetEndpoint") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "GetEndpoint") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -605,7 +610,7 @@ func (s *grpcService) GetEndpoint(ctx context.Context, req *ncproxygrpc.GetEndpo } func (s *grpcService) GetEndpoints(ctx context.Context, req *ncproxygrpc.GetEndpointsRequest) (_ *ncproxygrpc.GetEndpointsResponse, err error) { - ctx, span := trace.StartSpan(ctx, "GetEndpoints") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "GetEndpoints") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -656,7 +661,7 @@ func ncpNetworkingNetworkToNetworkResponse(network *ncproxynetworking.Network) ( } func (s *grpcService) GetNetwork(ctx context.Context, req *ncproxygrpc.GetNetworkRequest) (_ *ncproxygrpc.GetNetworkResponse, err error) { - ctx, span := trace.StartSpan(ctx, "GetNetwork") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "GetNetwork") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -685,7 +690,7 @@ func (s *grpcService) GetNetwork(ctx context.Context, req *ncproxygrpc.GetNetwor } func (s *grpcService) GetNetworks(ctx context.Context, req *ncproxygrpc.GetNetworksRequest) (_ *ncproxygrpc.GetNetworksResponse, err error) { - ctx, span := trace.StartSpan(ctx, "GetNetworks") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "GetNetworks") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -755,7 +760,7 @@ func getComputeAgentClient(agentAddr string) (*computeAgentClient, error) { } func (s *ttrpcService) RegisterComputeAgent(ctx context.Context, req *ncproxyttrpc.RegisterComputeAgentRequest) (_ *ncproxyttrpc.RegisterComputeAgentResponse, err error) { - ctx, span := trace.StartSpan(ctx, "RegisterComputeAgent") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "RegisterComputeAgent") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -782,7 +787,7 @@ func (s *ttrpcService) RegisterComputeAgent(ctx context.Context, req *ncproxyttr } func (s *ttrpcService) UnregisterComputeAgent(ctx context.Context, req *ncproxyttrpc.UnregisterComputeAgentRequest) (_ *ncproxyttrpc.UnregisterComputeAgentResponse, err error) { - ctx, span := trace.StartSpan(ctx, "UnregisterComputeAgent") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "UnregisterComputeAgent") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -809,7 +814,7 @@ func (s *ttrpcService) UnregisterComputeAgent(ctx context.Context, req *ncproxyt } func (s *ttrpcService) ConfigureNetworking(ctx context.Context, req *ncproxyttrpc.ConfigureNetworkingInternalRequest) (_ *ncproxyttrpc.ConfigureNetworkingInternalResponse, err error) { - ctx, span := trace.StartSpan(ctx, "ConfigureNetworking") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "ConfigureNetworking") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/cmd/ncproxy/run.go b/cmd/ncproxy/run.go index 6bfbd590e7..54ea609ef6 100644 --- a/cmd/ncproxy/run.go +++ b/cmd/ncproxy/run.go @@ -205,7 +205,7 @@ func run(clicontext *cli.Context) error { return fmt.Errorf("failed to connect to NodeNetworkService at address %s", conf.NodeNetSvcAddr) } - log.G(ctx).Infof("Successfully connected to NodeNetworkService at address %s", conf.NodeNetSvcAddr) + log.G(ctx).Debugf("Successfully connected to NodeNetworkService at address %s", conf.NodeNetSvcAddr) netSvcClient := nodenetsvc.NewNodeNetworkServiceClient(client) nodeNetSvcClient = &nodeNetSvcConn{ diff --git a/cmd/ncproxy/server.go b/cmd/ncproxy/server.go index 1be82a1146..80ccc42073 100644 --- a/cmd/ncproxy/server.go +++ b/cmd/ncproxy/server.go @@ -115,7 +115,7 @@ func (s *server) serve(ctx context.Context, ttrpcListener net.Listener, grpcList go func() { log.G(ctx).WithFields(logrus.Fields{ "address": s.conf.TTRPCAddr, - }).Info("Serving ncproxy TTRPC service") + }).Debug("Serving ncproxy TTRPC service") // No need to defer close the listener as ttrpc.Serve does this internally. serveErr <- trapClosedConnErr(s.ttrpc.Serve(ctx, ttrpcListener)) @@ -124,7 +124,7 @@ func (s *server) serve(ctx context.Context, ttrpcListener net.Listener, grpcList go func() { log.G(ctx).WithFields(logrus.Fields{ "address": s.conf.GRPCAddr, - }).Info("Serving ncproxy GRPC service") + }).Debug("Serving ncproxy GRPC service") defer grpcListener.Close() serveErr <- trapClosedConnErr(s.grpc.Serve(grpcListener)) @@ -182,7 +182,7 @@ func reconnectComputeAgents(ctx context.Context, agentStore *ncproxystore.Comput } return } - log.G(ctx).WithField("containerID", containerID).Info("reconnected to container's compute agent") + log.G(ctx).WithField("containerID", containerID).Debug("reconnected to container's compute agent") // connection succeeded, add entry in cache map for later // since the servers have not started running, we know that the cache cannot be empty diff --git a/cmd/runhcs/create-scratch.go b/cmd/runhcs/create-scratch.go index 9f63df4a69..752155f63c 100644 --- a/cmd/runhcs/create-scratch.go +++ b/cmd/runhcs/create-scratch.go @@ -12,7 +12,6 @@ import ( "github.com/Microsoft/hcsshim/osversion" "github.com/pkg/errors" "github.com/urfave/cli" - "go.opencensus.io/trace" ) var createScratchCommand = cli.Command{ @@ -36,7 +35,7 @@ var createScratchCommand = cli.Command{ }, Before: appargs.Validate(), Action: func(context *cli.Context) (err error) { - ctx, span := trace.StartSpan(gcontext.Background(), "create-scratch") + ctx, span := oc.StartSpan(gcontext.Background(), "create-scratch") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/cmd/runhcs/prepare-disk.go b/cmd/runhcs/prepare-disk.go index bebd641c20..897d10ca5d 100644 --- a/cmd/runhcs/prepare-disk.go +++ b/cmd/runhcs/prepare-disk.go @@ -12,7 +12,6 @@ import ( "github.com/Microsoft/hcsshim/osversion" "github.com/pkg/errors" "github.com/urfave/cli" - "go.opencensus.io/trace" ) const ( @@ -32,7 +31,7 @@ var prepareDiskCommand = cli.Command{ }, Before: appargs.Validate(), Action: func(context *cli.Context) (err error) { - ctx, span := trace.StartSpan(gcontext.Background(), prepareDiskStr) + ctx, span := oc.StartSpan(gcontext.Background(), prepareDiskStr) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/computestorage/attach.go b/computestorage/attach.go index 05b6ea7bd4..54c4b3bc4a 100644 --- a/computestorage/attach.go +++ b/computestorage/attach.go @@ -19,8 +19,8 @@ import ( // // `layerData` is the parent read-only layer data. func AttachLayerStorageFilter(ctx context.Context, layerPath string, layerData LayerData) (err error) { - title := "hcsshim.AttachLayerStorageFilter" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::AttachLayerStorageFilter" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/computestorage/destroy.go b/computestorage/destroy.go index 8dd942bab9..5058d3b55e 100644 --- a/computestorage/destroy.go +++ b/computestorage/destroy.go @@ -14,8 +14,8 @@ import ( // // `layerPath` is a path to a directory containing the layer to export. func DestroyLayer(ctx context.Context, layerPath string) (err error) { - title := "hcsshim.DestroyLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::DestroyLayer" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("layerPath", layerPath)) diff --git a/computestorage/detach.go b/computestorage/detach.go index 934ee5b1a6..daf1bfff20 100644 --- a/computestorage/detach.go +++ b/computestorage/detach.go @@ -14,8 +14,8 @@ import ( // // `layerPath` is a path to a directory containing the layer to export. func DetachLayerStorageFilter(ctx context.Context, layerPath string) (err error) { - title := "hcsshim.DetachLayerStorageFilter" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::DetachLayerStorageFilter" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("layerPath", layerPath)) diff --git a/computestorage/export.go b/computestorage/export.go index cf90d9b6c9..c6370a5c9a 100644 --- a/computestorage/export.go +++ b/computestorage/export.go @@ -21,8 +21,8 @@ import ( // // `options` are the export options applied to the exported layer. func ExportLayer(ctx context.Context, layerPath, exportFolderPath string, layerData LayerData, options ExportLayerOptions) (err error) { - title := "hcsshim.ExportLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::ExportLayer" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/computestorage/format.go b/computestorage/format.go index 05e0729f50..4a5735e989 100644 --- a/computestorage/format.go +++ b/computestorage/format.go @@ -11,7 +11,6 @@ import ( "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/osversion" "github.com/pkg/errors" - "go.opencensus.io/trace" "golang.org/x/sys/windows" ) @@ -43,8 +42,8 @@ func openDisk(path string) (windows.Handle, error) { // // If the VHD is not mounted it will be temporarily mounted. func FormatWritableLayerVhd(ctx context.Context, vhdHandle windows.Handle) (err error) { - title := "hcsshim.FormatWritableLayerVhd" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::FormatWritableLayerVhd" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/computestorage/import.go b/computestorage/import.go index a40b4037cc..e1c87416a3 100644 --- a/computestorage/import.go +++ b/computestorage/import.go @@ -21,8 +21,8 @@ import ( // // `layerData` is the parent layer data. func ImportLayer(ctx context.Context, layerPath, sourceFolderPath string, layerData LayerData) (err error) { - title := "hcsshim.ImportLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::ImportLayer" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/computestorage/initialize.go b/computestorage/initialize.go index ddd8f318da..d0c6216056 100644 --- a/computestorage/initialize.go +++ b/computestorage/initialize.go @@ -18,8 +18,8 @@ import ( // // `layerData` is the parent read-only layer data. func InitializeWritableLayer(ctx context.Context, layerPath string, layerData LayerData) (err error) { - title := "hcsshim.InitializeWritableLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::InitializeWritableLayer" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/computestorage/mount.go b/computestorage/mount.go index 6e445e766b..4f4d8ebf2f 100644 --- a/computestorage/mount.go +++ b/computestorage/mount.go @@ -8,14 +8,13 @@ import ( "github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/oc" "github.com/pkg/errors" - "go.opencensus.io/trace" "golang.org/x/sys/windows" ) // GetLayerVhdMountPath returns the volume path for a virtual disk of a writable container layer. func GetLayerVhdMountPath(ctx context.Context, vhdHandle windows.Handle) (path string, err error) { - title := "hcsshim.GetLayerVhdMountPath" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::GetLayerVhdMountPath" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/computestorage/setup.go b/computestorage/setup.go index 4b27b895ad..faec837ca1 100644 --- a/computestorage/setup.go +++ b/computestorage/setup.go @@ -23,8 +23,8 @@ import ( // // `options` are the options applied while processing the layer. func SetupBaseOSLayer(ctx context.Context, layerPath string, vhdHandle windows.Handle, options OsLayerOptions) (err error) { - title := "hcsshim.SetupBaseOSLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::SetupBaseOSLayer" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -54,8 +54,8 @@ func SetupBaseOSVolume(ctx context.Context, layerPath, volumePath string, option if osversion.Build() < 19645 { return errors.New("SetupBaseOSVolume is not present on builds older than 19645") } - title := "hcsshim.SetupBaseOSVolume" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::SetupBaseOSVolume" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/container.go b/container.go index 640e0b26f4..c8f09f88b9 100644 --- a/container.go +++ b/container.go @@ -62,7 +62,7 @@ type container struct { waitCh chan struct{} } -// createComputeSystemAdditionalJSON is read from the environment at initialisation +// createContainerAdditionalJSON is read from the environment at initialization // time. It allows an environment variable to define additional JSON which // is merged in the CreateComputeSystem call to HCS. var createContainerAdditionalJSON []byte diff --git a/hcn/hcnsupport.go b/hcn/hcnsupport.go index 00af20be31..c7cc5465a9 100644 --- a/hcn/hcnsupport.go +++ b/hcn/hcnsupport.go @@ -3,11 +3,13 @@ package hcn import ( - "fmt" + "context" "sync" "github.com/pkg/errors" "github.com/sirupsen/logrus" + + "github.com/Microsoft/hcsshim/internal/log" ) var ( @@ -81,6 +83,7 @@ func GetSupportedFeatures() SupportedFeatures { } func getSupportedFeatures() (SupportedFeatures, error) { + ctx := context.Background() var features SupportedFeatures globals, err := GetGlobals() if err != nil { @@ -114,10 +117,10 @@ func getSupportedFeatures() (SupportedFeatures, error) { features.NetworkACL = isFeatureSupported(globals.Version, NetworkACLPolicyVersion) features.NestedIpSet = isFeatureSupported(globals.Version, NestedIpSetVersion) - logrus.WithFields(logrus.Fields{ - "version": fmt.Sprintf("%+v", globals.Version), - "supportedFeatures": fmt.Sprintf("%+v", features), - }).Info("HCN feature check") + log.G(ctx).WithFields(logrus.Fields{ + "version": globals.Version, + "supportedFeatures": features, + }).Debug("HCN feature check") return features, nil } diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index 758eb78880..389dfc063b 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -11,12 +11,16 @@ import ( "sync/atomic" "time" - "github.com/Microsoft/hcsshim/internal/cow" - hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" - specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" "golang.org/x/sync/errgroup" "golang.org/x/sys/windows" + + "github.com/Microsoft/hcsshim/internal/cow" + hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/oc" + specs "github.com/opencontainers/runtime-spec/specs-go" ) // CmdProcessRequest stores information on command requests made through this package. @@ -29,6 +33,8 @@ type CmdProcessRequest struct { Stderr string } +// todo (helsaawy): replace use of Cmd.Log and switch to log.WithContext + // Cmd represents a command being prepared or run in a process host. type Cmd struct { // Host is the process host in which to launch the process. @@ -111,7 +117,7 @@ func Command(host cow.ProcessHost, name string, arg ...string) *Cmd { Spec: &specs.Process{ Args: append([]string{name}, arg...), }, - Log: logrus.NewEntry(logrus.StandardLogger()), + Log: log.G(context.Background()), ExitState: &ExitState{}, } if host.OS() == "windows" { @@ -128,12 +134,31 @@ func Command(host cow.ProcessHost, name string, arg ...string) *Cmd { func CommandContext(ctx context.Context, host cow.ProcessHost, name string, arg ...string) *Cmd { cmd := Command(host, name, arg...) cmd.Context = ctx + cmd.Log = log.G(ctx) return cmd } // Start starts a command. The caller must ensure that if Start succeeds, // Wait is eventually called to clean up resources. -func (c *Cmd) Start() error { +func (c *Cmd) Start() (err error) { + pctx := context.Background() + if c.Context != nil { + pctx = c.Context + } + ctx, span := oc.StartSpan(pctx, "cmd::Start") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute("cmd", log.Format(ctx, c.Spec.Args)), + trace.BoolAttribute("isOCI", c.Host.IsOCI()), + trace.StringAttribute("os", c.Host.OS()), + trace.StringAttribute("cwd", c.Spec.Cwd), + trace.StringAttribute("env", log.Format(ctx, c.Spec.Env))) + + if c.Log == nil { + c.Log = log.G(ctx) + } + c.allDoneCh = make(chan struct{}) var x interface{} if !c.Host.IsOCI() { @@ -182,17 +207,15 @@ func (c *Cmd) Start() error { } x = lpp } - if c.Context != nil && c.Context.Err() != nil { - return c.Context.Err() + if err = ctx.Err(); err != nil { + return err } - p, err := c.Host.CreateProcess(context.TODO(), x) + p, err := c.Host.CreateProcess(ctx, x) if err != nil { return err } c.Process = p - if c.Log != nil { - c.Log = c.Log.WithField("pid", p.Pid()) - } + c.Log = c.Log.WithField("pid", p.Pid()) // Start relaying process IO. stdin, stdout, stderr := p.Stdio() @@ -209,7 +232,7 @@ func (c *Cmd) Start() error { c.stdinErr.Store(err) } // Notify the process that there is no more input. - if err := p.CloseStdin(context.TODO()); err != nil && c.Log != nil { + if err := p.CloseStdin(ctx); err != nil && c.Log != nil { c.Log.WithError(err).Warn("failed to close Cmd stdin") } }() @@ -218,7 +241,7 @@ func (c *Cmd) Start() error { if c.Stdout != nil { c.iogrp.Go(func() error { _, err := relayIO(c.Stdout, stdout, c.Log, "stdout") - if err := p.CloseStdout(context.TODO()); err != nil { + if err := p.CloseStdout(ctx); err != nil { c.Log.WithError(err).Warn("failed to close Cmd stdout") } return err @@ -228,7 +251,7 @@ func (c *Cmd) Start() error { if c.Stderr != nil { c.iogrp.Go(func() error { _, err := relayIO(c.Stderr, stderr, c.Log, "stderr") - if err := p.CloseStderr(context.TODO()); err != nil { + if err := p.CloseStderr(ctx); err != nil { c.Log.WithError(err).Warn("failed to close Cmd stderr") } return err @@ -239,20 +262,33 @@ func (c *Cmd) Start() error { go func() { select { case <-c.Context.Done(): - _, _ = c.Process.Kill(context.TODO()) + // Process.Kill (via Process.Signal) will not send an RPC if the + // provided context in is cancelled (bridge.AsyncRPC will end early) + kctx := log.Copy(context.Background(), ctx) + _, _ = c.Process.Kill(kctx) case <-c.allDoneCh: } }() } + return nil } // Wait waits for a command and its IO to complete and closes the underlying // process. It can only be called once. It returns an ExitError if the command // runs and returns a non-zero exit code. -func (c *Cmd) Wait() error { +func (c *Cmd) Wait() (err error) { + pctx := context.Background() + if c.Context != nil { + pctx = c.Context + } + _, span := oc.StartSpan(pctx, "cmd::Wait") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute("cmd", log.Format(pctx, c.Spec.Args))) + waitErr := c.Process.Wait() - if waitErr != nil && c.Log != nil { + if waitErr != nil { c.Log.WithError(waitErr).Warn("process wait failed") } state := &ExitState{} @@ -271,9 +307,7 @@ func (c *Cmd) Wait() error { case <-t.C: // Close the process to cancel any reads to stdout or stderr. c.Process.Close() - if c.Log != nil { - c.Log.Warn("timed out waiting for stdio relay") - } + c.Log.Warn("timed out waiting for stdio relay") } }() } diff --git a/internal/cmd/diag.go b/internal/cmd/diag.go index e397bb85ee..7c77e80bf8 100644 --- a/internal/cmd/diag.go +++ b/internal/cmd/diag.go @@ -7,6 +7,8 @@ import ( "errors" "os/exec" + "github.com/sirupsen/logrus" + "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/uvm" @@ -14,6 +16,9 @@ import ( // ExecInUvm is a helper function used to execute commands specified in `req` inside the given UVM. func ExecInUvm(ctx context.Context, vm *uvm.UtilityVM, req *CmdProcessRequest) (int, error) { + ctx, etr := log.S(ctx, logrus.Fields{logfields.UVMID: vm.ID()}) + etr.Trace("cmd::ExecInUVM") + if len(req.Args) == 0 { return 0, errors.New("missing command") } @@ -41,6 +46,8 @@ func ExecInUvm(ctx context.Context, vm *uvm.UtilityVM, req *CmdProcessRequest) ( // ExecInShimHost is a helper function used to execute commands specified in `req` in the shim's // hosting system. func ExecInShimHost(ctx context.Context, req *CmdProcessRequest) (int, error) { + log.G(ctx).Trace("cmd::ExecInUVM") + if len(req.Args) == 0 { return 0, errors.New("missing command") } diff --git a/internal/cmd/io.go b/internal/cmd/io.go index 75ddd1f355..1e77c0fe14 100644 --- a/internal/cmd/io.go +++ b/internal/cmd/io.go @@ -10,6 +10,9 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" + + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" ) // UpstreamIO is an interface describing the IO to connect to above the shim. @@ -64,19 +67,26 @@ func NewUpstreamIO(ctx context.Context, id, stdout, stderr, stdin string, termin } // relayIO is a glorified io.Copy that also logs when the copy has completed. -func relayIO(w io.Writer, r io.Reader, log *logrus.Entry, name string) (int64, error) { +func relayIO(w io.Writer, r io.Reader, entry *logrus.Entry, name string) (int64, error) { n, err := io.Copy(w, r) - if log != nil { + if entry != nil { + ctx := entry.Context + if ctx == nil { + ctx = context.Background() + } + lvl := logrus.DebugLevel - log = log.WithFields(logrus.Fields{ - "file": name, - "bytes": n, + entry = entry.WithFields(logrus.Fields{ + logfields.File: name, + "bytes": n, + "reader": log.FormatIO(ctx, r), + "writer": log.FormatIO(ctx, w), }) if err != nil { lvl = logrus.ErrorLevel - log = log.WithError(err) + entry = entry.WithError(err) } - log.Log(lvl, "Cmd IO relay complete") + entry.Log(lvl, "Cmd IO relay complete") } return n, err } diff --git a/internal/cmd/io_binary.go b/internal/cmd/io_binary.go index 989a53c93c..2ef08def7d 100644 --- a/internal/cmd/io_binary.go +++ b/internal/cmd/io_binary.go @@ -20,6 +20,7 @@ import ( "github.com/sirupsen/logrus" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" ) const ( @@ -169,17 +170,29 @@ type binaryIO struct { // Close named pipes for container stdout and stderr and wait for the binary process to finish. func (b *binaryIO) Close(ctx context.Context) { + ctx, etr := log.S(ctx, logrus.Fields{ //nolint:ineffassign,staticcheck + "binaryCmd": b.cmd.String(), + "binaryProcessID": b.cmd.Process.Pid, + }) + etr.Trace("binaryIO::Close") + b.soutCloser.Do(func() { if b.sout != nil { + etr := etr.WithField(logfields.Pipe, b.stdout) err := b.sout.Close() if err != nil { - log.G(ctx).WithError(err).Errorf("error while closing stdout npipe") + etr.WithError(err).Errorf("error while closing stdout npipe") + } else { + etr.Debug("binaryIO::soutCloser - stdout") } } if b.serr != nil { + etr := etr.WithField(logfields.Pipe, b.stderr) err := b.serr.Close() if err != nil { - log.G(ctx).WithError(err).Errorf("error while closing stderr npipe") + etr.WithError(err).Errorf("error while closing stderr npipe") + } else { + etr.Debug("binaryIO::soutCloser - stderr") } } }) @@ -192,13 +205,14 @@ func (b *binaryIO) Close(ctx context.Context) { select { case err := <-done: if err != nil { - log.G(ctx).WithError(err).Errorf("error while waiting for binary cmd to finish") + etr.WithError(err).Errorf("error while waiting for binary cmd to finish") } case <-time.After(binaryCmdWaitTimeout): - log.G(ctx).Errorf("timeout while waiting for binaryIO process to finish. Killing") + etr := etr.WithField(logfields.Timeout, binaryCmdWaitTimeout.String()) + etr.Errorf("timeout while waiting for binaryIO process to finish. Killing") err := b.cmd.Process.Kill() if err != nil { - log.G(ctx).WithError(err).Errorf("error while killing binaryIO process") + etr.WithError(err).Errorf("error while killing binaryIO process") } } }) @@ -280,7 +294,7 @@ func (p *pipe) Read(b []byte) (int, error) { func (p *pipe) Close() error { if err := p.l.Close(); err != nil { - log.G(context.TODO()).WithError(err).Debug("error closing pipe listener") + log.G(context.Background()).WithError(err).Debug("error closing pipe listener") } p.conWg.Wait() if p.con != nil { diff --git a/internal/cmd/io_npipe.go b/internal/cmd/io_npipe.go index 614f34ca29..a285e88bae 100644 --- a/internal/cmd/io_npipe.go +++ b/internal/cmd/io_npipe.go @@ -15,6 +15,7 @@ import ( winio "github.com/Microsoft/go-winio" "github.com/Microsoft/go-winio/pkg/guid" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/cenkalti/backoff/v4" "github.com/sirupsen/logrus" "golang.org/x/sys/windows" @@ -34,7 +35,7 @@ func NewNpipeIO(ctx context.Context, stdin, stdout, stderr string, terminal bool "stdout": stdout, "stderr": stderr, "terminal": terminal, - }).Debug("NewNpipeIO") + }).Trace("NewNpipeIO") nio := &npipeio{ stdin: stdin, @@ -123,7 +124,7 @@ func (nprw *nPipeRetryWriter) Write(p []byte) (n int, err error) { nprw.Conn.Close() newConn, retryErr := nprw.retryDialPipe() if retryErr == nil { - log.G(nprw.ctx).WithField("address", nprw.pipePath).Info("Succeeded in reconnecting to named pipe") + log.G(nprw.ctx).WithField("address", nprw.pipePath).Debug("Succeeded in reconnecting to named pipe") nprw.Conn = newConn continue @@ -198,28 +199,31 @@ type npipeio struct { } func (nio *npipeio) Close(ctx context.Context) { + log.G(ctx).Trace("npipeio::Close") + // winio.win32Pipe.Close currently doesn't return any errors nio.sinCloser.Do(func() { if nio.sin != nil { - log.G(ctx).Debug("npipeio::sinCloser") + log.G(ctx).WithField(logfields.Pipe, nio.stdin).Debug("npipeio::sinCloser") nio.sin.Close() } }) nio.outErrCloser.Do(func() { if nio.sout != nil { - log.G(ctx).Debug("npipeio::outErrCloser - stdout") + log.G(ctx).WithField(logfields.Pipe, nio.stdout).Debug("npipeio::outErrCloser - stdout") nio.sout.Close() } if nio.serr != nil { - log.G(ctx).Debug("npipeio::outErrCloser - stderr") + log.G(ctx).WithField(logfields.Pipe, nio.stderr).Debug("npipeio::outErrCloser - stderr") nio.serr.Close() } }) } func (nio *npipeio) CloseStdin(ctx context.Context) { + log.G(ctx).Trace("npipeio::CloseStdin") nio.sinCloser.Do(func() { if nio.sin != nil { - log.G(ctx).Debug("npipeio::sinCloser") + log.G(ctx).WithField(logfields.Pipe, nio.stdin).Debug("npipeio::sinCloser") nio.sin.Close() } }) diff --git a/internal/copyfile/copyfile.go b/internal/copyfile/copyfile.go index 61aa2dc405..ea3e65b543 100644 --- a/internal/copyfile/copyfile.go +++ b/internal/copyfile/copyfile.go @@ -20,7 +20,7 @@ var ( // CopyFile is a utility for copying a file using CopyFileW win32 API for // performance. func CopyFile(ctx context.Context, srcFile, destFile string, overwrite bool) (err error) { - ctx, span := trace.StartSpan(ctx, "copyfile::CopyFile") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "copyfile::CopyFile") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/internal/devices/assigned_devices.go b/internal/devices/assigned_devices.go index 4750776403..a1ae4e0f73 100644 --- a/internal/devices/assigned_devices.go +++ b/internal/devices/assigned_devices.go @@ -44,7 +44,7 @@ func AddDevice(ctx context.Context, vm *uvm.UtilityVM, idType, deviceID string, return vpci, nil, errors.Wrapf(err, "failed to assign device %s of type %s to pod %s", deviceID, idType, vm.ID()) } vmBusInstanceID := vm.GetAssignedDeviceVMBUSInstanceID(vpci.VMBusGUID) - log.G(ctx).WithField("vmbus id", vmBusInstanceID).Info("vmbus instance ID") + log.G(ctx).WithField("vmbus id", vmBusInstanceID).Debug("vmbus instance ID") locationPaths, err = getChildrenDeviceLocationPaths(ctx, vm, vmBusInstanceID, deviceUtilPath) return vpci, locationPaths, err diff --git a/internal/gcs/bridge.go b/internal/gcs/bridge.go index 1e3e7c201d..f81cdb44cf 100644 --- a/internal/gcs/bridge.go +++ b/internal/gcs/bridge.go @@ -53,6 +53,9 @@ type rpc struct { ch chan struct{} } +// todo(helsaawy): remove bridge.log entry and log based on per-request context, not +// the context that started the bridge + // bridge represents a communcations bridge with the guest. It handles the // transport layer but (mostly) does not parse or construct the message payload. type bridge struct { @@ -311,7 +314,7 @@ func (brdg *bridge) recvLoop() error { } brdg.log.WithFields(logrus.Fields{ "payload": string(b), - "type": typ, + "type": typ.String(), "message-id": id}).Debug("bridge receive") switch typ & msgTypeMask { case msgTypeResponse: @@ -412,11 +415,10 @@ func (brdg *bridge) writeMessage(buf *bytes.Buffer, enc *json.Encoder, typ msgTy } brdg.log.WithFields(logrus.Fields{ "payload": string(b), - "type": typ, + "type": typ.String(), "message-id": id}).Debug("bridge send") } - // Write the message. _, err = buf.WriteTo(brdg.conn) if err != nil { return fmt.Errorf("bridge write: %s", err) diff --git a/internal/gcs/container.go b/internal/gcs/container.go index bf704fb548..69204a6d84 100644 --- a/internal/gcs/container.go +++ b/internal/gcs/container.go @@ -12,6 +12,7 @@ import ( "github.com/Microsoft/hcsshim/internal/hcs/schema1" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" "go.opencensus.io/trace" ) @@ -33,7 +34,7 @@ var _ cow.Container = &Container{} // CreateContainer creates a container using ID `cid` and `cfg`. The request // will likely not be cancellable even if `ctx` becomes done. func (gc *GuestConnection) CreateContainer(ctx context.Context, cid string, config interface{}) (_ *Container, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnection::CreateContainer") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::CreateContainer", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", cid)) @@ -91,17 +92,17 @@ func (c *Container) IsOCI() bool { // Close releases associated with the container. func (c *Container) Close() error { - c.closeOnce.Do(func() { - _, span := trace.StartSpan(context.Background(), "gcs::Container::Close") - defer span.End() - span.AddAttributes(trace.StringAttribute("cid", c.id)) - }) + _, span := oc.StartSpan(context.Background(), "gcs::Container::Close") + defer span.End() + span.AddAttributes(trace.StringAttribute("cid", c.id)) + + c.closeOnce.Do(func() {}) return nil } // CreateProcess creates a process in the container. func (c *Container) CreateProcess(ctx context.Context, config interface{}) (_ cow.Process, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::CreateProcess") + ctx, span := oc.StartSpan(ctx, "gcs::Container::CreateProcess", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -116,7 +117,7 @@ func (c *Container) ID() string { // Modify sends a modify request to the container. func (c *Container) Modify(ctx context.Context, config interface{}) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::Modify") + ctx, span := oc.StartSpan(ctx, "gcs::Container::Modify", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -131,7 +132,7 @@ func (c *Container) Modify(ctx context.Context, config interface{}) (err error) // Properties returns the requested container properties targeting a V1 schema container. func (c *Container) Properties(ctx context.Context, types ...schema1.PropertyType) (_ *schema1.ContainerProperties, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::Properties") + ctx, span := oc.StartSpan(ctx, "gcs::Container::Properties", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -150,7 +151,7 @@ func (c *Container) Properties(ctx context.Context, types ...schema1.PropertyTyp // PropertiesV2 returns the requested container properties targeting a V2 schema container. func (c *Container) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (_ *hcsschema.Properties, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::PropertiesV2") + ctx, span := oc.StartSpan(ctx, "gcs::Container::PropertiesV2", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -169,7 +170,7 @@ func (c *Container) PropertiesV2(ctx context.Context, types ...hcsschema.Propert // Start starts the container. func (c *Container) Start(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::Start") + ctx, span := oc.StartSpan(ctx, "gcs::Container::Start", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -200,7 +201,7 @@ func (c *Container) shutdown(ctx context.Context, proc rpcProc) error { // might not be terminated by the time the request completes (and might never // terminate). func (c *Container) Shutdown(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::Shutdown") + ctx, span := oc.StartSpan(ctx, "gcs::Container::Shutdown", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -214,7 +215,7 @@ func (c *Container) Shutdown(ctx context.Context) (err error) { // might not be terminated by the time the request completes (and might never // terminate). func (c *Container) Terminate(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::Terminate") + ctx, span := oc.StartSpan(ctx, "gcs::Container::Terminate", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -236,11 +237,11 @@ func (c *Container) Wait() error { } func (c *Container) waitBackground() { - ctx, span := trace.StartSpan(context.Background(), "gcs::Container::waitBackground") + ctx, span := oc.StartSpan(context.Background(), "gcs::Container::waitBackground") defer span.End() span.AddAttributes(trace.StringAttribute("cid", c.id)) err := c.Wait() - log.G(ctx).Debug("container exited") + log.G(ctx).WithField(logfields.ContainerID, c.id).Debug("container exited") oc.SetSpanStatus(span, err) } diff --git a/internal/gcs/guestconnection.go b/internal/gcs/guestconnection.go index bb28d890ff..689c30b3cf 100644 --- a/internal/gcs/guestconnection.go +++ b/internal/gcs/guestconnection.go @@ -68,7 +68,7 @@ type GuestConnectionConfig struct { // Connect establishes a GCS connection. `gcc.Conn` will be closed by this function. func (gcc *GuestConnectionConfig) Connect(ctx context.Context, isColdStart bool) (_ *GuestConnection, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnectionConfig::Connect") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnectionConfig::Connect", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -167,7 +167,7 @@ func (gc *GuestConnection) connect(ctx context.Context, isColdStart bool, initGu // Modify sends a modify settings request to the null container. This is // generally used to prepare virtual hardware that has been added to the guest. func (gc *GuestConnection) Modify(ctx context.Context, settings interface{}) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnection::Modify") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::Modify", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -180,7 +180,7 @@ func (gc *GuestConnection) Modify(ctx context.Context, settings interface{}) (er } func (gc *GuestConnection) DumpStacks(ctx context.Context) (response string, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnection::DumpStacks") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::DumpStacks", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -193,7 +193,7 @@ func (gc *GuestConnection) DumpStacks(ctx context.Context) (response string, err } func (gc *GuestConnection) DeleteContainerState(ctx context.Context, cid string) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnection::DeleteContainerState") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::DeleteContainerState", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", cid)) @@ -216,7 +216,7 @@ func (gc *GuestConnection) Close() error { // CreateProcess creates a process in the container host. func (gc *GuestConnection) CreateProcess(ctx context.Context, settings interface{}) (_ cow.Process, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnection::CreateProcess") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::CreateProcess", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -268,7 +268,7 @@ func (gc *GuestConnection) notify(ntf *containerNotification) error { if ch == nil { return fmt.Errorf("container %s not found", cid) } - logrus.WithField(logfields.ContainerID, cid).Info("container terminated in guest") + logrus.WithField(logfields.ContainerID, cid).Debug("container terminated in guest") close(ch) return nil } diff --git a/internal/gcs/guestconnection_test.go b/internal/gcs/guestconnection_test.go index f43a30d0bf..6ad9f4d697 100644 --- a/internal/gcs/guestconnection_test.go +++ b/internal/gcs/guestconnection_test.go @@ -20,6 +20,8 @@ import ( "github.com/sirupsen/logrus" "go.opencensus.io/trace" "go.opencensus.io/trace/tracestate" + + "github.com/Microsoft/hcsshim/internal/oc" ) const pipePortFmt = `\\.\pipe\gctest-port-%d` @@ -273,7 +275,7 @@ func Test_makeRequestNoSpan(t *testing.T) { } func Test_makeRequestWithSpan(t *testing.T) { - ctx, span := trace.StartSpan(context.Background(), t.Name()) + ctx, span := oc.StartSpan(context.Background(), t.Name()) defer span.End() r := makeRequest(ctx, t.Name()) diff --git a/internal/gcs/iochannel.go b/internal/gcs/iochannel.go index 5af6b81aaf..a2a032a12d 100644 --- a/internal/gcs/iochannel.go +++ b/internal/gcs/iochannel.go @@ -65,3 +65,7 @@ func (c *ioChannel) Write(b []byte) (int, error) { } return c.c.Write(b) } + +func (c *ioChannel) Addr() net.Addr { + return c.l.Addr() +} diff --git a/internal/gcs/process.go b/internal/gcs/process.go index 60141e9f70..fab6af75c7 100644 --- a/internal/gcs/process.go +++ b/internal/gcs/process.go @@ -124,7 +124,7 @@ func (gc *GuestConnection) exec(ctx context.Context, cid string, params interfac // Close releases resources associated with the process and closes the // associated standard IO streams. func (p *Process) Close() error { - ctx, span := trace.StartSpan(context.Background(), "gcs::Process::Close") + ctx, span := oc.StartSpan(context.Background(), "gcs::Process::Close") defer span.End() span.AddAttributes( trace.StringAttribute("cid", p.cid), @@ -144,7 +144,7 @@ func (p *Process) Close() error { // CloseStdin causes the process to read EOF on its stdin stream. func (p *Process) CloseStdin(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::CloseStdin") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "gcs::Process::CloseStdin") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -158,7 +158,7 @@ func (p *Process) CloseStdin(ctx context.Context) (err error) { } func (p *Process) CloseStdout(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::CloseStdout") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "gcs::Process::CloseStdout") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -169,7 +169,7 @@ func (p *Process) CloseStdout(ctx context.Context) (err error) { } func (p *Process) CloseStderr(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::CloseStderr") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "gcs::Process::CloseStderr") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -195,7 +195,7 @@ func (p *Process) ExitCode() (_ int, err error) { // signal was delivered. The process might not be terminated by the time this // returns. func (p *Process) Kill(ctx context.Context) (_ bool, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::Kill") + ctx, span := oc.StartSpan(ctx, "gcs::Process::Kill") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -213,7 +213,7 @@ func (p *Process) Pid() int { // ResizeConsole requests that the pty associated with the process resize its // window. func (p *Process) ResizeConsole(ctx context.Context, width, height uint16) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::ResizeConsole") + ctx, span := oc.StartSpan(ctx, "gcs::Process::ResizeConsole", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -232,7 +232,7 @@ func (p *Process) ResizeConsole(ctx context.Context, width, height uint16) (err // Signal sends a signal to the process, returning whether it was delivered. func (p *Process) Signal(ctx context.Context, options interface{}) (_ bool, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::Signal") + ctx, span := oc.StartSpan(ctx, "gcs::Process::Signal", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -277,7 +277,7 @@ func (p *Process) Wait() error { } func (p *Process) waitBackground() { - ctx, span := trace.StartSpan(context.Background(), "gcs::Process::waitBackground") + ctx, span := oc.StartSpan(context.Background(), "gcs::Process::waitBackground") defer span.End() span.AddAttributes( trace.StringAttribute("cid", p.cid), diff --git a/internal/gcs/protocol.go b/internal/gcs/protocol.go index 8450222a1a..94e55e4c1e 100644 --- a/internal/gcs/protocol.go +++ b/internal/gcs/protocol.go @@ -5,6 +5,7 @@ package gcs import ( "encoding/json" "fmt" + "strconv" "github.com/Microsoft/go-winio/pkg/guid" "github.com/Microsoft/hcsshim/internal/hcs/schema1" @@ -64,6 +65,43 @@ const ( rpcLifecycleNotification ) +func (rpc rpcProc) String() string { + switch rpc { + case rpcCreate: + return "Create" + case rpcStart: + return "Start" + case rpcShutdownGraceful: + return "ShutdownGraceful" + case rpcShutdownForced: + return "ShutdownForced" + case rpcExecuteProcess: + return "ExecuteProcess" + case rpcWaitForProcess: + return "WaitForProcess" + case rpcSignalProcess: + return "SignalProcess" + case rpcResizeConsole: + return "ResizeConsole" + case rpcGetProperties: + return "GetProperties" + case rpcModifySettings: + return "ModifySettings" + case rpcNegotiateProtocol: + return "NegotiateProtocol" + case rpcDumpStacks: + return "DumpStacks" + case rpcDeleteContainerState: + return "DeleteContainerState" + case rpcUpdateContainer: + return "UpdateContainer" + case rpcLifecycleNotification: + return "LifecycleNotification" + default: + return "0x" + strconv.FormatUint(uint64(rpc), 16) + } +} + type msgType uint32 const ( @@ -94,40 +132,7 @@ func (typ msgType) String() string { default: return fmt.Sprintf("%#x", uint32(typ)) } - switch rpcProc(typ &^ msgTypeMask) { - case rpcCreate: - s += "Create" - case rpcStart: - s += "Start" - case rpcShutdownGraceful: - s += "ShutdownGraceful" - case rpcShutdownForced: - s += "ShutdownForced" - case rpcExecuteProcess: - s += "ExecuteProcess" - case rpcWaitForProcess: - s += "WaitForProcess" - case rpcSignalProcess: - s += "SignalProcess" - case rpcResizeConsole: - s += "ResizeConsole" - case rpcGetProperties: - s += "GetProperties" - case rpcModifySettings: - s += "ModifySettings" - case rpcNegotiateProtocol: - s += "NegotiateProtocol" - case rpcDumpStacks: - s += "DumpStacks" - case rpcDeleteContainerState: - s += "DeleteContainerState" - case rpcUpdateContainer: - s += "UpdateContainer" - case rpcLifecycleNotification: - s += "LifecycleNotification" - default: - s += fmt.Sprintf("%#x", uint32(typ)) - } + s += rpcProc(typ &^ msgTypeMask).String() return s + ")" } diff --git a/internal/guest/bridge/bridge.go b/internal/guest/bridge/bridge.go index 402034f479..ff64f6352d 100644 --- a/internal/guest/bridge/bridge.go +++ b/internal/guest/bridge/bridge.go @@ -127,11 +127,14 @@ func (mux *Mux) ServeMsg(r *Request) (RequestResponse, error) { return h.ServeMsg(r) } +// todo (helsaawy): remove context as a field and pass it explicitly +// https://go.dev/blog/context-and-structs#storing-context-in-structs-leads-to-confusion + // Request is the bridge request that has been sent. type Request struct { // Context is the request context received from the bridge. Context context.Context - // Header is the wire format message header that preceeded the message for + // Header is the wire format message header that preceded the message for // this request. Header *prot.MessageHeader // ContainerID is the id of the container that this message corresponds to. @@ -164,7 +167,7 @@ type bridgeResponse struct { // It has two fundamentally different dispatch options: // // 1. Request/Response where using the `Handler` a request -// of a given type will be dispatched to the apprpriate handler +// of a given type will be dispatched to the appropriate handler // and an appropriate response will respond to exactly that request that // caused the dispatch. // @@ -288,9 +291,16 @@ func (b *Bridge) ListenAndServe(bridgeIn io.ReadCloser, bridgeOut io.WriteCloser } } } - ctx, span = trace.StartSpanWithRemoteParent(context.Background(), "opengcs::bridge::request", sc) + ctx, span = trace.StartSpanWithRemoteParent(context.Background(), + "opengcs::bridge::request", + sc, + oc.WithTraceLevelSampler, + oc.WithServerSpanKind) + ctx = log.U(ctx) } else { - ctx, span = trace.StartSpan(context.Background(), "opengcs::bridge::request") + ctx, span = oc.StartSpan(context.Background(), + "opengcs::bridge::request", + oc.WithServerSpanKind) } span.AddAttributes( @@ -410,8 +420,10 @@ func (b *Bridge) ListenAndServe(bridgeIn io.ReadCloser, bridgeOut io.WriteCloser // PublishNotification writes a specific notification to the bridge. func (b *Bridge) PublishNotification(n *prot.ContainerNotification) { - ctx, span := trace.StartSpan(context.Background(), "opengcs::bridge::PublishNotification") - span.AddAttributes(trace.StringAttribute("notification", fmt.Sprintf("%+v", n))) + ctx, span := oc.StartSpan(context.Background(), + "opengcs::bridge::PublishNotification", + oc.WithClientSpanKind) + span.AddAttributes(trace.StringAttribute("notification", log.Format(ctx, n))) // DONT defer span.End() here. Publish is odd because bridgeResponse calls // `End` on the `ctx` after the response is sent. diff --git a/internal/guest/bridge/bridge_v2.go b/internal/guest/bridge/bridge_v2.go index f7924a2576..b5ea68a89b 100644 --- a/internal/guest/bridge/bridge_v2.go +++ b/internal/guest/bridge/bridge_v2.go @@ -47,7 +47,7 @@ var capabilities = prot.GcsCapabilities{ // negotiateProtocolV2 was introduced in v4 so will not be called with a minimum // lower than that. func (b *Bridge) negotiateProtocolV2(r *Request) (_ RequestResponse, err error) { - _, span := trace.StartSpan(r.Context, "opengcs::bridge::negotiateProtocolV2") + _, span := oc.StartSpan(r.Context, "opengcs::bridge::negotiateProtocolV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -83,7 +83,7 @@ func (b *Bridge) negotiateProtocolV2(r *Request) (_ RequestResponse, err error) // // This is allowed only for protocol version 4+, schema version 2.1+ func (b *Bridge) createContainerV2(r *Request) (_ RequestResponse, err error) { - ctx, span := trace.StartSpan(r.Context, "opengcs::bridge::createContainerV2") + ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::createContainerV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -136,7 +136,7 @@ func (b *Bridge) createContainerV2(r *Request) (_ RequestResponse, err error) { // // This is allowed only for protocol version 4+, schema version 2.1+ func (b *Bridge) startContainerV2(r *Request) (_ RequestResponse, err error) { - _, span := trace.StartSpan(r.Context, "opengcs::bridge::startContainerV2") + _, span := oc.StartSpan(r.Context, "opengcs::bridge::startContainerV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -167,7 +167,7 @@ func (b *Bridge) startContainerV2(r *Request) (_ RequestResponse, err error) { // // This is allowed only for protocol version 4+, schema version 2.1+ func (b *Bridge) execProcessV2(r *Request) (_ RequestResponse, err error) { - ctx, span := trace.StartSpan(r.Context, "opengcs::bridge::execProcessV2") + ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::execProcessV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -223,7 +223,7 @@ func (b *Bridge) execProcessV2(r *Request) (_ RequestResponse, err error) { // // This is allowed only for protocol version 4+, schema version 2.1+ func (b *Bridge) killContainerV2(r *Request) (RequestResponse, error) { - ctx, span := trace.StartSpan(r.Context, "opengcs::bridge::killContainerV2") + ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::killContainerV2") defer span.End() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -236,7 +236,7 @@ func (b *Bridge) killContainerV2(r *Request) (RequestResponse, error) { // // This is allowed only for protocol version 4+, schema version 2.1+ func (b *Bridge) shutdownContainerV2(r *Request) (RequestResponse, error) { - ctx, span := trace.StartSpan(r.Context, "opengcs::bridge::shutdownContainerV2") + ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::shutdownContainerV2") defer span.End() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -282,7 +282,7 @@ func (b *Bridge) signalContainerV2(ctx context.Context, span *trace.Span, r *Req } func (b *Bridge) signalProcessV2(r *Request) (_ RequestResponse, err error) { - ctx, span := trace.StartSpan(r.Context, "opengcs::bridge::signalProcessV2") + ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::signalProcessV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -320,7 +320,7 @@ func (b *Bridge) signalProcessV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) getPropertiesV2(r *Request) (_ RequestResponse, err error) { - ctx, span := trace.StartSpan(r.Context, "opengcs::bridge::getPropertiesV2") + ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::getPropertiesV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -383,7 +383,7 @@ func (b *Bridge) getPropertiesV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) waitOnProcessV2(r *Request) (_ RequestResponse, err error) { - _, span := trace.StartSpan(r.Context, "opengcs::bridge::waitOnProcessV2") + _, span := oc.StartSpan(r.Context, "opengcs::bridge::waitOnProcessV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -438,7 +438,7 @@ func (b *Bridge) waitOnProcessV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) resizeConsoleV2(r *Request) (_ RequestResponse, err error) { - ctx, span := trace.StartSpan(r.Context, "opengcs::bridge::resizeConsoleV2") + ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::resizeConsoleV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -472,7 +472,7 @@ func (b *Bridge) resizeConsoleV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) modifySettingsV2(r *Request) (_ RequestResponse, err error) { - ctx, span := trace.StartSpan(r.Context, "opengcs::bridge::modifySettingsV2") + ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::modifySettingsV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) @@ -491,7 +491,7 @@ func (b *Bridge) modifySettingsV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) dumpStacksV2(r *Request) (_ RequestResponse, err error) { - _, span := trace.StartSpan(r.Context, "opengcs::bridge::dumpStacksV2") + _, span := oc.StartSpan(r.Context, "opengcs::bridge::dumpStacksV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -503,7 +503,7 @@ func (b *Bridge) dumpStacksV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) deleteContainerStateV2(r *Request) (_ RequestResponse, err error) { - ctx, span := trace.StartSpan(r.Context, "opengcs::bridge::deleteContainerStateV2") + ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::deleteContainerStateV2") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/internal/guest/kmsg/kmsg.go b/internal/guest/kmsg/kmsg.go index 112b26b2cc..2c0a698f8c 100644 --- a/internal/guest/kmsg/kmsg.go +++ b/internal/guest/kmsg/kmsg.go @@ -137,7 +137,7 @@ func ReadForever(logLevel LogLevel) { }).Error("failed to parse kmsg entry") } else { if entry.Priority <= logLevel { - logrus.WithFields(entry.logFormat()).Info("kmsg read") + logrus.WithFields(entry.logFormat()).Debug("kmsg read") } } } diff --git a/internal/guest/network/network.go b/internal/guest/network/network.go index d286952271..318671b99b 100644 --- a/internal/guest/network/network.go +++ b/internal/guest/network/network.go @@ -35,7 +35,7 @@ const maxDNSSearches = 6 // GenerateEtcHostsContent generates a /etc/hosts file based on `hostname`. func GenerateEtcHostsContent(ctx context.Context, hostname string) string { - _, span := trace.StartSpan(ctx, "network::GenerateEtcHostsContent") + _, span := oc.StartSpan(ctx, "network::GenerateEtcHostsContent") defer span.End() span.AddAttributes(trace.StringAttribute("hostname", hostname)) @@ -60,7 +60,7 @@ func GenerateEtcHostsContent(ctx context.Context, hostname string) string { // GenerateResolvConfContent generates the resolv.conf file content based on // `searches`, `servers`, and `options`. func GenerateResolvConfContent(ctx context.Context, searches, servers, options []string) (_ string, err error) { - _, span := trace.StartSpan(ctx, "network::GenerateResolvConfContent") + _, span := oc.StartSpan(ctx, "network::GenerateResolvConfContent") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -116,7 +116,7 @@ func MergeValues(first, second []string) []string { // // Will retry the operation until `ctx` is exceeded or canceled. func InstanceIDToName(ctx context.Context, id string, vpciAssigned bool) (_ string, err error) { - ctx, span := trace.StartSpan(ctx, "network::InstanceIDToName") + ctx, span := oc.StartSpan(ctx, "network::InstanceIDToName") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/internal/guest/runtime/hcsv2/container.go b/internal/guest/runtime/hcsv2/container.go index d890d0c2b0..021ef5fb47 100644 --- a/internal/guest/runtime/hcsv2/container.go +++ b/internal/guest/runtime/hcsv2/container.go @@ -24,6 +24,7 @@ import ( "github.com/Microsoft/hcsshim/internal/guest/transport" "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" ) @@ -179,7 +180,7 @@ func (c *Container) Update(ctx context.Context, resources interface{}) error { // Wait waits for the container's init process to exit. func (c *Container) Wait() prot.NotificationType { - _, span := trace.StartSpan(context.Background(), "opengcs::Container::Wait") + _, span := oc.StartSpan(context.Background(), "opengcs::Container::Wait") defer span.End() span.AddAttributes(trace.StringAttribute(logfields.ContainerID, c.id)) @@ -204,7 +205,7 @@ func (c *Container) setExitType(signal syscall.Signal) { // GetStats returns the cgroup metrics for the container. func (c *Container) GetStats(ctx context.Context) (*v1.Metrics, error) { - _, span := trace.StartSpan(ctx, "opengcs::Container::GetStats") + _, span := oc.StartSpan(ctx, "opengcs::Container::GetStats") defer span.End() span.AddAttributes(trace.StringAttribute("cid", c.id)) diff --git a/internal/guest/runtime/hcsv2/network.go b/internal/guest/runtime/hcsv2/network.go index 9feb7afaed..8ff63b317d 100644 --- a/internal/guest/runtime/hcsv2/network.go +++ b/internal/guest/runtime/hcsv2/network.go @@ -71,7 +71,7 @@ func getOrAddNetworkNamespace(id string) *namespace { // removeNetworkNamespace removes the in-memory `namespace` found by `id`. func removeNetworkNamespace(ctx context.Context, id string) (err error) { - _, span := trace.StartSpan(ctx, "hcsv2::removeNetworkNamespace") + _, span := oc.StartSpan(ctx, "hcsv2::removeNetworkNamespace") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -112,7 +112,7 @@ func (n *namespace) ID() string { // assigned adapters into this namespace. The caller MUST call `Sync()` to // complete this operation. func (n *namespace) AssignContainerPid(ctx context.Context, pid int) (err error) { - _, span := trace.StartSpan(ctx, "namespace::AssignContainerPid") + _, span := oc.StartSpan(ctx, "namespace::AssignContainerPid") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -147,12 +147,12 @@ func (n *namespace) Adapters() []*guestresource.LCOWNetworkAdapter { // namespace assigned to `n`. A user must call `Sync()` to complete this // operation. func (n *namespace) AddAdapter(ctx context.Context, adp *guestresource.LCOWNetworkAdapter) (err error) { - ctx, span := trace.StartSpan(ctx, "namespace::AddAdapter") + ctx, span := oc.StartSpan(ctx, "namespace::AddAdapter") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( trace.StringAttribute("namespace", n.id), - trace.StringAttribute("adapter", fmt.Sprintf("%+v", adp))) + trace.StringAttribute("adapter", log.Format(ctx, adp))) n.m.Lock() defer n.m.Unlock() @@ -179,7 +179,7 @@ func (n *namespace) AddAdapter(ctx context.Context, adp *guestresource.LCOWNetwo // RemoveAdapter removes the adapter matching `id` from `n`. If `id` is not // found returns no error. func (n *namespace) RemoveAdapter(ctx context.Context, id string) (err error) { - _, span := trace.StartSpan(ctx, "namespace::RemoveAdapter") + _, span := oc.StartSpan(ctx, "namespace::RemoveAdapter") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -206,7 +206,7 @@ func (n *namespace) RemoveAdapter(ctx context.Context, id string) (err error) { // Sync moves all adapters to the network namespace of `n` if assigned. func (n *namespace) Sync(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "namespace::Sync") + ctx, span := oc.StartSpan(ctx, "namespace::Sync") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("namespace", n.id)) @@ -244,7 +244,7 @@ type nicInNamespace struct { // assignToPid assigns `nin.adapter`, represented by `nin.ifname` to `pid`. func (nin *nicInNamespace) assignToPid(ctx context.Context, pid int) (err error) { - ctx, span := trace.StartSpan(ctx, "nicInNamespace::assignToPid") + ctx, span := oc.StartSpan(ctx, "nicInNamespace::assignToPid") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/internal/guest/runtime/hcsv2/process.go b/internal/guest/runtime/hcsv2/process.go index 0a7dee8b30..227aae1197 100644 --- a/internal/guest/runtime/hcsv2/process.go +++ b/internal/guest/runtime/hcsv2/process.go @@ -14,6 +14,7 @@ import ( "github.com/Microsoft/hcsshim/internal/guest/runtime" "github.com/Microsoft/hcsshim/internal/guest/stdio" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/oc" oci "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -83,7 +84,7 @@ func newProcess(c *Container, spec *oci.Process, process runtime.Process, pid ui p.exitWg.Add(1) p.writersWg.Add(1) go func() { - ctx, span := trace.StartSpan(context.Background(), "newProcess::waitBackground") + ctx, span := oc.StartSpan(context.Background(), "newProcess::waitBackground") defer span.End() span.AddAttributes( trace.StringAttribute("cid", p.cid), @@ -113,7 +114,7 @@ func newProcess(c *Container, spec *oci.Process, process runtime.Process, pid ui } c.processesMutex.Lock() - _, span := trace.StartSpan(context.Background(), "newProcess::waitBackground::waitAllWaiters") + _, span := oc.StartSpan(context.Background(), "newProcess::waitBackground::waitAllWaiters") defer span.End() span.AddAttributes( trace.StringAttribute("cid", p.cid), @@ -161,7 +162,7 @@ func (p *containerProcess) ResizeConsole(ctx context.Context, height, width uint // gather the exit code. The second channel must be signaled from the caller // when the caller has completed its use of this call to Wait. func (p *containerProcess) Wait() (<-chan int, chan<- bool) { - ctx, span := trace.StartSpan(context.Background(), "opengcs::containerProcess::Wait") + ctx, span := oc.StartSpan(context.Background(), "opengcs::containerProcess::Wait") span.AddAttributes( trace.StringAttribute("cid", p.cid), trace.Int64Attribute("pid", int64(p.pid))) @@ -284,7 +285,7 @@ func (ep *externalProcess) ResizeConsole(ctx context.Context, height, width uint } func (ep *externalProcess) Wait() (<-chan int, chan<- bool) { - _, span := trace.StartSpan(context.Background(), "opengcs::externalProcess::Wait") + _, span := oc.StartSpan(context.Background(), "opengcs::externalProcess::Wait") span.AddAttributes(trace.Int64Attribute("pid", int64(ep.cmd.Process.Pid))) exitCodeChan := make(chan int, 1) diff --git a/internal/guest/runtime/hcsv2/sandbox_container.go b/internal/guest/runtime/hcsv2/sandbox_container.go index 45ad286016..4280eeb329 100644 --- a/internal/guest/runtime/hcsv2/sandbox_container.go +++ b/internal/guest/runtime/hcsv2/sandbox_container.go @@ -33,7 +33,7 @@ func getSandboxResolvPath(id string) string { } func setupSandboxContainerSpec(ctx context.Context, id string, spec *oci.Spec) (err error) { - ctx, span := trace.StartSpan(ctx, "hcsv2::setupSandboxContainerSpec") + ctx, span := oc.StartSpan(ctx, "hcsv2::setupSandboxContainerSpec") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", id)) diff --git a/internal/guest/runtime/hcsv2/standalone_container.go b/internal/guest/runtime/hcsv2/standalone_container.go index 0e232e7eda..6da310a1e2 100644 --- a/internal/guest/runtime/hcsv2/standalone_container.go +++ b/internal/guest/runtime/hcsv2/standalone_container.go @@ -37,7 +37,7 @@ func getStandaloneResolvPath(id string) string { } func setupStandaloneContainerSpec(ctx context.Context, id string, spec *oci.Spec) (err error) { - ctx, span := trace.StartSpan(ctx, "hcsv2::setupStandaloneContainerSpec") + ctx, span := oc.StartSpan(ctx, "hcsv2::setupStandaloneContainerSpec") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", id)) diff --git a/internal/guest/runtime/hcsv2/workload_container.go b/internal/guest/runtime/hcsv2/workload_container.go index 45249305a0..35ba49744b 100644 --- a/internal/guest/runtime/hcsv2/workload_container.go +++ b/internal/guest/runtime/hcsv2/workload_container.go @@ -98,7 +98,7 @@ func specHasGPUDevice(spec *oci.Spec) bool { } func setupWorkloadContainerSpec(ctx context.Context, sbid, id string, spec *oci.Spec) (err error) { - ctx, span := trace.StartSpan(ctx, "hcsv2::setupWorkloadContainerSpec") + ctx, span := oc.StartSpan(ctx, "hcsv2::setupWorkloadContainerSpec") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/internal/guest/storage/devicemapper/targets.go b/internal/guest/storage/devicemapper/targets.go index 82650e7562..2235f76c74 100644 --- a/internal/guest/storage/devicemapper/targets.go +++ b/internal/guest/storage/devicemapper/targets.go @@ -18,7 +18,7 @@ import ( // CreateZeroSectorLinearTarget creates dm-linear target for a device at `devPath` and `mappingInfo`, returns // virtual block device path. func CreateZeroSectorLinearTarget(ctx context.Context, devPath, devName string, mappingInfo *guestresource.LCOWVPMemMappingInfo) (_ string, err error) { - _, span := trace.StartSpan(ctx, "devicemapper::CreateZeroSectorLinearTarget") + _, span := oc.StartSpan(ctx, "devicemapper::CreateZeroSectorLinearTarget") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -49,7 +49,7 @@ func CreateZeroSectorLinearTarget(ctx context.Context, devPath, devName string, // size | version hash_dev | hash_offset // target hash_block func CreateVerityTarget(ctx context.Context, devPath, devName string, verityInfo *guestresource.DeviceVerityInfo) (_ string, err error) { - _, span := trace.StartSpan(ctx, "devicemapper::CreateVerityTarget") + _, span := oc.StartSpan(ctx, "devicemapper::CreateVerityTarget") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/internal/guest/storage/mount.go b/internal/guest/storage/mount.go index 4d6d9ec0ba..cf7c62d45c 100644 --- a/internal/guest/storage/mount.go +++ b/internal/guest/storage/mount.go @@ -114,7 +114,7 @@ func MountRShared(path string) error { // UnmountPath unmounts the target path if it exists and is a mount path. If // removeTarget this will remove the previously mounted folder. func UnmountPath(ctx context.Context, target string, removeTarget bool) (err error) { - _, span := trace.StartSpan(ctx, "storage::UnmountPath") + _, span := oc.StartSpan(ctx, "storage::UnmountPath") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/internal/guest/storage/overlay/overlay.go b/internal/guest/storage/overlay/overlay.go index f108dba3b0..329940d89f 100644 --- a/internal/guest/storage/overlay/overlay.go +++ b/internal/guest/storage/overlay/overlay.go @@ -60,7 +60,7 @@ func processErrNoSpace(ctx context.Context, path string, err error) { // MountLayer first enforces the security policy for the container's layer paths // and then calls Mount to mount the layer paths as an overlayfs func MountLayer(ctx context.Context, layerPaths []string, upperdirPath, workdirPath, rootfsPath string, readonly bool, containerId string, securityPolicy securitypolicy.SecurityPolicyEnforcer) (err error) { - _, span := trace.StartSpan(ctx, "overlay::MountLayer") + _, span := oc.StartSpan(ctx, "overlay::MountLayer") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -81,7 +81,7 @@ func MountLayer(ctx context.Context, layerPaths []string, upperdirPath, workdirP // Always creates `target`. On mount failure the created `target` will // be automatically cleaned up. func Mount(ctx context.Context, basePaths []string, upperdirPath, workdirPath, target string, readonly bool) (err error) { - _, span := trace.StartSpan(ctx, "overlay::Mount") + _, span := oc.StartSpan(ctx, "overlay::Mount") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/internal/guest/storage/plan9/plan9.go b/internal/guest/storage/plan9/plan9.go index 28aa080207..2d98a762a6 100644 --- a/internal/guest/storage/plan9/plan9.go +++ b/internal/guest/storage/plan9/plan9.go @@ -30,7 +30,7 @@ var ( // `target` will be created. On mount failure the created `target` will be // automatically cleaned up. func Mount(ctx context.Context, vsock transport.Transport, target, share string, port uint32, readonly bool) (err error) { - _, span := trace.StartSpan(ctx, "plan9::Mount") + _, span := oc.StartSpan(ctx, "plan9::Mount") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/internal/guest/storage/pmem/pmem.go b/internal/guest/storage/pmem/pmem.go index 9063d4b3da..f6ec60d157 100644 --- a/internal/guest/storage/pmem/pmem.go +++ b/internal/guest/storage/pmem/pmem.go @@ -78,7 +78,7 @@ func Mount( verityInfo *guestresource.DeviceVerityInfo, securityPolicy securitypolicy.SecurityPolicyEnforcer, ) (err error) { - mCtx, span := trace.StartSpan(ctx, "pmem::Mount") + mCtx, span := oc.StartSpan(ctx, "pmem::Mount") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -139,7 +139,7 @@ func Unmount( verityInfo *guestresource.DeviceVerityInfo, securityPolicy securitypolicy.SecurityPolicyEnforcer, ) (err error) { - _, span := trace.StartSpan(ctx, "pmem::Unmount") + _, span := oc.StartSpan(ctx, "pmem::Unmount") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/internal/guest/storage/scsi/scsi.go b/internal/guest/storage/scsi/scsi.go index 8484f79ddb..71bdbcc0c4 100644 --- a/internal/guest/storage/scsi/scsi.go +++ b/internal/guest/storage/scsi/scsi.go @@ -100,7 +100,7 @@ func mount( verityInfo *guestresource.DeviceVerityInfo, securityPolicy securitypolicy.SecurityPolicyEnforcer, ) (err error) { - spnCtx, span := trace.StartSpan(ctx, "scsi::Mount") + spnCtx, span := oc.StartSpan(ctx, "scsi::Mount") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -229,7 +229,7 @@ func unmount( verityInfo *guestresource.DeviceVerityInfo, securityPolicy securitypolicy.SecurityPolicyEnforcer, ) (err error) { - ctx, span := trace.StartSpan(ctx, "scsi::Unmount") + ctx, span := oc.StartSpan(ctx, "scsi::Unmount") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -285,7 +285,7 @@ func Unmount( // ControllerLunToName finds the `/dev/sd*` path to the SCSI device on // `controller` index `lun`. func ControllerLunToName(ctx context.Context, controller, lun uint8) (_ string, err error) { - ctx, span := trace.StartSpan(ctx, "scsi::ControllerLunToName") + ctx, span := oc.StartSpan(ctx, "scsi::ControllerLunToName") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -329,7 +329,7 @@ func ControllerLunToName(ctx context.Context, controller, lun uint8) (_ string, // // If the device is not attached returns no error. func unplugDevice(ctx context.Context, controller, lun uint8) (err error) { - _, span := trace.StartSpan(ctx, "scsi::UnplugDevice") + _, span := oc.StartSpan(ctx, "scsi::UnplugDevice") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/internal/guest/transport/vsock.go b/internal/guest/transport/vsock.go index af5d46914a..f724a587b3 100644 --- a/internal/guest/transport/vsock.go +++ b/internal/guest/transport/vsock.go @@ -4,10 +4,13 @@ package transport import ( + "context" "fmt" "syscall" "time" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/linuxkit/virtsock/pkg/vsock" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -25,12 +28,15 @@ type VsockTransport struct{} var _ Transport = &VsockTransport{} +const _dialRetrySleepTime = 100 * time.Millisecond + // Dial accepts a vsock socket port number as configuration, and // returns an unconnected VsockConnection struct. func (t *VsockTransport) Dial(port uint32) (Connection, error) { - logrus.WithFields(logrus.Fields{ + _, etr := log.S(context.Background(), logrus.Fields{ "port": port, - }).Info("opengcs::VsockTransport::Dial - vsock dial port") + }) + etr.Trace("opengcs::VsockTransport::Dial") // HACK: Remove loop when vsock bugs are fixed! // Retry 10 times because vsock.Dial can return connection time out @@ -43,7 +49,11 @@ func (t *VsockTransport) Dial(port uint32) (Connection, error) { // If the error was ETIMEDOUT retry, otherwise fail. cause := errors.Cause(err) if errno, ok := cause.(syscall.Errno); ok && errno == syscall.ETIMEDOUT { - time.Sleep(100 * time.Millisecond) + etr.WithFields(logrus.Fields{ + logfields.Attempt: i + 1, + logfields.Duration: _dialRetrySleepTime.String(), + }).Debug("vsock dial timed out; sleeping before retrying") + time.Sleep(_dialRetrySleepTime) continue } else { return nil, errors.Wrapf(err, "vsock Dial port (%d) failed", port) diff --git a/internal/hcs/errors.go b/internal/hcs/errors.go index 226dad2fbc..7a387b399f 100644 --- a/internal/hcs/errors.go +++ b/internal/hcs/errors.go @@ -13,6 +13,8 @@ import ( "github.com/Microsoft/hcsshim/internal/log" ) +// todo (helsaawy): annotate errors with grpc status code + var ( // ErrComputeSystemDoesNotExist is an error encountered when the container being operated on no longer exists ErrComputeSystemDoesNotExist = syscall.Errno(0xc037010e) diff --git a/internal/hcs/process.go b/internal/hcs/process.go index 4bf3a167a5..a1065ceb5a 100644 --- a/internal/hcs/process.go +++ b/internal/hcs/process.go @@ -13,8 +13,10 @@ import ( "time" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/vmcompute" + "github.com/sirupsen/logrus" "go.opencensus.io/trace" ) @@ -120,11 +122,15 @@ func (process *Process) processSignalResult(ctx context.Context, err error) (boo // // For WCOW `guestresource.SignalProcessOptionsWCOW`. func (process *Process) Signal(ctx context.Context, options interface{}) (bool, error) { + operation := "hcs::Process::Signal" + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.ProcessID: process.processID, + logfields.ContainerID: process.SystemID()}) + etr.Trace(operation) + process.handleLock.RLock() defer process.handleLock.RUnlock() - operation := "hcs::Process::Signal" - if process.handle == 0 { return false, makeProcessError(process, operation, ErrAlreadyClosed, nil) } @@ -145,11 +151,15 @@ func (process *Process) Signal(ctx context.Context, options interface{}) (bool, // Kill signals the process to terminate but does not wait for it to finish terminating. func (process *Process) Kill(ctx context.Context) (bool, error) { + operation := "hcs::Process::Kill" + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.ProcessID: process.processID, + logfields.ContainerID: process.SystemID()}) + etr.Trace(operation) + process.handleLock.RLock() defer process.handleLock.RUnlock() - operation := "hcs::Process::Kill" - if process.handle == 0 { return false, makeProcessError(process, operation, ErrAlreadyClosed, nil) } @@ -203,7 +213,7 @@ func (process *Process) Kill(ctx context.Context) (bool, error) { // call multiple times. func (process *Process) waitBackground() { operation := "hcs::Process::waitBackground" - ctx, span := trace.StartSpan(context.Background(), operation) + ctx, span := oc.StartSpan(context.Background(), operation) defer span.End() span.AddAttributes( trace.StringAttribute("cid", process.SystemID()), @@ -245,7 +255,7 @@ func (process *Process) waitBackground() { } } } - log.G(ctx).WithField("exitCode", exitCode).Debug("process exited") + log.G(ctx).WithField("exitCode", exitCode).Debug("hcs::Process process exited") process.closedWaitOnce.Do(func() { process.exitCode = exitCode @@ -264,11 +274,15 @@ func (process *Process) Wait() error { // ResizeConsole resizes the console of the process. func (process *Process) ResizeConsole(ctx context.Context, width, height uint16) error { + operation := "hcs::Process::ResizeConsole" + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.ProcessID: process.processID, + logfields.ContainerID: process.SystemID()}) + etr.Trace(operation) + process.handleLock.RLock() defer process.handleLock.RUnlock() - operation := "hcs::Process::ResizeConsole" - if process.handle == 0 { return makeProcessError(process, operation, ErrAlreadyClosed, nil) } @@ -314,7 +328,7 @@ func (process *Process) ExitCode() (int, error) { // are the responsibility of the caller to close. func (process *Process) StdioLegacy() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) { operation := "hcs::Process::StdioLegacy" - ctx, span := trace.StartSpan(context.Background(), operation) + ctx, span := oc.StartSpan(context.Background(), operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -361,12 +375,18 @@ func (process *Process) Stdio() (stdin io.Writer, stdout, stderr io.Reader) { // CloseStdin closes the write side of the stdin pipe so that the process is // notified on the read side that there is no more data in stdin. -func (process *Process) CloseStdin(ctx context.Context) error { +func (process *Process) CloseStdin(ctx context.Context) (err error) { + operation := "hcs::Process::CloseStdin" + ctx, span := oc.StartSpan(ctx, operation) //nolint:ineffassign,staticcheck + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute("cid", process.SystemID()), + trace.Int64Attribute("pid", int64(process.processID))) + process.handleLock.RLock() defer process.handleLock.RUnlock() - operation := "hcs::Process::CloseStdin" - if process.handle == 0 { return makeProcessError(process, operation, ErrAlreadyClosed, nil) } @@ -400,7 +420,7 @@ func (process *Process) CloseStdin(ctx context.Context) error { } func (process *Process) CloseStdout(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "hcs::Process::CloseStdout") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "hcs::Process::CloseStdout") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -424,7 +444,7 @@ func (process *Process) CloseStdout(ctx context.Context) (err error) { } func (process *Process) CloseStderr(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "hcs::Process::CloseStderr") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "hcs::Process::CloseStderr") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -451,7 +471,7 @@ func (process *Process) CloseStderr(ctx context.Context) (err error) { // or wait on it. func (process *Process) Close() (err error) { operation := "hcs::Process::Close" - ctx, span := trace.StartSpan(context.Background(), operation) + ctx, span := oc.StartSpan(context.Background(), operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/internal/hcs/system.go b/internal/hcs/system.go index 052d08ccc3..a3e37d1b81 100644 --- a/internal/hcs/system.go +++ b/internal/hcs/system.go @@ -14,9 +14,11 @@ import ( "github.com/Microsoft/hcsshim/internal/hcs/schema1" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/timeout" "github.com/Microsoft/hcsshim/internal/vmcompute" + "github.com/sirupsen/logrus" "go.opencensus.io/trace" ) @@ -46,7 +48,7 @@ func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface in // hcsCreateComputeSystemContext is an async operation. Start the outer span // here to measure the full create time. - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := oc.StartSpan(ctx, operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", id)) @@ -99,6 +101,7 @@ func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface in // OpenComputeSystem opens an existing compute system by ID. func OpenComputeSystem(ctx context.Context, id string) (*System, error) { operation := "hcs::OpenComputeSystem" + log.G(ctx).WithField(logfields.ContainerID, id).Trace(operation) computeSystem := newSystem(id) handle, resultJSON, err := vmcompute.HcsOpenComputeSystem(ctx, id) @@ -151,6 +154,7 @@ func (computeSystem *System) IsOCI() bool { // GetComputeSystems gets a list of the compute systems on the system that match the query func GetComputeSystems(ctx context.Context, q schema1.ComputeSystemQuery) ([]schema1.ContainerProperties, error) { operation := "hcs::GetComputeSystems" + log.G(ctx).WithField("query", q).Trace(operation) queryb, err := json.Marshal(q) if err != nil { @@ -180,7 +184,7 @@ func (computeSystem *System) Start(ctx context.Context) (err error) { // hcsStartComputeSystemContext is an async operation. Start the outer span // here to measure the full start time. - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := oc.StartSpan(ctx, operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -208,11 +212,12 @@ func (computeSystem *System) ID() string { // Shutdown requests a compute system shutdown. func (computeSystem *System) Shutdown(ctx context.Context) error { + operation := "hcs::System::Shutdown" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::Shutdown" - if computeSystem.handle == 0 { return nil } @@ -229,11 +234,12 @@ func (computeSystem *System) Shutdown(ctx context.Context) error { // Terminate requests a compute system terminate. func (computeSystem *System) Terminate(ctx context.Context) error { + operation := "hcs::System::Terminate" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::Terminate" - if computeSystem.handle == 0 { return nil } @@ -255,7 +261,7 @@ func (computeSystem *System) Terminate(ctx context.Context) error { // safe to call multiple times. func (computeSystem *System) waitBackground() { operation := "hcs::System::waitBackground" - ctx, span := trace.StartSpan(context.Background(), operation) + ctx, span := oc.StartSpan(context.Background(), operation) defer span.End() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -299,11 +305,12 @@ func (computeSystem *System) ExitError() error { // Properties returns the requested container properties targeting a V1 schema container. func (computeSystem *System) Properties(ctx context.Context, types ...schema1.PropertyType) (*schema1.ContainerProperties, error) { + operation := "hcs::System::Properties" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::Properties" - queryBytes, err := json.Marshal(schema1.PropertyQuery{PropertyTypes: types}) if err != nil { return nil, makeSystemError(computeSystem, operation, err, nil) @@ -328,11 +335,12 @@ func (computeSystem *System) Properties(ctx context.Context, types ...schema1.Pr // PropertiesV2 returns the requested container properties targeting a V2 schema container. func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (*hcsschema.Properties, error) { + operation := "hcs::System::PropertiesV2" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::PropertiesV2" - queryBytes, err := json.Marshal(hcsschema.PropertyQuery{PropertyTypes: types}) if err != nil { return nil, makeSystemError(computeSystem, operation, err, nil) @@ -361,7 +369,7 @@ func (computeSystem *System) Pause(ctx context.Context) (err error) { // hcsPauseComputeSystemContext is an async peration. Start the outer span // here to measure the full pause time. - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := oc.StartSpan(ctx, operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -388,7 +396,7 @@ func (computeSystem *System) Resume(ctx context.Context) (err error) { // hcsResumeComputeSystemContext is an async operation. Start the outer span // here to measure the full restore time. - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := oc.StartSpan(ctx, operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -413,9 +421,9 @@ func (computeSystem *System) Resume(ctx context.Context) (err error) { func (computeSystem *System) Save(ctx context.Context, options interface{}) (err error) { operation := "hcs::System::Save" - // hcsSaveComputeSystemContext is an async peration. Start the outer span + // hcsSaveComputeSystemContext is an async operation. Start the outer span // here to measure the full save time. - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := oc.StartSpan(ctx, operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -468,6 +476,9 @@ func (computeSystem *System) createProcess(ctx context.Context, operation string // CreateProcess launches a new process within the computeSystem. func (computeSystem *System) CreateProcess(ctx context.Context, c interface{}) (cow.Process, error) { operation := "hcs::System::CreateProcess" + ctx, etr := log.S(ctx, logrus.Fields{logfields.ContainerID: computeSystem.id}) + etr.Trace(operation) + process, processInfo, err := computeSystem.createProcess(ctx, operation, c) if err != nil { return nil, err @@ -497,11 +508,12 @@ func (computeSystem *System) CreateProcess(ctx context.Context, c interface{}) ( // OpenProcess gets an interface to an existing process within the computeSystem. func (computeSystem *System) OpenProcess(ctx context.Context, pid int) (*Process, error) { + operation := "hcs::System::OpenProcess" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::OpenProcess" - if computeSystem.handle == 0 { return nil, makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) } @@ -524,7 +536,7 @@ func (computeSystem *System) OpenProcess(ctx context.Context, pid int) (*Process // Close cleans up any state associated with the compute system but does not terminate or wait for it. func (computeSystem *System) Close() (err error) { operation := "hcs::System::Close" - ctx, span := trace.StartSpan(context.Background(), operation) + ctx, span := oc.StartSpan(context.Background(), operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -614,11 +626,12 @@ func (computeSystem *System) unregisterCallback(ctx context.Context) error { // Modify the System by sending a request to HCS func (computeSystem *System) Modify(ctx context.Context, config interface{}) error { + operation := "hcs::System::Modify" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::Modify" - if computeSystem.handle == 0 { return makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) } diff --git a/internal/hcsoci/create.go b/internal/hcsoci/create.go index 6df67ee876..dbc5ff5585 100644 --- a/internal/hcsoci/create.go +++ b/internal/hcsoci/create.go @@ -18,6 +18,8 @@ import ( "github.com/Microsoft/hcsshim/internal/hcs" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/oci" "github.com/Microsoft/hcsshim/internal/resources" "github.com/Microsoft/hcsshim/internal/schemaversion" @@ -25,6 +27,7 @@ import ( "github.com/Microsoft/hcsshim/pkg/annotations" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" ) var ( @@ -216,9 +219,9 @@ func initializeCreateOptions(ctx context.Context, createOptions *CreateOptions) coi.templateID = oci.ParseAnnotationsTemplateID(ctx, createOptions.Spec) log.G(ctx).WithFields(logrus.Fields{ - "options": fmt.Sprintf("%+v", createOptions), + "options": createOptions, "schema": coi.actualSchemaVersion, - }).Debug("hcsshim::initializeCreateOptions") + }).Debug("hcsshim::initializeCreateOptions options") return coi, nil } @@ -269,6 +272,11 @@ func configureSandboxNetwork(ctx context.Context, coi *createOptionsInternal, r // release the resources on failure, so that the client can make the necessary // call to release resources that have been allocated as part of calling this function. func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.Container, _ *resources.Resources, err error) { + ctx, span := oc.StartSpan(ctx, "hcsoci::CreateContainer") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.ID, createOptions.ID)) + coi, err := initializeCreateOptions(ctx, createOptions) if err != nil { return nil, nil, err @@ -321,12 +329,13 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C } var hcsDocument, gcsDocument interface{} - log.G(ctx).Debug("hcsshim::CreateContainer allocating resources") + etr := log.G(ctx) + etr.Debug("hcsshim::CreateContainer allocating resources") if coi.Spec.Linux != nil { if schemaversion.IsV10(coi.actualSchemaVersion) { return nil, r, errors.New("LCOW v1 not supported") } - log.G(ctx).Debug("hcsshim::CreateContainer allocateLinuxResources") + etr.Debug("hcsshim::CreateContainer allocateLinuxResources") err = allocateLinuxResources(ctx, coi, r, isSandbox) if err != nil { log.G(ctx).WithError(err).Debug("failed to allocateLinuxResources") @@ -334,19 +343,19 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C } gcsDocument, err = createLinuxContainerDocument(ctx, coi, r.ContainerRootInUVM()) if err != nil { - log.G(ctx).WithError(err).Debug("failed createHCSContainerDocument") + log.G(ctx).WithError(err).Error("failed createHCSContainerDocument") return nil, r, err } } else { err = allocateWindowsResources(ctx, coi, r, isSandbox) if err != nil { - log.G(ctx).WithError(err).Debug("failed to allocateWindowsResources") + etr.WithError(err).Error("failed to allocateWindowsResources") return nil, r, err } - log.G(ctx).Debug("hcsshim::CreateContainer creating container document") + etr.Debug("hcsshim::CreateContainer creating container document") v1, v2, err := createWindowsContainerDocument(ctx, coi) if err != nil { - log.G(ctx).WithError(err).Debug("failed createHCSContainerDocument") + etr.WithError(err).Error("failed createHCSContainerDocument") return nil, r, err } @@ -370,7 +379,7 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C } } - log.G(ctx).Debug("hcsshim::CreateContainer creating compute system") + etr.Debug("hcsshim::CreateContainer creating compute system") if gcsDocument != nil { c, err := coi.HostingSystem.CreateContainer(ctx, coi.actualID, gcsDocument) if err != nil { @@ -390,6 +399,11 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C // CreateContainer does. Also, instead of sending create container request it sends a modify // request to an existing container. CloneContainer only works for WCOW. func CloneContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.Container, _ *resources.Resources, err error) { + ctx, span := oc.StartSpan(ctx, "hcsoci::CloneContainer") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.ID, createOptions.ID)) + coi, err := initializeCreateOptions(ctx, createOptions) if err != nil { return nil, nil, err diff --git a/internal/hcsoci/devices.go b/internal/hcsoci/devices.go index ccc19d4af8..d01d65c86b 100644 --- a/internal/hcsoci/devices.go +++ b/internal/hcsoci/devices.go @@ -158,7 +158,7 @@ func handleAssignedDevicesWindows( ID: value, IDType: uvm.VPCILocationPathIDType, } - log.G(ctx).WithField("parsed devices", specDev).Info("added windows device to spec") + log.G(ctx).WithField("parsed devices", specDev).Debug("added windows device to spec") resultDevs = append(resultDevs, specDev) } } diff --git a/internal/hcsoci/hcsdoc_lcow.go b/internal/hcsoci/hcsdoc_lcow.go index 5612cd18f0..26308a7a47 100644 --- a/internal/hcsoci/hcsdoc_lcow.go +++ b/internal/hcsoci/hcsdoc_lcow.go @@ -78,12 +78,13 @@ type linuxHostedSystem struct { } func createLinuxContainerDocument(ctx context.Context, coi *createOptionsInternal, guestRoot string) (*linuxHostedSystem, error) { + log.G(ctx).WithField("guestRoot", guestRoot).Trace("hcsshim::createLinuxContainerDoc") + spec, err := createLCOWSpec(coi) if err != nil { return nil, err } - log.G(ctx).WithField("guestRoot", guestRoot).Debug("hcsshim::createLinuxContainerDoc") return &linuxHostedSystem{ SchemaVersion: schemaversion.SchemaV21(), OciBundlePath: guestRoot, diff --git a/internal/hcsoci/hcsdoc_wcow.go b/internal/hcsoci/hcsdoc_wcow.go index 1d25b44438..3cc0eba7e1 100644 --- a/internal/hcsoci/hcsdoc_wcow.go +++ b/internal/hcsoci/hcsdoc_wcow.go @@ -19,6 +19,7 @@ import ( hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/layers" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oci" "github.com/Microsoft/hcsshim/internal/processorinfo" "github.com/Microsoft/hcsshim/internal/uvm" @@ -143,7 +144,12 @@ func ConvertCPULimits(ctx context.Context, cid string, spec *specs.Spec, maxCPUC // a container, both hosted and process isolated. It creates both v1 and v2 // container objects, WCOW only. The containers storage should have been mounted already. func createWindowsContainerDocument(ctx context.Context, coi *createOptionsInternal) (*schema1.ContainerConfig, *hcsschema.Container, error) { - log.G(ctx).Debug("hcsshim: CreateHCSContainerDocument") + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.Name: coi.actualID, + "owner": coi.actualOwner, + }) + etr.Trace("hcsshim: CreateHCSContainerDocument") + // TODO: Make this safe if exported so no null pointer dereferences. if coi.Spec == nil { @@ -227,12 +233,12 @@ func createWindowsContainerDocument(ctx context.Context, coi *createOptionsInter } else if newCPULimit > 10000 { newCPULimit = 10000 } - log.G(ctx).WithFields(logrus.Fields{ + etr.WithFields(logrus.Fields{ "hostCPUCount": hostCPUCount, "uvmCPUCount": uvmCPUCount, "oldCPULimit": cpuLimit, "newCPULimit": newCPULimit, - }).Info("rescaling CPU limit for UVM sandbox") + }).Debug("rescaling CPU limit for UVM sandbox") cpuLimit = newCPULimit } diff --git a/internal/hcsoci/network.go b/internal/hcsoci/network.go index 27bf2669d2..c6e0ed01b7 100644 --- a/internal/hcsoci/network.go +++ b/internal/hcsoci/network.go @@ -8,18 +8,18 @@ import ( "github.com/Microsoft/hcsshim/hcn" "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/resources" "github.com/Microsoft/hcsshim/internal/uvm" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" ) -func createNetworkNamespace(ctx context.Context, coi *createOptionsInternal, r *resources.Resources) error { - op := "hcsoci::createNetworkNamespace" - l := log.G(ctx).WithField(logfields.ContainerID, coi.ID) - l.Debug(op + " - Begin") - defer func() { - l.Debug(op + " - End") - }() +func createNetworkNamespace(ctx context.Context, coi *createOptionsInternal, r *resources.Resources) (err error) { + ctx, span := oc.StartSpan(ctx, "hcsoci::createNetworkNamespace") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.ContainerID, coi.ID)) ns, err := hcn.NewNamespace("").Create() if err != nil { @@ -29,7 +29,7 @@ func createNetworkNamespace(ctx context.Context, coi *createOptionsInternal, r * log.G(ctx).WithFields(logrus.Fields{ "netID": ns.Id, logfields.ContainerID: coi.ID, - }).Info("created network namespace for container") + }).Debug("created network namespace for container") r.SetNetNS(ns.Id) r.SetCreatedNetNS(true) @@ -43,7 +43,7 @@ func createNetworkNamespace(ctx context.Context, coi *createOptionsInternal, r * log.G(ctx).WithFields(logrus.Fields{ "netID": ns.Id, "endpointID": endpointID, - }).Info("added network endpoint to namespace") + }).Debug("added network endpoint to namespace") endpoints = append(endpoints, endpointID) } r.Add(&uvm.NetworkEndpoints{EndpointIDs: endpoints, Namespace: ns.Id}) diff --git a/internal/hcsoci/resources.go b/internal/hcsoci/resources.go index 46ad55660f..d42fe79f0f 100644 --- a/internal/hcsoci/resources.go +++ b/internal/hcsoci/resources.go @@ -14,7 +14,7 @@ func NormalizeProcessorCount(ctx context.Context, cid string, requestedCount, ho "id": cid, "requested count": requestedCount, "assigned count": hostCount, - }).Warn("Changing user requested cpu count to current number of processors on the host") + }).Warn("Changing user requested cpu count to current number of processors on the host") return hostCount } else { return requestedCount diff --git a/internal/hcsoci/resources_lcow.go b/internal/hcsoci/resources_lcow.go index d438738c28..e190e48e05 100644 --- a/internal/hcsoci/resources_lcow.go +++ b/internal/hcsoci/resources_lcow.go @@ -78,9 +78,9 @@ func allocateLinuxResources(ctx context.Context, coi *createOptionsInternal, r * } } - l := log.G(ctx).WithField("mount", fmt.Sprintf("%+v", mount)) + entry := log.G(ctx).WithField("mount", mount) if mount.Type == "physical-disk" { - l.Debug("hcsshim::allocateLinuxResources Hot-adding SCSI physical disk for OCI mount") + entry.Debug("hcsshim::allocateLinuxResources Hot-adding SCSI physical disk for OCI mount") uvmPathForShare = fmt.Sprintf(guestpath.LCOWGlobalMountPrefixFmt, coi.HostingSystem.UVMMountCounter()) scsiMount, err := coi.HostingSystem.AddSCSIPhysicalDisk(ctx, hostPath, uvmPathForShare, readOnly, mount.Options) if err != nil { @@ -91,7 +91,7 @@ func allocateLinuxResources(ctx context.Context, coi *createOptionsInternal, r * r.Add(scsiMount) coi.Spec.Mounts[i].Type = "none" } else if mount.Type == "virtual-disk" { - l.Debug("hcsshim::allocateLinuxResources Hot-adding SCSI virtual disk for OCI mount") + entry.Debug("hcsshim::allocateLinuxResources Hot-adding SCSI virtual disk for OCI mount") uvmPathForShare = fmt.Sprintf(guestpath.LCOWGlobalMountPrefixFmt, coi.HostingSystem.UVMMountCounter()) // if the scsi device is already attached then we take the uvm path that the function below returns @@ -149,7 +149,7 @@ func allocateLinuxResources(ctx context.Context, coi *createOptionsInternal, r * restrictAccess = true uvmPathForFile = path.Join(uvmPathForShare, fileName) } - l.Debug("hcsshim::allocateLinuxResources Hot-adding Plan9 for OCI mount") + entry.Debug("hcsshim::allocateLinuxResources Hot-adding Plan9 for OCI mount") share, err := coi.HostingSystem.AddPlan9(ctx, hostPath, uvmPathForShare, readOnly, restrictAccess, allowedNames) if err != nil { diff --git a/internal/hcsoci/resources_wcow.go b/internal/hcsoci/resources_wcow.go index fa22c8047e..76e21546b2 100644 --- a/internal/hcsoci/resources_wcow.go +++ b/internal/hcsoci/resources_wcow.go @@ -150,16 +150,17 @@ func setupMounts(ctx context.Context, coi *createOptionsInternal, r *resources.R break } } - l := log.G(ctx).WithField("mount", fmt.Sprintf("%+v", mount)) + + entry := log.G(ctx).WithField("mount", mount) if mount.Type == "physical-disk" { - l.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI physical disk for OCI mount") + entry.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI physical disk for OCI mount") scsiMount, err := coi.HostingSystem.AddSCSIPhysicalDisk(ctx, mount.Source, uvmPath, readOnly, mount.Options) if err != nil { return errors.Wrapf(err, "adding SCSI physical disk mount %+v", mount) } r.Add(scsiMount) } else if mount.Type == "virtual-disk" { - l.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI virtual disk for OCI mount") + entry.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI virtual disk for OCI mount") scsiMount, err := coi.HostingSystem.AddSCSI( ctx, mount.Source, @@ -174,7 +175,7 @@ func setupMounts(ctx context.Context, coi *createOptionsInternal, r *resources.R } r.Add(scsiMount) } else if mount.Type == "extensible-virtual-disk" { - l.Debug("hcsshim::allocateWindowsResource Hot-adding ExtensibleVirtualDisk") + entry.Debug("hcsshim::allocateWindowsResource Hot-adding ExtensibleVirtualDisk") scsiMount, err := coi.HostingSystem.AddSCSIExtensibleVirtualDisk(ctx, mount.Source, uvmPath, readOnly) if err != nil { return errors.Wrapf(err, "adding SCSI EVD mount failed %+v", mount) @@ -214,7 +215,7 @@ func setupMounts(ctx context.Context, coi *createOptionsInternal, r *resources.R } r.Add(pipe) } else { - l.Debug("hcsshim::allocateWindowsResources Hot-adding VSMB share for OCI mount") + entry.Debug("hcsshim::allocateWindowsResources Hot-adding VSMB share for OCI mount") options := coi.HostingSystem.DefaultVSMBOptions(readOnly) share, err := coi.HostingSystem.AddVSMB(ctx, mount.Source, options) if err != nil { diff --git a/internal/layers/layers.go b/internal/layers/layers.go index e0fa566b63..fb2682caaa 100644 --- a/internal/layers/layers.go +++ b/internal/layers/layers.go @@ -12,12 +12,15 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" "golang.org/x/sys/windows" "github.com/Microsoft/hcsshim/internal/guestpath" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/hcserror" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/ospath" "github.com/Microsoft/hcsshim/internal/uvm" "github.com/Microsoft/hcsshim/internal/wclayer" @@ -46,7 +49,12 @@ func NewImageLayers(vm *uvm.UtilityVM, containerRootInUVM string, layers []strin } // Release unmounts all of the layers located in the layers array. -func (layers *ImageLayers) Release(ctx context.Context, all bool) error { +func (layers *ImageLayers) Release(ctx context.Context, all bool) (err error) { + ctx, span := oc.StartSpan(ctx, "layers::Release") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute("ImageLayers", log.Format(ctx, layers))) + if layers.skipCleanup && layers.vm != nil { return nil } @@ -58,7 +66,7 @@ func (layers *ImageLayers) Release(ctx context.Context, all bool) error { if layers.vm != nil { crp = containerRootfsPath(layers.vm, layers.containerRootInUVM) } - err := UnmountContainerLayers(ctx, layers.layers, crp, layers.volumeMountPath, layers.vm, op) + err = UnmountContainerLayers(ctx, layers.layers, crp, layers.volumeMountPath, layers.vm, op) if err != nil { return err } @@ -79,7 +87,13 @@ func (layers *ImageLayers) Release(ctx context.Context, all bool) error { // // TODO dcantah: Keep better track of the layers that are added, don't simply discard the SCSI, VSMB, etc. resource types gotten inside. func MountContainerLayers(ctx context.Context, containerID string, layerFolders []string, guestRoot string, volumeMountPath string, vm *uvm.UtilityVM) (_ string, err error) { - log.G(ctx).WithField("layerFolders", layerFolders).Debug("hcsshim::mountContainerLayers") + ctx, span := oc.StartSpan(ctx, "layers::MountContainerLayers") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute("layerFolders", log.Format(ctx, layerFolders)), + trace.StringAttribute("guestRoot", guestRoot), + trace.StringAttribute("volumeMountPath", volumeMountPath)) if vm == nil { if len(layerFolders) < 2 { @@ -161,7 +175,7 @@ func MountContainerLayers(ctx context.Context, containerID string, layerFolders } // V2 UVM - log.G(ctx).WithField("os", vm.OS()).Debug("hcsshim::mountContainerLayers V2 UVM") + log.G(ctx).WithField("os", vm.OS()).Debug("layers::MountContainerLayers V2 UVM") var ( layersAdded []string @@ -268,7 +282,6 @@ func MountContainerLayers(ctx context.Context, containerID string, layerFolders if err != nil { return "", err } - log.G(ctx).Debug("hcsshim::mountContainerLayers Succeeded") return rootfs, nil } @@ -341,8 +354,12 @@ const ( ) // UnmountContainerLayers is a helper for clients to hide all the complexity of layer unmounting -func UnmountContainerLayers(ctx context.Context, layerFolders []string, containerRootPath, volumeMountPath string, vm *uvm.UtilityVM, op UnmountOperation) error { - log.G(ctx).WithField("layerFolders", layerFolders).Debug("hcsshim::unmountContainerLayers") +func UnmountContainerLayers(ctx context.Context, layerFolders []string, containerRootPath, volumeMountPath string, vm *uvm.UtilityVM, op UnmountOperation) (err error) { + ctx, span := oc.StartSpan(ctx, "layers::UnmountContainerLayers") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute("layerFolders", fmt.Sprint(layerFolders))) + if vm == nil { // Must be an argon - folders are mounted on the host if op != UnmountOperationAll { @@ -443,6 +460,12 @@ func UnmountContainerLayers(ctx context.Context, layerFolders []string, containe // GetHCSLayers converts host paths corresponding to container layers into HCS schema V2 layers func GetHCSLayers(ctx context.Context, vm *uvm.UtilityVM, paths []string) (layers []hcsschema.Layer, err error) { + ctx, span := oc.StartSpan(ctx, "layers::GetHCSLayers") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.UVMID, vm.ID()), + trace.StringAttribute("paths", fmt.Sprint(paths))) + for _, path := range paths { uvmPath, err := vm.GetVSMBUvmPath(ctx, path, true) if err != nil { @@ -484,7 +507,7 @@ func mountSandboxVolume(ctx context.Context, hostPath, volumeName string) (err e log.G(ctx).WithFields(logrus.Fields{ "hostpath": hostPath, "volumeName": volumeName, - }).Debug("mounting volume for container") + }).Trace("layers::mountSandboxVolume") if _, err := os.Stat(hostPath); os.IsNotExist(err) { if err := os.MkdirAll(hostPath, 0777); err != nil { @@ -510,10 +533,10 @@ func mountSandboxVolume(ctx context.Context, hostPath, volumeName string) (err e } // Remove volume mount point. And remove folder afterwards. -func removeSandboxMountPoint(ctx context.Context, hostPath string) error { +func removeSandboxMountPoint(ctx context.Context, hostPath string) (err error) { log.G(ctx).WithFields(logrus.Fields{ "hostpath": hostPath, - }).Debug("removing volume mount point for container") + }).Trace("layers::removeSandboxMountPoint") if err := windows.DeleteVolumeMountPoint(windows.StringToUTF16Ptr(hostPath)); err != nil { return errors.Wrap(err, "failed to delete sandbox volume mount point") diff --git a/internal/log/context.go b/internal/log/context.go new file mode 100644 index 0000000000..0cb80b336a --- /dev/null +++ b/internal/log/context.go @@ -0,0 +1,127 @@ +package log + +import ( + "context" + + "github.com/sirupsen/logrus" + "go.opencensus.io/trace" +) + +type entryContextKeyType int + +const _entryContextKey entryContextKeyType = iota + +var ( + // L is the default, blank logging entry. WithField and co. all return a copy + // of the original entry, so this will not leak fields between calls. + // + // Do NOT modify fields directly, as that will corrupt state for all users and + // is not thread safe. + L = logrus.NewEntry(logrus.StandardLogger()) + + // G is an alias for GetEntry + G = GetEntry + + // S is an alias for SetEntry + S = SetEntry + + // U is an alias for UpdateContext + U = UpdateContext +) + +// GetContext returns a `logrus.Entry` stored in context (if any), appended with +// the `TraceID, SpanID` from `ctx` if `ctx` contains an OpenCensus `trace.Span`. +// +// Unlike FromContext, this will overwrite any tracing information already +// present in the entry. +func GetEntry(ctx context.Context) *logrus.Entry { + entry := FromContext(ctx) + return entry +} + +// SetEntry updates the log entry in the context with the provided fields, and +// returns both. It is equivlent to: +// entry := G(ctx).WithFields(fields) +// ctx = WithContext(ctx, entry) +func SetEntry(ctx context.Context, fields logrus.Fields) (context.Context, *logrus.Entry) { + e := G(ctx) + if len(fields) > 0 { + e = e.WithFields(fields) + } + ctx = WithContext(ctx, e) + + return ctx, e +} + +// UpdateContext extracts the log entry from the context, and, if the entry's +// context points to a parent's of the current context, ands the entry +// to the most recent context. +// +// This allows the entry to reference the most recent context and any new +// values (such as span contexts) added to it. +func UpdateContext(ctx context.Context) context.Context { + e := FromContext(ctx) + if e.Context != ctx { + ctx = WithContext(ctx, e) + } + + return ctx +} + +// WithContext returns a context that contains the provided log entry. +// The entry can be extracted with `G` (preferred) or `FromContext`. +// +// The entry in the context is a copy of `entry` (generated by `entry.WithContext`) +func WithContext(ctx context.Context, entry *logrus.Entry) context.Context { + entry = entry.WithContext(ctx) + + return context.WithValue(ctx, _entryContextKey, entry) +} + +// FromContext returns the log entry stored in the context, if one exits, or +// the default logging entry otherwise. +func FromContext(ctx context.Context) *logrus.Entry { + entry := fromContext(ctx) + + if entry == nil { + return L.WithContext(ctx) + } + + return entry +} + +// Copy extracts the tracing Span and logging entry from the src Context, if they +// exist, and adds them to the dst Context. +// +// This is useful to share tracing and logging between contexts, but not the +// cancellation. For example, if the src Context has been cancelled but cleanup +// operations triggered by the cancellation require a non-cancelled context to +// execute +func Copy(dst context.Context, src context.Context) context.Context { + if s := trace.FromContext(src); s != nil { + dst = trace.NewContext(dst, s) + } + + if e := fromContext(src); e != nil { + dst = WithContext(dst, e) + } + + return dst +} + +func fromContext(ctx context.Context) *logrus.Entry { + e, _ := ctx.Value(_entryContextKey).(*logrus.Entry) + + return e +} + +// IsLevelEnabled checks if the level of the logger stored in the context +// (or the default logger) is greather than the specified logging level. +func IsLevelEnabled(ctx context.Context, level logrus.Level) bool { + l := L.Logger + if e := fromContext(ctx); e != nil { + l = e.Logger + } + + return l.IsLevelEnabled(level) +} diff --git a/internal/log/format.go b/internal/log/format.go new file mode 100644 index 0000000000..b6981a50e0 --- /dev/null +++ b/internal/log/format.go @@ -0,0 +1,74 @@ +package log + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net" + "reflect" + "time" +) + +const TimeFormat = time.RFC3339Nano + +func FormatTime(t time.Time) string { + return t.Format(TimeFormat) +} + +// FormatIO formats net.Conn and other types that have an `Addr()` or `Name()`. +// +// See FormatEnabled for more information. +func FormatIO(ctx context.Context, v interface{}) string { + m := make(map[string]string) + m["type"] = reflect.TypeOf(v).String() + + switch t := v.(type) { + case net.Conn: + m["local_address"] = formatAddr(t.LocalAddr()) + m["remote_address"] = formatAddr(t.RemoteAddr()) + case interface{ Addr() net.Addr }: + m["address"] = formatAddr(t.Addr()) + default: + return Format(ctx, t) + } + + return Format(ctx, m) +} + +func formatAddr(a net.Addr) string { + return a.Network() + "://" + a.String() +} + +// Format formats an object into a JSON string, without any indendtation or +// HTML escapes. +// Context is used to output a log waring if the conversion fails. +// +// This is intended primarily for `trace.StringAttribute()` +func Format(ctx context.Context, v interface{}) string { + b, err := encode(v) + if err != nil { + G(ctx).WithError(err).Warning("could not format value") + return "" + } + + return string(b) +} + +func encode(v interface{}) ([]byte, error) { + return encodeBuffer(&bytes.Buffer{}, v) +} + +func encodeBuffer(buf *bytes.Buffer, v interface{}) ([]byte, error) { + enc := json.NewEncoder(buf) + enc.SetEscapeHTML(false) + enc.SetIndent("", "") + + if err := enc.Encode(v); err != nil { + err = fmt.Errorf("could not marshall %T to JSON for logging: %w", v, err) + return nil, err + } + + // encoder.Encode appends a newline to the end + return bytes.TrimSpace(buf.Bytes()), nil +} diff --git a/internal/log/g.go b/internal/log/g.go deleted file mode 100644 index ba6b1a4a53..0000000000 --- a/internal/log/g.go +++ /dev/null @@ -1,23 +0,0 @@ -package log - -import ( - "context" - - "github.com/sirupsen/logrus" - "go.opencensus.io/trace" -) - -// G returns a `logrus.Entry` with the `TraceID, SpanID` from `ctx` if `ctx` -// contains an OpenCensus `trace.Span`. -func G(ctx context.Context) *logrus.Entry { - span := trace.FromContext(ctx) - if span != nil { - sctx := span.SpanContext() - return logrus.WithFields(logrus.Fields{ - "traceID": sctx.TraceID.String(), - "spanID": sctx.SpanID.String(), - // "parentSpanID": TODO: JTERRY75 - Try to convince OC to export this? - }) - } - return logrus.NewEntry(logrus.StandardLogger()) -} diff --git a/internal/log/hook.go b/internal/log/hook.go new file mode 100644 index 0000000000..73a7f8c29a --- /dev/null +++ b/internal/log/hook.go @@ -0,0 +1,153 @@ +package log + +import ( + "bytes" + "reflect" + "time" + + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/containerd/containerd/log" + "github.com/sirupsen/logrus" + "go.opencensus.io/trace" +) + +const nullString = "null" + +var _bytesBufferType = reflect.TypeOf(bytes.Buffer{}).String() + +// Hook serves to intercept and format `logrus.Entry`s before they are passed +// to the ETW hook. +// +// The containerd shim discards the (formatted) logrus output, and outputs only via ETW. +// The Linux GCS outputs logrus entries over stdout, which is consumed by the shim and +// then re-output via the ETW hook. +type Hook struct { + // EncodeAsJSON formats structs, maps, arrays, slices, and `bytes.Buffer` as JSON. + // Variables of `bytes.Buffer` will be converted to `[]byte`. + // + // Default is true. + EncodeAsJSON bool + + // FormatTime specifies the format for `time.Time` variables. + // An empty string disabled formatting. + // + // Default is `"github.com/containerd/containerd/log".RFC3339NanoFixed`. + TimeFormat string + + AddSpanContext bool +} + +var _ logrus.Hook = &Hook{} + +func NewHook() *Hook { + return &Hook{ + EncodeAsJSON: true, + TimeFormat: log.RFC3339NanoFixed, + AddSpanContext: true, + } +} + +func (h *Hook) Levels() []logrus.Level { + return logrus.AllLevels +} + +func (h *Hook) Fire(e *logrus.Entry) (err error) { + // JSON encode, if necessary, then add span information + h.encode(e) + h.addSpanContext(e) + + return nil +} + +func (h *Hook) encode(e *logrus.Entry) { + d := e.Data + + formatTime := len(h.TimeFormat) > 0 + if !(h.EncodeAsJSON || formatTime) { + return + } + + // todo: replace these with constraints.Integer, constraints.Float, etc with go1.18 + for k, v := range d { + switch vv := v.(type) { + // built in types + case bool, string, error, uintptr, + int8, int16, int32, int64, int, + uint8, uint32, uint64, uint, + float32, float64: + continue + case time.Time: + if formatTime { + d[k] = vv.Format(h.TimeFormat) + } + continue + case bytes.Buffer, *bytes.Buffer: + // this resolves `vv` to `interface{}`, so cannot use `vv.Bytes` + // Could move to below the `reflect.Indirect()` call below, but + // that would require additional typematching and dereferencing, + // regardless. Easier to keep these duplicate + // branches here + if vp, ok := vv.(bytes.Buffer); ok { + vv = &vp + } + v = (vv.(*bytes.Buffer)).Bytes() + // case bytes.Buffer: + // v = vv.Bytes() + // case *bytes.Buffer: + // v = vv.Bytes() + } + if !h.EncodeAsJSON { + continue + } + + // dereference any pointers + rv := reflect.Indirect(reflect.ValueOf(v)) + // check if `v` is a null pointer + if !rv.IsValid() { + d[k] = nullString + continue + } + + switch rv.Kind() { + case reflect.Map, reflect.Struct, reflect.Array, reflect.Slice: + default: + continue + } + + b, err := encode(v) + if err != nil { + // Errors are written to stderr (ie, to `panic.log`) and stops the remaining + // hooks (ie, exporting to ETW) from firing. So add encoding errors to + // the entry data to be written out, but keep on processing. + d[k+"-"+logrus.ErrorKey] = err.Error() + } + + // if `err != nil`, then `b == nil` and this will be the the empty string + d[k] = string(b) + } +} + +func (h *Hook) addSpanContext(e *logrus.Entry) { + ctx := e.Context + if ctx == nil { + return + } + span := trace.FromContext(ctx) + if span == nil { + return + } + sctx := span.SpanContext() + e.Data[logfields.TraceID] = sctx.TraceID.String() + e.Data[logfields.SpanID] = sctx.SpanID.String() +} + +// byteArrayValueToSlice creates a slice from the underlying data in the [n]byte array +// rv *MUST* be of type byte array +func byteArrayValueToSlice(rv reflect.Value) []byte { + l := rv.Len() + b := make([]byte, l) + for i := 0; i < rv.Len(); i++ { + b[i] = byte(rv.Index(i).Uint()) + } + return b +} diff --git a/internal/log/scrub.go b/internal/log/scrub.go index d51e0fd89f..c7d8d120f7 100644 --- a/internal/log/scrub.go +++ b/internal/log/scrub.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "errors" - "strings" "sync/atomic" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" @@ -38,6 +37,7 @@ func SetScrubbing(enable bool) { // IsScrubbingEnabled checks if scrubbing is enabled func IsScrubbingEnabled() bool { v := atomic.LoadInt32(&_scrub) + return v != 0 } @@ -56,11 +56,12 @@ func ScrubProcessParameters(s string) (string, error) { } pp.Environment = map[string]string{_scrubbedReplacement: _scrubbedReplacement} - buf := bytes.NewBuffer(b[:0]) - if err := encode(buf, pp); err != nil { + b, err := encodeBuffer(bytes.NewBuffer(b[:0]), pp) + if err != nil { return "", err } - return strings.TrimSpace(buf.String()), nil + + return string(b), nil } // ScrubBridgeCreate scrubs requests sent over the bridge of type @@ -84,8 +85,10 @@ func scrubBridgeCreate(m genMap) error { return err } m["ContainerConfig"] = string(b) + return nil } + return ErrUnknownType } @@ -97,10 +100,12 @@ func scrubLinuxHostedSystem(m genMap) error { if m, ok := index(m, "process"); ok { if _, ok := m["env"]; ok { m["env"] = []string{_scrubbedReplacement} + return nil } } } + return ErrUnknownType } @@ -150,21 +155,12 @@ func scrubBytes(b []byte, scrub scrubberFunc) ([]byte, error) { return nil, err } - buf := &bytes.Buffer{} - if err := encode(buf, m); err != nil { + b, err := encode(m) + if err != nil { return nil, err } - return bytes.TrimSpace(buf.Bytes()), nil -} - -func encode(buf *bytes.Buffer, v interface{}) error { - enc := json.NewEncoder(buf) - enc.SetEscapeHTML(false) - if err := enc.Encode(v); err != nil { - return err - } - return nil + return b, nil } func isRequestBase(m genMap) bool { diff --git a/internal/logfields/fields.go b/internal/logfields/fields.go index cf2c166d9b..7f2dfe2626 100644 --- a/internal/logfields/fields.go +++ b/internal/logfields/fields.go @@ -3,21 +3,42 @@ package logfields const ( // Identifiers + Name = "name" + Operation = "operation" + + ID = "id" ContainerID = "cid" - UVMID = "uvm-id" + ExecID = "eid" ProcessID = "pid" + TaskID = "tid" + UVMID = "uvm-id" + + // networking and IO + + File = "file" + Path = "path" + Bytes = "bytes" + Pipe = "pipe" // Common Misc - // Timeout represents an operation timeout. - Timeout = "timeout" + Attempt = "attemptNo" JSON = "json" + // Time + + StartTime = "startTime" + EndTime = "endTime" + Duration = "duration" + Timeout = "timeout" + // Keys/values Field = "field" + Key = "key" OCIAnnotation = "oci-annotation" Value = "value" + Options = "options" // Golang type's @@ -29,4 +50,10 @@ const ( // runhcs VMShimOperation = "vmshim-op" + + // logging and tracing + + TraceID = "traceID" + SpanID = "spanID" + ParentSpanID = "parentSpanID" ) diff --git a/internal/oc/errors.go b/internal/oc/errors.go new file mode 100644 index 0000000000..38adbf52cf --- /dev/null +++ b/internal/oc/errors.go @@ -0,0 +1,58 @@ +package oc + +import ( + "context" + "errors" + + "go.opencensus.io/trace" + // "github.com/Microsoft/hcsshim/internal/hcs" +) + +// todo: break import cycle with "internal/hcs" + +func toStatusCode(err error) uint32 { + switch { + case checkErrors(err, context.Canceled): + return trace.StatusCodeCancelled + // case checkErrors(err, hcs.ErrVmcomputeInvalidJSON): + // return trace.StatusCodeInvalidArgument + case checkErrors(err, context.DeadlineExceeded): + return trace.StatusCodeDeadlineExceeded + // case checkErrors(err): + // return trace.StatusCodeNotFound + // case checkErrors(err): + // return trace.StatusCodeAlreadyExists + // case checkErrors(err): + // return trace.StatusCodePermissionDenied + // case checkErrors(err): + // return trace.StatusCodeResourceExhausted + // case checkErrors(err): + // return trace.StatusCodeFailedPrecondition + // case checkErrors(err): + // return trace.StatusCodeAborted + // case checkErrors(err): + // return trace.StatusCodeOutOfRange + // case checkErrors(err): + // return trace.StatusCodeUnimplemented + // case checkErrors(err): + // return trace.StatusCodeInternal + // case checkErrors(err): + // return trace.StatusCodeUnavailable + // case checkErrors(err): + // return trace.StatusCodeDataLoss + // case checkErrors(err): + // return trace.StatusCodeUnauthenticated + default: + return trace.StatusCodeUnknown + } +} + +func checkErrors(err error, errs ...error) bool { + for _, e := range errs { + if errors.Is(err, e) { + return true + } + } + + return false +} diff --git a/internal/oc/exporter.go b/internal/oc/exporter.go index f428bdaf72..ba8bdbe4b8 100644 --- a/internal/oc/exporter.go +++ b/internal/oc/exporter.go @@ -3,19 +3,23 @@ package oc import ( "github.com/sirupsen/logrus" "go.opencensus.io/trace" + + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" ) -var _ = (trace.Exporter)(&LogrusExporter{}) +const spanMessage = "Span" // LogrusExporter is an OpenCensus `trace.Exporter` that exports // `trace.SpanData` to logrus output. -type LogrusExporter struct { -} +type LogrusExporter struct{} + +var _ trace.Exporter = &LogrusExporter{} // ExportSpan exports `s` based on the the following rules: // -// 1. All output will contain `s.Attributes`, `s.TraceID`, `s.SpanID`, -// `s.ParentSpanID` for correlation +// 1. All output will contain `s.Attributes`, `s.SpanKind`, `s.TraceID`, +// `s.SpanID`, and `s.ParentSpanID` for correlation // // 2. Any calls to .Annotate will not be supported. // @@ -23,21 +27,55 @@ type LogrusExporter struct { // `s.Status.Code != 0` in which case it will be written at `logrus.ErrorLevel` // providing `s.Status.Message` as the error value. func (le *LogrusExporter) ExportSpan(s *trace.SpanData) { - // Combine all span annotations with traceID, spanID, parentSpanID - baseEntry := logrus.WithFields(logrus.Fields(s.Attributes)) - baseEntry.Data["traceID"] = s.TraceID.String() - baseEntry.Data["spanID"] = s.SpanID.String() - baseEntry.Data["parentSpanID"] = s.ParentSpanID.String() - baseEntry.Data["startTime"] = s.StartTime - baseEntry.Data["endTime"] = s.EndTime - baseEntry.Data["duration"] = s.EndTime.Sub(s.StartTime).String() - baseEntry.Data["name"] = s.Name - baseEntry.Time = s.StartTime + if s.DroppedAnnotationCount > 0 { + logrus.WithFields(logrus.Fields{ + "name": s.Name, + logfields.TraceID: s.TraceID.String(), + logfields.SpanID: s.SpanID.String(), + "dropped": s.DroppedAttributeCount, + "maxAttributes": len(s.Attributes), + }).Warning("span had dropped attributes") + } + + // Combine all span annotations with traceID, spanID, parentSpanID, and error + entry := logrus.WithFields(logrus.Fields(s.Attributes)) + // All span fields are string, so we can safely skip overhead in entry.WithFields + // and add them directly to entry.Data. + // Avoid growing the entry.Data map and reallocating buckets by creating new + // `logrus.Fields` and copying data over. + data := make(logrus.Fields, len(entry.Data)+9) // should only add 9 new entries + for k, v := range entry.Data { //copy old data + data[k] = v + } + data[logfields.Name] = s.Name + data[logfields.TraceID] = s.TraceID.String() + data[logfields.SpanID] = s.SpanID.String() + data[logfields.ParentSpanID] = s.ParentSpanID.String() + data[logfields.StartTime] = log.FormatTime(s.StartTime) + data[logfields.EndTime] = log.FormatTime(s.EndTime) + data[logfields.Duration] = s.EndTime.Sub(s.StartTime).String() + if sk := spanKindToString(s.SpanKind); sk != "" { + data["spanKind"] = sk + } level := logrus.InfoLevel if s.Status.Code != 0 { level = logrus.ErrorLevel - baseEntry.Data[logrus.ErrorKey] = s.Status.Message + data[logrus.ErrorKey] = s.Status.Message + } + + entry.Data = data + entry.Time = s.StartTime + entry.Log(level, spanMessage) +} + +// GetSpanName checks if the entry appears to be span entry exported by the `LogrusExporter` +// and returns the the span name. +// +// This is intended to be used with the winio ETW exporter. +func GetSpanName(e *logrus.Entry) string { + if s, ok := (e.Data[logfields.Name]).(string); ok && e.Message == spanMessage { + return s } - baseEntry.Log(level, "Span") + return "" } diff --git a/internal/oc/span.go b/internal/oc/span.go index fee4765cbc..027eff9ee1 100644 --- a/internal/oc/span.go +++ b/internal/oc/span.go @@ -1,17 +1,60 @@ package oc import ( + "context" + + "github.com/Microsoft/hcsshim/internal/log" "go.opencensus.io/trace" ) +var DefaultSampler = trace.AlwaysSample() + // SetSpanStatus sets `span.SetStatus` to the proper status depending on `err`. If // `err` is `nil` assumes `trace.StatusCodeOk`. func SetSpanStatus(span *trace.Span, err error) { status := trace.Status{} if err != nil { - // TODO: JTERRY75 - Handle errors in a non-generic way - status.Code = trace.StatusCodeUnknown + status.Code = int32(toStatusCode(err)) status.Message = err.Error() } span.SetStatus(status) } + +// StartSpan wraps go.opencensus.io/oc.StartSpan, but, if the span is sampling, +// adds a log entry to the context that points to the newly created span. +func StartSpan(ctx context.Context, name string, o ...trace.StartOption) (context.Context, *trace.Span) { + ctx, s := trace.StartSpan(ctx, name, o...) + return update(ctx, s) +} + +// StartSpanWithRemoteParent wraps go.opencensus.io/oc.StartSpanWithRemoteParent. +// +// See StartSpan for more information. +func StartSpanWithRemoteParent(ctx context.Context, name string, parent trace.SpanContext, o ...trace.StartOption) (context.Context, *trace.Span) { + ctx, s := trace.StartSpan(ctx, name, o...) + return update(ctx, s) +} + +func update(ctx context.Context, s *trace.Span) (context.Context, *trace.Span) { + if s.IsRecordingEvents() { + ctx = log.UpdateContext(ctx) + } + + return ctx, s +} + +var WithServerSpanKind = trace.WithSpanKind(trace.SpanKindServer) +var WithClientSpanKind = trace.WithSpanKind(trace.SpanKindServer) + +func spanKindToString(sk int) string { + switch sk { + case trace.SpanKindUnspecified: + return "unknown" + case trace.SpanKindClient: + return "client" + case trace.SpanKindServer: + return "server" + default: + return "" + } +} diff --git a/internal/resources/resources.go b/internal/resources/resources.go index 90fe116ae5..234fa70500 100644 --- a/internal/resources/resources.go +++ b/internal/resources/resources.go @@ -9,7 +9,10 @@ import ( "github.com/Microsoft/hcsshim/internal/credentials" "github.com/Microsoft/hcsshim/internal/layers" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/uvm" + "go.opencensus.io/trace" ) // NetNS returns the network namespace for the container @@ -95,8 +98,15 @@ func NewContainerResources(id string) *Resources { // ReleaseResources releases/frees all of the resources associated with a container. This includes // Plan9 shares, vsmb mounts, pipe mounts, network endpoints, scsi mounts, vpci devices and layers. // TODO: make method on Resources struct. -func ReleaseResources(ctx context.Context, r *Resources, vm *uvm.UtilityVM, all bool) error { +// TODO: group together all the different errors into one +func ReleaseResources(ctx context.Context, r *Resources, vm *uvm.UtilityVM, all bool) (err error) { + ctx, span := oc.StartSpan(ctx, "resources::ReleaseResources") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + if vm != nil { + span.AddAttributes(trace.StringAttribute(logfields.ID, vm.ID())) + if r.addedNetNSToVM { if err := vm.TearDownNetworking(ctx, r.netNS); err != nil { log.G(ctx).Warn(err) diff --git a/internal/uvm/computeagent.go b/internal/uvm/computeagent.go index 44b328ad37..7993204bf4 100644 --- a/internal/uvm/computeagent.go +++ b/internal/uvm/computeagent.go @@ -65,7 +65,7 @@ func (ca *computeAgent) AssignPCI(ctx context.Context, req *computeagent.AssignP "containerID": req.ContainerID, "deviceID": req.DeviceID, "virtualFunctionIndex": req.VirtualFunctionIndex, - }).Info("AssignPCI request") + }).Trace("computeAgent::AssignPCI") if req.DeviceID == "" { return nil, status.Error(codes.InvalidArgument, "received empty field in request") @@ -82,7 +82,7 @@ func (ca *computeAgent) RemovePCI(ctx context.Context, req *computeagent.RemoveP log.G(ctx).WithFields(logrus.Fields{ "containerID": req.ContainerID, "deviceID": req.DeviceID, - }).Info("RemovePCI request") + }).Trace("computeAgent::RemovePCI") if req.DeviceID == "" { return nil, status.Error(codes.InvalidArgument, "received empty field in request") @@ -97,9 +97,9 @@ func (ca *computeAgent) RemovePCI(ctx context.Context, req *computeagent.RemoveP func (ca *computeAgent) AddNIC(ctx context.Context, req *computeagent.AddNICInternalRequest) (*computeagent.AddNICInternalResponse, error) { log.G(ctx).WithFields(logrus.Fields{ "containerID": req.ContainerID, - "endpoint": req.Endpoint, + "endpoint": req.Endpoint.String(), "nicID": req.NicID, - }).Info("AddNIC request") + }).Trace("computeAgent::AddNIC") if req.NicID == "" || req.Endpoint == nil { return nil, status.Error(codes.InvalidArgument, "received empty field in request") @@ -141,9 +141,9 @@ func (ca *computeAgent) AddNIC(ctx context.Context, req *computeagent.AddNICInte // ModifyNIC will modify a NIC from the computeagent services hosting UVM. func (ca *computeAgent) ModifyNIC(ctx context.Context, req *computeagent.ModifyNICInternalRequest) (*computeagent.ModifyNICInternalResponse, error) { log.G(ctx).WithFields(logrus.Fields{ + "endpoint": req.Endpoint.String(), "nicID": req.NicID, - "endpoint": req.Endpoint, - }).Info("ModifyNIC request") + }).Trace("computeAgent::ModifyNIC") if req.NicID == "" || req.Endpoint == nil || req.IovPolicySettings == nil { return nil, status.Error(codes.InvalidArgument, "received empty field in request") @@ -191,10 +191,9 @@ func (ca *computeAgent) ModifyNIC(ctx context.Context, req *computeagent.ModifyN // DeleteNIC will delete a NIC from the computeagent services hosting UVM. func (ca *computeAgent) DeleteNIC(ctx context.Context, req *computeagent.DeleteNICInternalRequest) (*computeagent.DeleteNICInternalResponse, error) { log.G(ctx).WithFields(logrus.Fields{ - "containerID": req.ContainerID, - "nicID": req.NicID, - "endpoint": req.Endpoint, - }).Info("DeleteNIC request") + "endpoint": req.Endpoint.String(), + "nicID": req.NicID, + }).Trace("computeAgent::DeleteNIC") if req.NicID == "" || req.Endpoint == nil { return nil, status.Error(codes.InvalidArgument, "received empty field in request") @@ -240,7 +239,7 @@ func setupAndServe(ctx context.Context, caAddr string, vm *UtilityVM) error { } computeagent.RegisterComputeAgentService(s, &computeAgent{vm}) - log.G(ctx).WithField("address", l.Addr().String()).Info("serving compute agent") + log.G(ctx).WithField("address", log.FormatIO(ctx, l)).Debug("serving compute agent") go func() { defer l.Close() if err := trapClosedConnErr(s.Serve(ctx, l)); err != nil { diff --git a/internal/uvm/create.go b/internal/uvm/create.go index b07a78bdd3..9b36372ef0 100644 --- a/internal/uvm/create.go +++ b/internal/uvm/create.go @@ -243,7 +243,7 @@ func (uvm *UtilityVM) create(ctx context.Context, doc interface{}) error { // Close terminates and releases resources associated with the utility VM. func (uvm *UtilityVM) Close() (err error) { - ctx, span := trace.StartSpan(context.Background(), "uvm::Close") + ctx, span := oc.StartSpan(context.Background(), "uvm::Close") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute(logfields.UVMID, uvm.id)) diff --git a/internal/uvm/create_lcow.go b/internal/uvm/create_lcow.go index 79a065454e..39a30545f8 100644 --- a/internal/uvm/create_lcow.go +++ b/internal/uvm/create_lcow.go @@ -707,7 +707,7 @@ func makeLCOWDoc(ctx context.Context, opts *OptionsLCOW, uvm *UtilityVM) (_ *hcs // consumes a set of options derived from various defaults and options // expressed as annotations. func CreateLCOW(ctx context.Context, opts *OptionsLCOW) (_ *UtilityVM, err error) { - ctx, span := trace.StartSpan(ctx, "uvm::CreateLCOW") + ctx, span := oc.StartSpan(ctx, "uvm::CreateLCOW") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -720,7 +720,10 @@ func CreateLCOW(ctx context.Context, opts *OptionsLCOW) (_ *UtilityVM, err error } span.AddAttributes(trace.StringAttribute(logfields.UVMID, opts.ID)) - log.G(ctx).WithField("options", fmt.Sprintf("%+v", opts)).Debug("uvm::CreateLCOW options") + log.G(ctx).WithFields(logrus.Fields{ + logfields.Options: opts.Options, + "options-lcow": opts, + }).Debug("uvm::CreateLCOW options") // We dont serialize OutputHandler so if it is missing we need to put it back to the default. if opts.OutputHandler == nil { diff --git a/internal/uvm/create_wcow.go b/internal/uvm/create_wcow.go index ba11257b56..09352b8646 100644 --- a/internal/uvm/create_wcow.go +++ b/internal/uvm/create_wcow.go @@ -8,11 +8,12 @@ import ( "os" "path/filepath" + "github.com/Microsoft/go-winio" + "github.com/Microsoft/go-winio/pkg/guid" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "go.opencensus.io/trace" - "github.com/Microsoft/go-winio" - "github.com/Microsoft/go-winio/pkg/guid" "github.com/Microsoft/hcsshim/internal/gcs" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" @@ -233,7 +234,7 @@ func prepareConfigDoc(ctx context.Context, uvm *UtilityVM, opts *OptionsWCOW, uv // - The scratch is always attached to SCSI 0:0 // func CreateWCOW(ctx context.Context, opts *OptionsWCOW) (_ *UtilityVM, err error) { - ctx, span := trace.StartSpan(ctx, "uvm::CreateWCOW") + ctx, span := oc.StartSpan(ctx, "uvm::CreateWCOW") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -246,7 +247,10 @@ func CreateWCOW(ctx context.Context, opts *OptionsWCOW) (_ *UtilityVM, err error } span.AddAttributes(trace.StringAttribute(logfields.UVMID, opts.ID)) - log.G(ctx).WithField("options", fmt.Sprintf("%+v", opts)).Debug("uvm::CreateWCOW options") + log.G(ctx).WithFields(logrus.Fields{ + logfields.Options: opts.Options, + "options-wcow": opts, + }).Debug("uvm::CreateWCOW options") uvm := &UtilityVM{ id: opts.ID, diff --git a/internal/uvm/network.go b/internal/uvm/network.go index 03509ad882..5f6d7c176a 100644 --- a/internal/uvm/network.go +++ b/internal/uvm/network.go @@ -12,6 +12,7 @@ import ( "github.com/containerd/ttrpc" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" "github.com/Microsoft/hcsshim/hcn" "github.com/Microsoft/hcsshim/internal/hcs/resourcepaths" @@ -19,6 +20,7 @@ import ( "github.com/Microsoft/hcsshim/internal/hns" "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/ncproxyttrpc" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" "github.com/Microsoft/hcsshim/osversion" @@ -98,13 +100,11 @@ func (uvm *UtilityVM) SetupNetworkNamespace(ctx context.Context, nsid string) er } // GetNamespaceEndpoints gets all endpoints in `netNS` -func GetNamespaceEndpoints(ctx context.Context, netNS string) ([]*hns.HNSEndpoint, error) { - op := "uvm::GetNamespaceEndpoints" - l := log.G(ctx).WithField("netns-id", netNS) - l.Debug(op + " - Begin") - defer func() { - l.Debug(op + " - End") - }() +func GetNamespaceEndpoints(ctx context.Context, netNS string) (_ []*hns.HNSEndpoint, err error) { + ctx, span := oc.StartSpan(ctx, "uvm::GetNamespaceEndpoints") //nolint:ineffassign,staticcheck + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute("netns-id", netNS)) ids, err := hns.GetNamespaceEndpoints(netNS) if err != nil { diff --git a/internal/uvm/plan9.go b/internal/uvm/plan9.go index d8fce975f8..9de1b046ae 100644 --- a/internal/uvm/plan9.go +++ b/internal/uvm/plan9.go @@ -11,9 +11,13 @@ import ( "github.com/Microsoft/hcsshim/internal/hcs" "github.com/Microsoft/hcsshim/internal/hcs/resourcepaths" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" "github.com/Microsoft/hcsshim/osversion" + "go.opencensus.io/trace" ) // Plan9Share is a struct containing host paths for the UVM @@ -34,7 +38,18 @@ func (p9 *Plan9Share) Release(ctx context.Context) error { const plan9Port = 564 // AddPlan9 adds a Plan9 share to a utility VM. -func (uvm *UtilityVM) AddPlan9(ctx context.Context, hostPath string, uvmPath string, readOnly bool, restrict bool, allowedNames []string) (*Plan9Share, error) { +func (uvm *UtilityVM) AddPlan9(ctx context.Context, hostPath string, uvmPath string, readOnly bool, restrict bool, allowedNames []string) (_ *Plan9Share, err error) { + ctx, span := oc.StartSpan(ctx, "uvm::AddPlan9") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute(logfields.UVMID, uvm.id), + trace.StringAttribute("hostPath", hostPath), + trace.StringAttribute("uvmPath", uvmPath), + trace.BoolAttribute("readOnly", readOnly), + trace.BoolAttribute("restrict", restrict), + trace.StringAttribute("allowedNamed", log.Format(ctx, allowedNames))) + if uvm.operatingSystem != "linux" { return nil, errNotSupported } @@ -110,7 +125,15 @@ func (uvm *UtilityVM) AddPlan9(ctx context.Context, hostPath string, uvmPath str // RemovePlan9 removes a Plan9 share from a utility VM. Each Plan9 share is ref-counted // and only actually removed when the ref-count drops to zero. -func (uvm *UtilityVM) RemovePlan9(ctx context.Context, share *Plan9Share) error { +func (uvm *UtilityVM) RemovePlan9(ctx context.Context, share *Plan9Share) (err error) { + ctx, span := oc.StartSpan(ctx, "uvm::RemovePlan9") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute(logfields.UVMID, uvm.id), + trace.StringAttribute("uvmPath", share.name), + trace.StringAttribute("uvmPath", share.uvmPath)) + if uvm.operatingSystem != "linux" { return errNotSupported } diff --git a/internal/uvm/start.go b/internal/uvm/start.go index 412717aca6..6f65a2be5c 100644 --- a/internal/uvm/start.go +++ b/internal/uvm/start.go @@ -115,7 +115,7 @@ func parseLogrus(vmid string) func(r io.Reader) { break } fields[logfields.UVMID] = vmid - fields["vm.time"] = gcsEntry.Time + fields["vm.time"] = log.FormatTime(gcsEntry.Time) e.Log(gcsEntry.Level, gcsEntry.Message) } } diff --git a/internal/uvm/vsmb.go b/internal/uvm/vsmb.go index 348058c7ef..55d52b9ab3 100644 --- a/internal/uvm/vsmb.go +++ b/internal/uvm/vsmb.go @@ -13,12 +13,15 @@ import ( "unsafe" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" "golang.org/x/sys/windows" "github.com/Microsoft/hcsshim/internal/hcs" "github.com/Microsoft/hcsshim/internal/hcs/resourcepaths" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/winapi" "github.com/Microsoft/hcsshim/osversion" @@ -161,7 +164,16 @@ func forceNoDirectMap(path string) (bool, error) { // AddVSMB adds a VSMB share to a Windows utility VM. Each VSMB share is ref-counted and // only added if it isn't already. This is used for read-only layers, mapped directories // to a container, and for mapped pipes. -func (uvm *UtilityVM) AddVSMB(ctx context.Context, hostPath string, options *hcsschema.VirtualSmbShareOptions) (*VSMBShare, error) { +func (uvm *UtilityVM) AddVSMB(ctx context.Context, hostPath string, options *hcsschema.VirtualSmbShareOptions) (_ *VSMBShare, err error) { + ctx, span := oc.StartSpan(ctx, "uvm::AddVSMB") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute(logfields.UVMID, uvm.id), + trace.StringAttribute("hostPath", hostPath), + trace.BoolAttribute("readOnly", options.ReadOnly), + trace.BoolAttribute("restrict", options.RestrictFileAccess)) + if uvm.operatingSystem != "windows" { return nil, errNotSupported } @@ -197,7 +209,7 @@ func (uvm *UtilityVM) AddVSMB(ctx context.Context, hostPath string, options *hcs if force, err := forceNoDirectMap(hostPath); err != nil { return nil, err } else if force { - log.G(ctx).WithField("path", hostPath).Info("Forcing NoDirectmap for VSMB mount") + log.G(ctx).WithField("hostPath", hostPath).Debug("Forcing NoDirectmap for VSMB mount") options.NoDirectmap = true } @@ -230,9 +242,9 @@ func (uvm *UtilityVM) AddVSMB(ctx context.Context, hostPath string, options *hcs log.G(ctx).WithFields(logrus.Fields{ "name": share.name, "path": hostPath, - "options": fmt.Sprintf("%+#v", options), + "options": options, "operation": requestType, - }).Info("Modifying VSMB share") + }).Debug("Modifying VSMB share") modification := &hcsschema.ModifySettingRequest{ RequestType: requestType, Settings: hcsschema.VirtualSmbShare{ @@ -257,7 +269,15 @@ func (uvm *UtilityVM) AddVSMB(ctx context.Context, hostPath string, options *hcs // RemoveVSMB removes a VSMB share from a utility VM. Each VSMB share is ref-counted // and only actually removed when the ref-count drops to zero. -func (uvm *UtilityVM) RemoveVSMB(ctx context.Context, hostPath string, readOnly bool) error { +func (uvm *UtilityVM) RemoveVSMB(ctx context.Context, hostPath string, readOnly bool) (err error) { + ctx, span := oc.StartSpan(ctx, "uvm::RemoveVSMB") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute(logfields.UVMID, uvm.id), + trace.BoolAttribute("readOnly", readOnly), + trace.StringAttribute("hostPath", hostPath)) + if uvm.operatingSystem != "windows" { return errNotSupported } @@ -394,6 +414,12 @@ func (vsmb *VSMBShare) GobDecode(data []byte) error { // clone VSMB share we just need to add it into the config doc of that VM and increase the // vsmb counter. func (vsmb *VSMBShare) Clone(ctx context.Context, vm *UtilityVM, cd *cloneData) error { + log.G(ctx).WithFields(logrus.Fields{ + "hostPath": vsmb.HostPath, + "guestPath": vsmb.guestPath, + "name": vsmb.name, + }).Trace("vsmb::Clone") + cd.doc.VirtualMachine.Devices.VirtualSmb.Shares = append(cd.doc.VirtualMachine.Devices.VirtualSmb.Shares, hcsschema.VirtualSmbShare{ Name: vsmb.name, Path: vsmb.HostPath, diff --git a/internal/vmcompute/vmcompute.go b/internal/vmcompute/vmcompute.go index ef2e3708b8..ee3bf80559 100644 --- a/internal/vmcompute/vmcompute.go +++ b/internal/vmcompute/vmcompute.go @@ -4,6 +4,7 @@ package vmcompute import ( gcontext "context" + "errors" "syscall" "time" @@ -87,8 +88,8 @@ func execute(ctx gcontext.Context, timeout time.Duration, f func() error) error }() select { case <-ctx.Done(): - if ctx.Err() == gcontext.DeadlineExceeded { - log.G(ctx).WithField(logfields.Timeout, timeout). + if errors.Is(ctx.Err(), gcontext.DeadlineExceeded) { + log.G(ctx).WithField(logfields.Timeout, timeout.String()). Warning("Syscall did not complete within operation timeout. This may indicate a platform issue. If it appears to be making no forward progress, obtain the stacks and see if there is a syscall stuck in the platform API for a significant length of time.") } return ctx.Err() @@ -98,7 +99,7 @@ func execute(ctx gcontext.Context, timeout time.Duration, f func() error) error } func HcsEnumerateComputeSystems(ctx gcontext.Context, query string) (computeSystems, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsEnumerateComputeSystems") + ctx, span := oc.StartSpan(ctx, "HcsEnumerateComputeSystems") defer span.End() defer func() { if result != "" { @@ -125,7 +126,7 @@ func HcsEnumerateComputeSystems(ctx gcontext.Context, query string) (computeSyst } func HcsCreateComputeSystem(ctx gcontext.Context, id string, configuration string, identity syscall.Handle) (computeSystem HcsSystem, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsCreateComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsCreateComputeSystem") defer span.End() defer func() { if result != "" { @@ -150,7 +151,7 @@ func HcsCreateComputeSystem(ctx gcontext.Context, id string, configuration strin } func HcsOpenComputeSystem(ctx gcontext.Context, id string) (computeSystem HcsSystem, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsOpenComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsOpenComputeSystem") defer span.End() defer func() { if result != "" { @@ -170,7 +171,7 @@ func HcsOpenComputeSystem(ctx gcontext.Context, id string) (computeSystem HcsSys } func HcsCloseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem) (hr error) { - ctx, span := trace.StartSpan(ctx, "HcsCloseComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsCloseComputeSystem") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -180,7 +181,7 @@ func HcsCloseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem) (hr er } func HcsStartComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsStartComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsStartComputeSystem") defer span.End() defer func() { if result != "" { @@ -203,7 +204,7 @@ func HcsStartComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, option } func HcsShutdownComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsShutdownComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsShutdownComputeSystem") defer span.End() defer func() { if result != "" { @@ -226,7 +227,7 @@ func HcsShutdownComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, opt } func HcsTerminateComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsTerminateComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsTerminateComputeSystem") defer span.End() defer func() { if result != "" { @@ -249,7 +250,7 @@ func HcsTerminateComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, op } func HcsPauseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsPauseComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsPauseComputeSystem") defer span.End() defer func() { if result != "" { @@ -272,7 +273,7 @@ func HcsPauseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, option } func HcsResumeComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsResumeComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsResumeComputeSystem") defer span.End() defer func() { if result != "" { @@ -295,7 +296,7 @@ func HcsResumeComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, optio } func HcsGetComputeSystemProperties(ctx gcontext.Context, computeSystem HcsSystem, propertyQuery string) (properties, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsGetComputeSystemProperties") + ctx, span := oc.StartSpan(ctx, "HcsGetComputeSystemProperties") defer span.End() defer func() { if result != "" { @@ -322,7 +323,7 @@ func HcsGetComputeSystemProperties(ctx gcontext.Context, computeSystem HcsSystem } func HcsModifyComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, configuration string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsModifyComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsModifyComputeSystem") defer span.End() defer func() { if result != "" { @@ -343,7 +344,7 @@ func HcsModifyComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, confi } func HcsModifyServiceSettings(ctx gcontext.Context, settings string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsModifyServiceSettings") + ctx, span := oc.StartSpan(ctx, "HcsModifyServiceSettings") defer span.End() defer func() { if result != "" { @@ -364,7 +365,7 @@ func HcsModifyServiceSettings(ctx gcontext.Context, settings string) (result str } func HcsRegisterComputeSystemCallback(ctx gcontext.Context, computeSystem HcsSystem, callback uintptr, context uintptr) (callbackHandle HcsCallback, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsRegisterComputeSystemCallback") + ctx, span := oc.StartSpan(ctx, "HcsRegisterComputeSystemCallback") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -374,7 +375,7 @@ func HcsRegisterComputeSystemCallback(ctx gcontext.Context, computeSystem HcsSys } func HcsUnregisterComputeSystemCallback(ctx gcontext.Context, callbackHandle HcsCallback) (hr error) { - ctx, span := trace.StartSpan(ctx, "HcsUnregisterComputeSystemCallback") + ctx, span := oc.StartSpan(ctx, "HcsUnregisterComputeSystemCallback") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -384,7 +385,7 @@ func HcsUnregisterComputeSystemCallback(ctx gcontext.Context, callbackHandle Hcs } func HcsCreateProcess(ctx gcontext.Context, computeSystem HcsSystem, processParameters string) (processInformation HcsProcessInformation, process HcsProcess, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsCreateProcess") + ctx, span := oc.StartSpan(ctx, "HcsCreateProcess") defer span.End() defer func() { if result != "" { @@ -410,7 +411,7 @@ func HcsCreateProcess(ctx gcontext.Context, computeSystem HcsSystem, processPara } func HcsOpenProcess(ctx gcontext.Context, computeSystem HcsSystem, pid uint32) (process HcsProcess, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsOpenProcess") + ctx, span := oc.StartSpan(ctx, "HcsOpenProcess") defer span.End() defer func() { if result != "" { @@ -431,7 +432,7 @@ func HcsOpenProcess(ctx gcontext.Context, computeSystem HcsSystem, pid uint32) ( } func HcsCloseProcess(ctx gcontext.Context, process HcsProcess) (hr error) { - ctx, span := trace.StartSpan(ctx, "HcsCloseProcess") + ctx, span := oc.StartSpan(ctx, "HcsCloseProcess") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -441,7 +442,7 @@ func HcsCloseProcess(ctx gcontext.Context, process HcsProcess) (hr error) { } func HcsTerminateProcess(ctx gcontext.Context, process HcsProcess) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsTerminateProcess") + ctx, span := oc.StartSpan(ctx, "HcsTerminateProcess") defer span.End() defer func() { if result != "" { @@ -461,7 +462,7 @@ func HcsTerminateProcess(ctx gcontext.Context, process HcsProcess) (result strin } func HcsSignalProcess(ctx gcontext.Context, process HcsProcess, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsSignalProcess") + ctx, span := oc.StartSpan(ctx, "HcsSignalProcess") defer span.End() defer func() { if result != "" { @@ -482,7 +483,7 @@ func HcsSignalProcess(ctx gcontext.Context, process HcsProcess, options string) } func HcsGetProcessInfo(ctx gcontext.Context, process HcsProcess) (processInformation HcsProcessInformation, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsGetProcessInfo") + ctx, span := oc.StartSpan(ctx, "HcsGetProcessInfo") defer span.End() defer func() { if result != "" { @@ -502,7 +503,7 @@ func HcsGetProcessInfo(ctx gcontext.Context, process HcsProcess) (processInforma } func HcsGetProcessProperties(ctx gcontext.Context, process HcsProcess) (processProperties, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsGetProcessProperties") + ctx, span := oc.StartSpan(ctx, "HcsGetProcessProperties") defer span.End() defer func() { if result != "" { @@ -528,7 +529,7 @@ func HcsGetProcessProperties(ctx gcontext.Context, process HcsProcess) (processP } func HcsModifyProcess(ctx gcontext.Context, process HcsProcess, settings string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsModifyProcess") + ctx, span := oc.StartSpan(ctx, "HcsModifyProcess") defer span.End() defer func() { if result != "" { @@ -549,7 +550,7 @@ func HcsModifyProcess(ctx gcontext.Context, process HcsProcess, settings string) } func HcsGetServiceProperties(ctx gcontext.Context, propertyQuery string) (properties, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsGetServiceProperties") + ctx, span := oc.StartSpan(ctx, "HcsGetServiceProperties") defer span.End() defer func() { if result != "" { @@ -576,7 +577,7 @@ func HcsGetServiceProperties(ctx gcontext.Context, propertyQuery string) (proper } func HcsRegisterProcessCallback(ctx gcontext.Context, process HcsProcess, callback uintptr, context uintptr) (callbackHandle HcsCallback, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsRegisterProcessCallback") + ctx, span := oc.StartSpan(ctx, "HcsRegisterProcessCallback") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -586,7 +587,7 @@ func HcsRegisterProcessCallback(ctx gcontext.Context, process HcsProcess, callba } func HcsUnregisterProcessCallback(ctx gcontext.Context, callbackHandle HcsCallback) (hr error) { - ctx, span := trace.StartSpan(ctx, "HcsUnregisterProcessCallback") + ctx, span := oc.StartSpan(ctx, "HcsUnregisterProcessCallback") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -596,7 +597,7 @@ func HcsUnregisterProcessCallback(ctx gcontext.Context, callbackHandle HcsCallba } func HcsSaveComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsSaveComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsSaveComputeSystem") defer span.End() defer func() { if result != "" { diff --git a/internal/wclayer/activatelayer.go b/internal/wclayer/activatelayer.go index 98a79ef4c5..e12253c947 100644 --- a/internal/wclayer/activatelayer.go +++ b/internal/wclayer/activatelayer.go @@ -16,7 +16,7 @@ import ( // An activated layer must later be deactivated via DeactivateLayer. func ActivateLayer(ctx context.Context, path string) (err error) { title := "hcsshim::ActivateLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/internal/wclayer/createlayer.go b/internal/wclayer/createlayer.go index 4e81298514..932475723a 100644 --- a/internal/wclayer/createlayer.go +++ b/internal/wclayer/createlayer.go @@ -14,7 +14,7 @@ import ( // the parent layer provided. func CreateLayer(ctx context.Context, path, parent string) (err error) { title := "hcsshim::CreateLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/internal/wclayer/createscratchlayer.go b/internal/wclayer/createscratchlayer.go index 5750d53e91..5c9d5d2507 100644 --- a/internal/wclayer/createscratchlayer.go +++ b/internal/wclayer/createscratchlayer.go @@ -15,7 +15,7 @@ import ( // This requires the full list of paths to all parent layers up to the base func CreateScratchLayer(ctx context.Context, path string, parentLayerPaths []string) (err error) { title := "hcsshim::CreateScratchLayer" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/internal/wclayer/deactivatelayer.go b/internal/wclayer/deactivatelayer.go index 724af6223d..e3bc77cbc8 100644 --- a/internal/wclayer/deactivatelayer.go +++ b/internal/wclayer/deactivatelayer.go @@ -13,7 +13,7 @@ import ( // DeactivateLayer will dismount a layer that was mounted via ActivateLayer. func DeactivateLayer(ctx context.Context, path string) (err error) { title := "hcsshim::DeactivateLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/internal/wclayer/destroylayer.go b/internal/wclayer/destroylayer.go index 20c5afea7f..d0a59efe12 100644 --- a/internal/wclayer/destroylayer.go +++ b/internal/wclayer/destroylayer.go @@ -14,7 +14,7 @@ import ( // path, including that layer's containing folder, if any. func DestroyLayer(ctx context.Context, path string) (err error) { title := "hcsshim::DestroyLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/internal/wclayer/expandscratchsize.go b/internal/wclayer/expandscratchsize.go index 38071322b7..e2ec27ad08 100644 --- a/internal/wclayer/expandscratchsize.go +++ b/internal/wclayer/expandscratchsize.go @@ -18,7 +18,7 @@ import ( // ExpandScratchSize expands the size of a layer to at least size bytes. func ExpandScratchSize(ctx context.Context, path string, size uint64) (err error) { title := "hcsshim::ExpandScratchSize" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/internal/wclayer/exportlayer.go b/internal/wclayer/exportlayer.go index 3c388ef4bc..62e5d32c06 100644 --- a/internal/wclayer/exportlayer.go +++ b/internal/wclayer/exportlayer.go @@ -21,7 +21,7 @@ import ( // perform the export. func ExportLayer(ctx context.Context, path string, exportFolderPath string, parentLayerPaths []string) (err error) { title := "hcsshim::ExportLayer" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -52,7 +52,7 @@ type LayerReader interface { // The caller must have taken the SeBackupPrivilege privilege // to call this and any methods on the resulting LayerReader. func NewLayerReader(ctx context.Context, path string, parentLayerPaths []string) (_ LayerReader, err error) { - ctx, span := trace.StartSpan(ctx, "hcsshim::NewLayerReader") + ctx, span := oc.StartSpan(ctx, "hcsshim::NewLayerReader") defer func() { if err != nil { oc.SetSpanStatus(span, err) diff --git a/internal/wclayer/getlayermountpath.go b/internal/wclayer/getlayermountpath.go index 761b5bbd1d..715e06e379 100644 --- a/internal/wclayer/getlayermountpath.go +++ b/internal/wclayer/getlayermountpath.go @@ -18,7 +18,7 @@ import ( // folder path at which the layer is stored. func GetLayerMountPath(ctx context.Context, path string) (_ string, err error) { title := "hcsshim::GetLayerMountPath" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/internal/wclayer/getsharedbaseimages.go b/internal/wclayer/getsharedbaseimages.go index 1da329c7a4..5e400fb209 100644 --- a/internal/wclayer/getsharedbaseimages.go +++ b/internal/wclayer/getsharedbaseimages.go @@ -16,7 +16,7 @@ import ( // of registering them with the graphdriver, graph, and tagstore. func GetSharedBaseImages(ctx context.Context) (_ string, err error) { title := "hcsshim::GetSharedBaseImages" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/internal/wclayer/grantvmaccess.go b/internal/wclayer/grantvmaccess.go index b0da3e71df..20217ed81b 100644 --- a/internal/wclayer/grantvmaccess.go +++ b/internal/wclayer/grantvmaccess.go @@ -13,7 +13,7 @@ import ( // GrantVmAccess adds access to a file for a given VM func GrantVmAccess(ctx context.Context, vmid string, filepath string) (err error) { title := "hcsshim::GrantVmAccess" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/internal/wclayer/importlayer.go b/internal/wclayer/importlayer.go index cd4e470837..b9946c5f4a 100644 --- a/internal/wclayer/importlayer.go +++ b/internal/wclayer/importlayer.go @@ -22,7 +22,7 @@ import ( // be present on the system at the paths provided in parentLayerPaths. func ImportLayer(ctx context.Context, path string, importFolderPath string, parentLayerPaths []string) (err error) { title := "hcsshim::ImportLayer" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -126,7 +126,7 @@ func (r *legacyLayerWriterWrapper) Close() (err error) { // The caller must have taken the SeBackupPrivilege and SeRestorePrivilege privileges // to call this and any methods on the resulting LayerWriter. func NewLayerWriter(ctx context.Context, path string, parentLayerPaths []string) (_ LayerWriter, err error) { - ctx, span := trace.StartSpan(ctx, "hcsshim::NewLayerWriter") + ctx, span := oc.StartSpan(ctx, "hcsshim::NewLayerWriter") defer func() { if err != nil { oc.SetSpanStatus(span, err) diff --git a/internal/wclayer/layerexists.go b/internal/wclayer/layerexists.go index 5ee3379cfb..4d82977ea1 100644 --- a/internal/wclayer/layerexists.go +++ b/internal/wclayer/layerexists.go @@ -14,7 +14,7 @@ import ( // to the system. func LayerExists(ctx context.Context, path string) (_ bool, err error) { title := "hcsshim::LayerExists" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/internal/wclayer/layerid.go b/internal/wclayer/layerid.go index ea459d2d42..d4805f1444 100644 --- a/internal/wclayer/layerid.go +++ b/internal/wclayer/layerid.go @@ -14,7 +14,7 @@ import ( // LayerID returns the layer ID of a layer on disk. func LayerID(ctx context.Context, path string) (_ guid.GUID, err error) { title := "hcsshim::LayerID" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/internal/wclayer/nametoguid.go b/internal/wclayer/nametoguid.go index 30938e3d66..c45fa2750c 100644 --- a/internal/wclayer/nametoguid.go +++ b/internal/wclayer/nametoguid.go @@ -16,7 +16,7 @@ import ( // across all clients. func NameToGuid(ctx context.Context, name string) (_ guid.GUID, err error) { title := "hcsshim::NameToGuid" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("objectName", name)) diff --git a/internal/wclayer/preparelayer.go b/internal/wclayer/preparelayer.go index 2f128ab153..b66e071245 100644 --- a/internal/wclayer/preparelayer.go +++ b/internal/wclayer/preparelayer.go @@ -21,7 +21,7 @@ var prepareLayerLock sync.Mutex // Disabling the filter must be done via UnprepareLayer. func PrepareLayer(ctx context.Context, path string, parentLayerPaths []string) (err error) { title := "hcsshim::PrepareLayer" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/internal/wclayer/processimage.go b/internal/wclayer/processimage.go index aaf55d887b..7c49cbda45 100644 --- a/internal/wclayer/processimage.go +++ b/internal/wclayer/processimage.go @@ -14,7 +14,7 @@ import ( // The files should have been extracted to \Files. func ProcessBaseLayer(ctx context.Context, path string) (err error) { title := "hcsshim::ProcessBaseLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) @@ -30,7 +30,7 @@ func ProcessBaseLayer(ctx context.Context, path string) (err error) { // The files should have been extracted to \Files. func ProcessUtilityVMImage(ctx context.Context, path string) (err error) { title := "hcsshim::ProcessUtilityVMImage" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/internal/wclayer/unpreparelayer.go b/internal/wclayer/unpreparelayer.go index c53a06ea2c..fe20702c18 100644 --- a/internal/wclayer/unpreparelayer.go +++ b/internal/wclayer/unpreparelayer.go @@ -14,7 +14,7 @@ import ( // the given id. func UnprepareLayer(ctx context.Context, path string) (err error) { title := "hcsshim::UnprepareLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/pkg/octtrpc/interceptor.go b/pkg/octtrpc/interceptor.go index 4bbf9484c3..a99ee21d5c 100644 --- a/pkg/octtrpc/interceptor.go +++ b/pkg/octtrpc/interceptor.go @@ -5,6 +5,8 @@ import ( "encoding/base64" "strings" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/containerd/ttrpc" "go.opencensus.io/trace" "go.opencensus.io/trace/propagation" @@ -67,7 +69,7 @@ func ClientInterceptor(opts ...Option) ttrpc.UnaryClientInterceptor { opt(&o) } return func(ctx context.Context, req *ttrpc.Request, resp *ttrpc.Response, info *ttrpc.UnaryClientInfo, inv ttrpc.Invoker) (err error) { - ctx, span := trace.StartSpan( + ctx, span := oc.StartSpan( ctx, convertMethodName(info.FullMethod), trace.WithSampler(o.sampler), @@ -105,8 +107,9 @@ func ServerInterceptor(opts ...Option) ttrpc.UnaryServerInterceptor { trace.WithSpanKind(trace.SpanKindServer), trace.WithSampler(o.sampler), ) + ctx = log.U(ctx) } else { - ctx, span = trace.StartSpan( + ctx, span = oc.StartSpan( ctx, name, trace.WithSpanKind(trace.SpanKindServer), diff --git a/test/vendor/github.com/Microsoft/hcsshim/computestorage/attach.go b/test/vendor/github.com/Microsoft/hcsshim/computestorage/attach.go index 05b6ea7bd4..54c4b3bc4a 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/computestorage/attach.go +++ b/test/vendor/github.com/Microsoft/hcsshim/computestorage/attach.go @@ -19,8 +19,8 @@ import ( // // `layerData` is the parent read-only layer data. func AttachLayerStorageFilter(ctx context.Context, layerPath string, layerData LayerData) (err error) { - title := "hcsshim.AttachLayerStorageFilter" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::AttachLayerStorageFilter" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/computestorage/destroy.go b/test/vendor/github.com/Microsoft/hcsshim/computestorage/destroy.go index 8dd942bab9..5058d3b55e 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/computestorage/destroy.go +++ b/test/vendor/github.com/Microsoft/hcsshim/computestorage/destroy.go @@ -14,8 +14,8 @@ import ( // // `layerPath` is a path to a directory containing the layer to export. func DestroyLayer(ctx context.Context, layerPath string) (err error) { - title := "hcsshim.DestroyLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::DestroyLayer" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("layerPath", layerPath)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/computestorage/detach.go b/test/vendor/github.com/Microsoft/hcsshim/computestorage/detach.go index 934ee5b1a6..daf1bfff20 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/computestorage/detach.go +++ b/test/vendor/github.com/Microsoft/hcsshim/computestorage/detach.go @@ -14,8 +14,8 @@ import ( // // `layerPath` is a path to a directory containing the layer to export. func DetachLayerStorageFilter(ctx context.Context, layerPath string) (err error) { - title := "hcsshim.DetachLayerStorageFilter" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::DetachLayerStorageFilter" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("layerPath", layerPath)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/computestorage/export.go b/test/vendor/github.com/Microsoft/hcsshim/computestorage/export.go index cf90d9b6c9..c6370a5c9a 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/computestorage/export.go +++ b/test/vendor/github.com/Microsoft/hcsshim/computestorage/export.go @@ -21,8 +21,8 @@ import ( // // `options` are the export options applied to the exported layer. func ExportLayer(ctx context.Context, layerPath, exportFolderPath string, layerData LayerData, options ExportLayerOptions) (err error) { - title := "hcsshim.ExportLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::ExportLayer" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/computestorage/format.go b/test/vendor/github.com/Microsoft/hcsshim/computestorage/format.go index 05e0729f50..4a5735e989 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/computestorage/format.go +++ b/test/vendor/github.com/Microsoft/hcsshim/computestorage/format.go @@ -11,7 +11,6 @@ import ( "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/osversion" "github.com/pkg/errors" - "go.opencensus.io/trace" "golang.org/x/sys/windows" ) @@ -43,8 +42,8 @@ func openDisk(path string) (windows.Handle, error) { // // If the VHD is not mounted it will be temporarily mounted. func FormatWritableLayerVhd(ctx context.Context, vhdHandle windows.Handle) (err error) { - title := "hcsshim.FormatWritableLayerVhd" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::FormatWritableLayerVhd" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/test/vendor/github.com/Microsoft/hcsshim/computestorage/import.go b/test/vendor/github.com/Microsoft/hcsshim/computestorage/import.go index a40b4037cc..e1c87416a3 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/computestorage/import.go +++ b/test/vendor/github.com/Microsoft/hcsshim/computestorage/import.go @@ -21,8 +21,8 @@ import ( // // `layerData` is the parent layer data. func ImportLayer(ctx context.Context, layerPath, sourceFolderPath string, layerData LayerData) (err error) { - title := "hcsshim.ImportLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::ImportLayer" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/computestorage/initialize.go b/test/vendor/github.com/Microsoft/hcsshim/computestorage/initialize.go index ddd8f318da..d0c6216056 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/computestorage/initialize.go +++ b/test/vendor/github.com/Microsoft/hcsshim/computestorage/initialize.go @@ -18,8 +18,8 @@ import ( // // `layerData` is the parent read-only layer data. func InitializeWritableLayer(ctx context.Context, layerPath string, layerData LayerData) (err error) { - title := "hcsshim.InitializeWritableLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::InitializeWritableLayer" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/computestorage/mount.go b/test/vendor/github.com/Microsoft/hcsshim/computestorage/mount.go index 6e445e766b..4f4d8ebf2f 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/computestorage/mount.go +++ b/test/vendor/github.com/Microsoft/hcsshim/computestorage/mount.go @@ -8,14 +8,13 @@ import ( "github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/oc" "github.com/pkg/errors" - "go.opencensus.io/trace" "golang.org/x/sys/windows" ) // GetLayerVhdMountPath returns the volume path for a virtual disk of a writable container layer. func GetLayerVhdMountPath(ctx context.Context, vhdHandle windows.Handle) (path string, err error) { - title := "hcsshim.GetLayerVhdMountPath" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::GetLayerVhdMountPath" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/test/vendor/github.com/Microsoft/hcsshim/computestorage/setup.go b/test/vendor/github.com/Microsoft/hcsshim/computestorage/setup.go index 4b27b895ad..faec837ca1 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/computestorage/setup.go +++ b/test/vendor/github.com/Microsoft/hcsshim/computestorage/setup.go @@ -23,8 +23,8 @@ import ( // // `options` are the options applied while processing the layer. func SetupBaseOSLayer(ctx context.Context, layerPath string, vhdHandle windows.Handle, options OsLayerOptions) (err error) { - title := "hcsshim.SetupBaseOSLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::SetupBaseOSLayer" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -54,8 +54,8 @@ func SetupBaseOSVolume(ctx context.Context, layerPath, volumePath string, option if osversion.Build() < 19645 { return errors.New("SetupBaseOSVolume is not present on builds older than 19645") } - title := "hcsshim.SetupBaseOSVolume" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + title := "hcsshim::SetupBaseOSVolume" + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/container.go b/test/vendor/github.com/Microsoft/hcsshim/container.go index 640e0b26f4..c8f09f88b9 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/container.go +++ b/test/vendor/github.com/Microsoft/hcsshim/container.go @@ -62,7 +62,7 @@ type container struct { waitCh chan struct{} } -// createComputeSystemAdditionalJSON is read from the environment at initialisation +// createContainerAdditionalJSON is read from the environment at initialization // time. It allows an environment variable to define additional JSON which // is merged in the CreateComputeSystem call to HCS. var createContainerAdditionalJSON []byte diff --git a/test/vendor/github.com/Microsoft/hcsshim/hcn/hcnsupport.go b/test/vendor/github.com/Microsoft/hcsshim/hcn/hcnsupport.go index 00af20be31..8be28c19a0 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/hcn/hcnsupport.go +++ b/test/vendor/github.com/Microsoft/hcsshim/hcn/hcnsupport.go @@ -3,11 +3,13 @@ package hcn import ( - "fmt" + "context" "sync" "github.com/pkg/errors" "github.com/sirupsen/logrus" + + "github.com/Microsoft/hcsshim/internal/log" ) var ( @@ -81,6 +83,7 @@ func GetSupportedFeatures() SupportedFeatures { } func getSupportedFeatures() (SupportedFeatures, error) { + ctx := context.Background() var features SupportedFeatures globals, err := GetGlobals() if err != nil { @@ -114,10 +117,10 @@ func getSupportedFeatures() (SupportedFeatures, error) { features.NetworkACL = isFeatureSupported(globals.Version, NetworkACLPolicyVersion) features.NestedIpSet = isFeatureSupported(globals.Version, NestedIpSetVersion) - logrus.WithFields(logrus.Fields{ - "version": fmt.Sprintf("%+v", globals.Version), - "supportedFeatures": fmt.Sprintf("%+v", features), - }).Info("HCN feature check") + log.G(ctx).WithFields(logrus.Fields{ + "version": log.FormatEnabled(ctx, logrus.DebugLevel, globals.Version), + "supportedFeatures": log.FormatEnabled(ctx, logrus.DebugLevel, features), + }).Debug("HCN feature check") return features, nil } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/cmd.go b/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/cmd.go index 758eb78880..389dfc063b 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/cmd.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/cmd.go @@ -11,12 +11,16 @@ import ( "sync/atomic" "time" - "github.com/Microsoft/hcsshim/internal/cow" - hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" - specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" "golang.org/x/sync/errgroup" "golang.org/x/sys/windows" + + "github.com/Microsoft/hcsshim/internal/cow" + hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/oc" + specs "github.com/opencontainers/runtime-spec/specs-go" ) // CmdProcessRequest stores information on command requests made through this package. @@ -29,6 +33,8 @@ type CmdProcessRequest struct { Stderr string } +// todo (helsaawy): replace use of Cmd.Log and switch to log.WithContext + // Cmd represents a command being prepared or run in a process host. type Cmd struct { // Host is the process host in which to launch the process. @@ -111,7 +117,7 @@ func Command(host cow.ProcessHost, name string, arg ...string) *Cmd { Spec: &specs.Process{ Args: append([]string{name}, arg...), }, - Log: logrus.NewEntry(logrus.StandardLogger()), + Log: log.G(context.Background()), ExitState: &ExitState{}, } if host.OS() == "windows" { @@ -128,12 +134,31 @@ func Command(host cow.ProcessHost, name string, arg ...string) *Cmd { func CommandContext(ctx context.Context, host cow.ProcessHost, name string, arg ...string) *Cmd { cmd := Command(host, name, arg...) cmd.Context = ctx + cmd.Log = log.G(ctx) return cmd } // Start starts a command. The caller must ensure that if Start succeeds, // Wait is eventually called to clean up resources. -func (c *Cmd) Start() error { +func (c *Cmd) Start() (err error) { + pctx := context.Background() + if c.Context != nil { + pctx = c.Context + } + ctx, span := oc.StartSpan(pctx, "cmd::Start") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute("cmd", log.Format(ctx, c.Spec.Args)), + trace.BoolAttribute("isOCI", c.Host.IsOCI()), + trace.StringAttribute("os", c.Host.OS()), + trace.StringAttribute("cwd", c.Spec.Cwd), + trace.StringAttribute("env", log.Format(ctx, c.Spec.Env))) + + if c.Log == nil { + c.Log = log.G(ctx) + } + c.allDoneCh = make(chan struct{}) var x interface{} if !c.Host.IsOCI() { @@ -182,17 +207,15 @@ func (c *Cmd) Start() error { } x = lpp } - if c.Context != nil && c.Context.Err() != nil { - return c.Context.Err() + if err = ctx.Err(); err != nil { + return err } - p, err := c.Host.CreateProcess(context.TODO(), x) + p, err := c.Host.CreateProcess(ctx, x) if err != nil { return err } c.Process = p - if c.Log != nil { - c.Log = c.Log.WithField("pid", p.Pid()) - } + c.Log = c.Log.WithField("pid", p.Pid()) // Start relaying process IO. stdin, stdout, stderr := p.Stdio() @@ -209,7 +232,7 @@ func (c *Cmd) Start() error { c.stdinErr.Store(err) } // Notify the process that there is no more input. - if err := p.CloseStdin(context.TODO()); err != nil && c.Log != nil { + if err := p.CloseStdin(ctx); err != nil && c.Log != nil { c.Log.WithError(err).Warn("failed to close Cmd stdin") } }() @@ -218,7 +241,7 @@ func (c *Cmd) Start() error { if c.Stdout != nil { c.iogrp.Go(func() error { _, err := relayIO(c.Stdout, stdout, c.Log, "stdout") - if err := p.CloseStdout(context.TODO()); err != nil { + if err := p.CloseStdout(ctx); err != nil { c.Log.WithError(err).Warn("failed to close Cmd stdout") } return err @@ -228,7 +251,7 @@ func (c *Cmd) Start() error { if c.Stderr != nil { c.iogrp.Go(func() error { _, err := relayIO(c.Stderr, stderr, c.Log, "stderr") - if err := p.CloseStderr(context.TODO()); err != nil { + if err := p.CloseStderr(ctx); err != nil { c.Log.WithError(err).Warn("failed to close Cmd stderr") } return err @@ -239,20 +262,33 @@ func (c *Cmd) Start() error { go func() { select { case <-c.Context.Done(): - _, _ = c.Process.Kill(context.TODO()) + // Process.Kill (via Process.Signal) will not send an RPC if the + // provided context in is cancelled (bridge.AsyncRPC will end early) + kctx := log.Copy(context.Background(), ctx) + _, _ = c.Process.Kill(kctx) case <-c.allDoneCh: } }() } + return nil } // Wait waits for a command and its IO to complete and closes the underlying // process. It can only be called once. It returns an ExitError if the command // runs and returns a non-zero exit code. -func (c *Cmd) Wait() error { +func (c *Cmd) Wait() (err error) { + pctx := context.Background() + if c.Context != nil { + pctx = c.Context + } + _, span := oc.StartSpan(pctx, "cmd::Wait") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute("cmd", log.Format(pctx, c.Spec.Args))) + waitErr := c.Process.Wait() - if waitErr != nil && c.Log != nil { + if waitErr != nil { c.Log.WithError(waitErr).Warn("process wait failed") } state := &ExitState{} @@ -271,9 +307,7 @@ func (c *Cmd) Wait() error { case <-t.C: // Close the process to cancel any reads to stdout or stderr. c.Process.Close() - if c.Log != nil { - c.Log.Warn("timed out waiting for stdio relay") - } + c.Log.Warn("timed out waiting for stdio relay") } }() } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/diag.go b/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/diag.go index e397bb85ee..7c77e80bf8 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/diag.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/diag.go @@ -7,6 +7,8 @@ import ( "errors" "os/exec" + "github.com/sirupsen/logrus" + "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/uvm" @@ -14,6 +16,9 @@ import ( // ExecInUvm is a helper function used to execute commands specified in `req` inside the given UVM. func ExecInUvm(ctx context.Context, vm *uvm.UtilityVM, req *CmdProcessRequest) (int, error) { + ctx, etr := log.S(ctx, logrus.Fields{logfields.UVMID: vm.ID()}) + etr.Trace("cmd::ExecInUVM") + if len(req.Args) == 0 { return 0, errors.New("missing command") } @@ -41,6 +46,8 @@ func ExecInUvm(ctx context.Context, vm *uvm.UtilityVM, req *CmdProcessRequest) ( // ExecInShimHost is a helper function used to execute commands specified in `req` in the shim's // hosting system. func ExecInShimHost(ctx context.Context, req *CmdProcessRequest) (int, error) { + log.G(ctx).Trace("cmd::ExecInUVM") + if len(req.Args) == 0 { return 0, errors.New("missing command") } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io.go b/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io.go index 75ddd1f355..44a8e82447 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io.go @@ -10,6 +10,9 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" + + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" ) // UpstreamIO is an interface describing the IO to connect to above the shim. @@ -64,19 +67,26 @@ func NewUpstreamIO(ctx context.Context, id, stdout, stderr, stdin string, termin } // relayIO is a glorified io.Copy that also logs when the copy has completed. -func relayIO(w io.Writer, r io.Reader, log *logrus.Entry, name string) (int64, error) { +func relayIO(w io.Writer, r io.Reader, entry *logrus.Entry, name string) (int64, error) { n, err := io.Copy(w, r) - if log != nil { + if entry != nil { + ctx := entry.Context + if ctx == nil { + ctx = context.Background() + } + lvl := logrus.DebugLevel - log = log.WithFields(logrus.Fields{ - "file": name, - "bytes": n, + entry = entry.WithFields(logrus.Fields{ + logfields.File: name, + "bytes": n, + "reader": log.FormatIO(ctx, logrus.ErrorLevel, r), + "writer": log.FormatIO(ctx, logrus.ErrorLevel, w), }) if err != nil { lvl = logrus.ErrorLevel - log = log.WithError(err) + entry = entry.WithError(err) } - log.Log(lvl, "Cmd IO relay complete") + entry.Log(lvl, "Cmd IO relay complete") } return n, err } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io_binary.go b/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io_binary.go index 989a53c93c..2ef08def7d 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io_binary.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io_binary.go @@ -20,6 +20,7 @@ import ( "github.com/sirupsen/logrus" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" ) const ( @@ -169,17 +170,29 @@ type binaryIO struct { // Close named pipes for container stdout and stderr and wait for the binary process to finish. func (b *binaryIO) Close(ctx context.Context) { + ctx, etr := log.S(ctx, logrus.Fields{ //nolint:ineffassign,staticcheck + "binaryCmd": b.cmd.String(), + "binaryProcessID": b.cmd.Process.Pid, + }) + etr.Trace("binaryIO::Close") + b.soutCloser.Do(func() { if b.sout != nil { + etr := etr.WithField(logfields.Pipe, b.stdout) err := b.sout.Close() if err != nil { - log.G(ctx).WithError(err).Errorf("error while closing stdout npipe") + etr.WithError(err).Errorf("error while closing stdout npipe") + } else { + etr.Debug("binaryIO::soutCloser - stdout") } } if b.serr != nil { + etr := etr.WithField(logfields.Pipe, b.stderr) err := b.serr.Close() if err != nil { - log.G(ctx).WithError(err).Errorf("error while closing stderr npipe") + etr.WithError(err).Errorf("error while closing stderr npipe") + } else { + etr.Debug("binaryIO::soutCloser - stderr") } } }) @@ -192,13 +205,14 @@ func (b *binaryIO) Close(ctx context.Context) { select { case err := <-done: if err != nil { - log.G(ctx).WithError(err).Errorf("error while waiting for binary cmd to finish") + etr.WithError(err).Errorf("error while waiting for binary cmd to finish") } case <-time.After(binaryCmdWaitTimeout): - log.G(ctx).Errorf("timeout while waiting for binaryIO process to finish. Killing") + etr := etr.WithField(logfields.Timeout, binaryCmdWaitTimeout.String()) + etr.Errorf("timeout while waiting for binaryIO process to finish. Killing") err := b.cmd.Process.Kill() if err != nil { - log.G(ctx).WithError(err).Errorf("error while killing binaryIO process") + etr.WithError(err).Errorf("error while killing binaryIO process") } } }) @@ -280,7 +294,7 @@ func (p *pipe) Read(b []byte) (int, error) { func (p *pipe) Close() error { if err := p.l.Close(); err != nil { - log.G(context.TODO()).WithError(err).Debug("error closing pipe listener") + log.G(context.Background()).WithError(err).Debug("error closing pipe listener") } p.conWg.Wait() if p.con != nil { diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io_npipe.go b/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io_npipe.go index 614f34ca29..a285e88bae 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io_npipe.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/cmd/io_npipe.go @@ -15,6 +15,7 @@ import ( winio "github.com/Microsoft/go-winio" "github.com/Microsoft/go-winio/pkg/guid" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/cenkalti/backoff/v4" "github.com/sirupsen/logrus" "golang.org/x/sys/windows" @@ -34,7 +35,7 @@ func NewNpipeIO(ctx context.Context, stdin, stdout, stderr string, terminal bool "stdout": stdout, "stderr": stderr, "terminal": terminal, - }).Debug("NewNpipeIO") + }).Trace("NewNpipeIO") nio := &npipeio{ stdin: stdin, @@ -123,7 +124,7 @@ func (nprw *nPipeRetryWriter) Write(p []byte) (n int, err error) { nprw.Conn.Close() newConn, retryErr := nprw.retryDialPipe() if retryErr == nil { - log.G(nprw.ctx).WithField("address", nprw.pipePath).Info("Succeeded in reconnecting to named pipe") + log.G(nprw.ctx).WithField("address", nprw.pipePath).Debug("Succeeded in reconnecting to named pipe") nprw.Conn = newConn continue @@ -198,28 +199,31 @@ type npipeio struct { } func (nio *npipeio) Close(ctx context.Context) { + log.G(ctx).Trace("npipeio::Close") + // winio.win32Pipe.Close currently doesn't return any errors nio.sinCloser.Do(func() { if nio.sin != nil { - log.G(ctx).Debug("npipeio::sinCloser") + log.G(ctx).WithField(logfields.Pipe, nio.stdin).Debug("npipeio::sinCloser") nio.sin.Close() } }) nio.outErrCloser.Do(func() { if nio.sout != nil { - log.G(ctx).Debug("npipeio::outErrCloser - stdout") + log.G(ctx).WithField(logfields.Pipe, nio.stdout).Debug("npipeio::outErrCloser - stdout") nio.sout.Close() } if nio.serr != nil { - log.G(ctx).Debug("npipeio::outErrCloser - stderr") + log.G(ctx).WithField(logfields.Pipe, nio.stderr).Debug("npipeio::outErrCloser - stderr") nio.serr.Close() } }) } func (nio *npipeio) CloseStdin(ctx context.Context) { + log.G(ctx).Trace("npipeio::CloseStdin") nio.sinCloser.Do(func() { if nio.sin != nil { - log.G(ctx).Debug("npipeio::sinCloser") + log.G(ctx).WithField(logfields.Pipe, nio.stdin).Debug("npipeio::sinCloser") nio.sin.Close() } }) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/copyfile/copyfile.go b/test/vendor/github.com/Microsoft/hcsshim/internal/copyfile/copyfile.go index 61aa2dc405..ea3e65b543 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/copyfile/copyfile.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/copyfile/copyfile.go @@ -20,7 +20,7 @@ var ( // CopyFile is a utility for copying a file using CopyFileW win32 API for // performance. func CopyFile(ctx context.Context, srcFile, destFile string, overwrite bool) (err error) { - ctx, span := trace.StartSpan(ctx, "copyfile::CopyFile") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "copyfile::CopyFile") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/devices/assigned_devices.go b/test/vendor/github.com/Microsoft/hcsshim/internal/devices/assigned_devices.go index 4750776403..a1ae4e0f73 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/devices/assigned_devices.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/devices/assigned_devices.go @@ -44,7 +44,7 @@ func AddDevice(ctx context.Context, vm *uvm.UtilityVM, idType, deviceID string, return vpci, nil, errors.Wrapf(err, "failed to assign device %s of type %s to pod %s", deviceID, idType, vm.ID()) } vmBusInstanceID := vm.GetAssignedDeviceVMBUSInstanceID(vpci.VMBusGUID) - log.G(ctx).WithField("vmbus id", vmBusInstanceID).Info("vmbus instance ID") + log.G(ctx).WithField("vmbus id", vmBusInstanceID).Debug("vmbus instance ID") locationPaths, err = getChildrenDeviceLocationPaths(ctx, vm, vmBusInstanceID, deviceUtilPath) return vpci, locationPaths, err diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/bridge.go b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/bridge.go index 1e3e7c201d..f81cdb44cf 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/bridge.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/bridge.go @@ -53,6 +53,9 @@ type rpc struct { ch chan struct{} } +// todo(helsaawy): remove bridge.log entry and log based on per-request context, not +// the context that started the bridge + // bridge represents a communcations bridge with the guest. It handles the // transport layer but (mostly) does not parse or construct the message payload. type bridge struct { @@ -311,7 +314,7 @@ func (brdg *bridge) recvLoop() error { } brdg.log.WithFields(logrus.Fields{ "payload": string(b), - "type": typ, + "type": typ.String(), "message-id": id}).Debug("bridge receive") switch typ & msgTypeMask { case msgTypeResponse: @@ -412,11 +415,10 @@ func (brdg *bridge) writeMessage(buf *bytes.Buffer, enc *json.Encoder, typ msgTy } brdg.log.WithFields(logrus.Fields{ "payload": string(b), - "type": typ, + "type": typ.String(), "message-id": id}).Debug("bridge send") } - // Write the message. _, err = buf.WriteTo(brdg.conn) if err != nil { return fmt.Errorf("bridge write: %s", err) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/container.go b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/container.go index bf704fb548..69204a6d84 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/container.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/container.go @@ -12,6 +12,7 @@ import ( "github.com/Microsoft/hcsshim/internal/hcs/schema1" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" "go.opencensus.io/trace" ) @@ -33,7 +34,7 @@ var _ cow.Container = &Container{} // CreateContainer creates a container using ID `cid` and `cfg`. The request // will likely not be cancellable even if `ctx` becomes done. func (gc *GuestConnection) CreateContainer(ctx context.Context, cid string, config interface{}) (_ *Container, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnection::CreateContainer") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::CreateContainer", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", cid)) @@ -91,17 +92,17 @@ func (c *Container) IsOCI() bool { // Close releases associated with the container. func (c *Container) Close() error { - c.closeOnce.Do(func() { - _, span := trace.StartSpan(context.Background(), "gcs::Container::Close") - defer span.End() - span.AddAttributes(trace.StringAttribute("cid", c.id)) - }) + _, span := oc.StartSpan(context.Background(), "gcs::Container::Close") + defer span.End() + span.AddAttributes(trace.StringAttribute("cid", c.id)) + + c.closeOnce.Do(func() {}) return nil } // CreateProcess creates a process in the container. func (c *Container) CreateProcess(ctx context.Context, config interface{}) (_ cow.Process, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::CreateProcess") + ctx, span := oc.StartSpan(ctx, "gcs::Container::CreateProcess", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -116,7 +117,7 @@ func (c *Container) ID() string { // Modify sends a modify request to the container. func (c *Container) Modify(ctx context.Context, config interface{}) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::Modify") + ctx, span := oc.StartSpan(ctx, "gcs::Container::Modify", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -131,7 +132,7 @@ func (c *Container) Modify(ctx context.Context, config interface{}) (err error) // Properties returns the requested container properties targeting a V1 schema container. func (c *Container) Properties(ctx context.Context, types ...schema1.PropertyType) (_ *schema1.ContainerProperties, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::Properties") + ctx, span := oc.StartSpan(ctx, "gcs::Container::Properties", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -150,7 +151,7 @@ func (c *Container) Properties(ctx context.Context, types ...schema1.PropertyTyp // PropertiesV2 returns the requested container properties targeting a V2 schema container. func (c *Container) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (_ *hcsschema.Properties, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::PropertiesV2") + ctx, span := oc.StartSpan(ctx, "gcs::Container::PropertiesV2", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -169,7 +170,7 @@ func (c *Container) PropertiesV2(ctx context.Context, types ...hcsschema.Propert // Start starts the container. func (c *Container) Start(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::Start") + ctx, span := oc.StartSpan(ctx, "gcs::Container::Start", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -200,7 +201,7 @@ func (c *Container) shutdown(ctx context.Context, proc rpcProc) error { // might not be terminated by the time the request completes (and might never // terminate). func (c *Container) Shutdown(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::Shutdown") + ctx, span := oc.StartSpan(ctx, "gcs::Container::Shutdown", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -214,7 +215,7 @@ func (c *Container) Shutdown(ctx context.Context) (err error) { // might not be terminated by the time the request completes (and might never // terminate). func (c *Container) Terminate(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Container::Terminate") + ctx, span := oc.StartSpan(ctx, "gcs::Container::Terminate", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) @@ -236,11 +237,11 @@ func (c *Container) Wait() error { } func (c *Container) waitBackground() { - ctx, span := trace.StartSpan(context.Background(), "gcs::Container::waitBackground") + ctx, span := oc.StartSpan(context.Background(), "gcs::Container::waitBackground") defer span.End() span.AddAttributes(trace.StringAttribute("cid", c.id)) err := c.Wait() - log.G(ctx).Debug("container exited") + log.G(ctx).WithField(logfields.ContainerID, c.id).Debug("container exited") oc.SetSpanStatus(span, err) } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/guestconnection.go b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/guestconnection.go index bb28d890ff..689c30b3cf 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/guestconnection.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/guestconnection.go @@ -68,7 +68,7 @@ type GuestConnectionConfig struct { // Connect establishes a GCS connection. `gcc.Conn` will be closed by this function. func (gcc *GuestConnectionConfig) Connect(ctx context.Context, isColdStart bool) (_ *GuestConnection, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnectionConfig::Connect") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnectionConfig::Connect", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -167,7 +167,7 @@ func (gc *GuestConnection) connect(ctx context.Context, isColdStart bool, initGu // Modify sends a modify settings request to the null container. This is // generally used to prepare virtual hardware that has been added to the guest. func (gc *GuestConnection) Modify(ctx context.Context, settings interface{}) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnection::Modify") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::Modify", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -180,7 +180,7 @@ func (gc *GuestConnection) Modify(ctx context.Context, settings interface{}) (er } func (gc *GuestConnection) DumpStacks(ctx context.Context) (response string, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnection::DumpStacks") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::DumpStacks", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -193,7 +193,7 @@ func (gc *GuestConnection) DumpStacks(ctx context.Context) (response string, err } func (gc *GuestConnection) DeleteContainerState(ctx context.Context, cid string) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnection::DeleteContainerState") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::DeleteContainerState", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", cid)) @@ -216,7 +216,7 @@ func (gc *GuestConnection) Close() error { // CreateProcess creates a process in the container host. func (gc *GuestConnection) CreateProcess(ctx context.Context, settings interface{}) (_ cow.Process, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::GuestConnection::CreateProcess") + ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::CreateProcess", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -268,7 +268,7 @@ func (gc *GuestConnection) notify(ntf *containerNotification) error { if ch == nil { return fmt.Errorf("container %s not found", cid) } - logrus.WithField(logfields.ContainerID, cid).Info("container terminated in guest") + logrus.WithField(logfields.ContainerID, cid).Debug("container terminated in guest") close(ch) return nil } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/iochannel.go b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/iochannel.go index 5af6b81aaf..a2a032a12d 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/iochannel.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/iochannel.go @@ -65,3 +65,7 @@ func (c *ioChannel) Write(b []byte) (int, error) { } return c.c.Write(b) } + +func (c *ioChannel) Addr() net.Addr { + return c.l.Addr() +} diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/process.go b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/process.go index 60141e9f70..fab6af75c7 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/process.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/process.go @@ -124,7 +124,7 @@ func (gc *GuestConnection) exec(ctx context.Context, cid string, params interfac // Close releases resources associated with the process and closes the // associated standard IO streams. func (p *Process) Close() error { - ctx, span := trace.StartSpan(context.Background(), "gcs::Process::Close") + ctx, span := oc.StartSpan(context.Background(), "gcs::Process::Close") defer span.End() span.AddAttributes( trace.StringAttribute("cid", p.cid), @@ -144,7 +144,7 @@ func (p *Process) Close() error { // CloseStdin causes the process to read EOF on its stdin stream. func (p *Process) CloseStdin(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::CloseStdin") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "gcs::Process::CloseStdin") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -158,7 +158,7 @@ func (p *Process) CloseStdin(ctx context.Context) (err error) { } func (p *Process) CloseStdout(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::CloseStdout") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "gcs::Process::CloseStdout") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -169,7 +169,7 @@ func (p *Process) CloseStdout(ctx context.Context) (err error) { } func (p *Process) CloseStderr(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::CloseStderr") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "gcs::Process::CloseStderr") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -195,7 +195,7 @@ func (p *Process) ExitCode() (_ int, err error) { // signal was delivered. The process might not be terminated by the time this // returns. func (p *Process) Kill(ctx context.Context) (_ bool, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::Kill") + ctx, span := oc.StartSpan(ctx, "gcs::Process::Kill") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -213,7 +213,7 @@ func (p *Process) Pid() int { // ResizeConsole requests that the pty associated with the process resize its // window. func (p *Process) ResizeConsole(ctx context.Context, width, height uint16) (err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::ResizeConsole") + ctx, span := oc.StartSpan(ctx, "gcs::Process::ResizeConsole", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -232,7 +232,7 @@ func (p *Process) ResizeConsole(ctx context.Context, width, height uint16) (err // Signal sends a signal to the process, returning whether it was delivered. func (p *Process) Signal(ctx context.Context, options interface{}) (_ bool, err error) { - ctx, span := trace.StartSpan(ctx, "gcs::Process::Signal") + ctx, span := oc.StartSpan(ctx, "gcs::Process::Signal", oc.WithClientSpanKind) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -277,7 +277,7 @@ func (p *Process) Wait() error { } func (p *Process) waitBackground() { - ctx, span := trace.StartSpan(context.Background(), "gcs::Process::waitBackground") + ctx, span := oc.StartSpan(context.Background(), "gcs::Process::waitBackground") defer span.End() span.AddAttributes( trace.StringAttribute("cid", p.cid), diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/protocol.go b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/protocol.go index 8450222a1a..94e55e4c1e 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/protocol.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/gcs/protocol.go @@ -5,6 +5,7 @@ package gcs import ( "encoding/json" "fmt" + "strconv" "github.com/Microsoft/go-winio/pkg/guid" "github.com/Microsoft/hcsshim/internal/hcs/schema1" @@ -64,6 +65,43 @@ const ( rpcLifecycleNotification ) +func (rpc rpcProc) String() string { + switch rpc { + case rpcCreate: + return "Create" + case rpcStart: + return "Start" + case rpcShutdownGraceful: + return "ShutdownGraceful" + case rpcShutdownForced: + return "ShutdownForced" + case rpcExecuteProcess: + return "ExecuteProcess" + case rpcWaitForProcess: + return "WaitForProcess" + case rpcSignalProcess: + return "SignalProcess" + case rpcResizeConsole: + return "ResizeConsole" + case rpcGetProperties: + return "GetProperties" + case rpcModifySettings: + return "ModifySettings" + case rpcNegotiateProtocol: + return "NegotiateProtocol" + case rpcDumpStacks: + return "DumpStacks" + case rpcDeleteContainerState: + return "DeleteContainerState" + case rpcUpdateContainer: + return "UpdateContainer" + case rpcLifecycleNotification: + return "LifecycleNotification" + default: + return "0x" + strconv.FormatUint(uint64(rpc), 16) + } +} + type msgType uint32 const ( @@ -94,40 +132,7 @@ func (typ msgType) String() string { default: return fmt.Sprintf("%#x", uint32(typ)) } - switch rpcProc(typ &^ msgTypeMask) { - case rpcCreate: - s += "Create" - case rpcStart: - s += "Start" - case rpcShutdownGraceful: - s += "ShutdownGraceful" - case rpcShutdownForced: - s += "ShutdownForced" - case rpcExecuteProcess: - s += "ExecuteProcess" - case rpcWaitForProcess: - s += "WaitForProcess" - case rpcSignalProcess: - s += "SignalProcess" - case rpcResizeConsole: - s += "ResizeConsole" - case rpcGetProperties: - s += "GetProperties" - case rpcModifySettings: - s += "ModifySettings" - case rpcNegotiateProtocol: - s += "NegotiateProtocol" - case rpcDumpStacks: - s += "DumpStacks" - case rpcDeleteContainerState: - s += "DeleteContainerState" - case rpcUpdateContainer: - s += "UpdateContainer" - case rpcLifecycleNotification: - s += "LifecycleNotification" - default: - s += fmt.Sprintf("%#x", uint32(typ)) - } + s += rpcProc(typ &^ msgTypeMask).String() return s + ")" } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go index 226dad2fbc..7a387b399f 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go @@ -13,6 +13,8 @@ import ( "github.com/Microsoft/hcsshim/internal/log" ) +// todo (helsaawy): annotate errors with grpc status code + var ( // ErrComputeSystemDoesNotExist is an error encountered when the container being operated on no longer exists ErrComputeSystemDoesNotExist = syscall.Errno(0xc037010e) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go index 4bf3a167a5..a1065ceb5a 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go @@ -13,8 +13,10 @@ import ( "time" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/vmcompute" + "github.com/sirupsen/logrus" "go.opencensus.io/trace" ) @@ -120,11 +122,15 @@ func (process *Process) processSignalResult(ctx context.Context, err error) (boo // // For WCOW `guestresource.SignalProcessOptionsWCOW`. func (process *Process) Signal(ctx context.Context, options interface{}) (bool, error) { + operation := "hcs::Process::Signal" + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.ProcessID: process.processID, + logfields.ContainerID: process.SystemID()}) + etr.Trace(operation) + process.handleLock.RLock() defer process.handleLock.RUnlock() - operation := "hcs::Process::Signal" - if process.handle == 0 { return false, makeProcessError(process, operation, ErrAlreadyClosed, nil) } @@ -145,11 +151,15 @@ func (process *Process) Signal(ctx context.Context, options interface{}) (bool, // Kill signals the process to terminate but does not wait for it to finish terminating. func (process *Process) Kill(ctx context.Context) (bool, error) { + operation := "hcs::Process::Kill" + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.ProcessID: process.processID, + logfields.ContainerID: process.SystemID()}) + etr.Trace(operation) + process.handleLock.RLock() defer process.handleLock.RUnlock() - operation := "hcs::Process::Kill" - if process.handle == 0 { return false, makeProcessError(process, operation, ErrAlreadyClosed, nil) } @@ -203,7 +213,7 @@ func (process *Process) Kill(ctx context.Context) (bool, error) { // call multiple times. func (process *Process) waitBackground() { operation := "hcs::Process::waitBackground" - ctx, span := trace.StartSpan(context.Background(), operation) + ctx, span := oc.StartSpan(context.Background(), operation) defer span.End() span.AddAttributes( trace.StringAttribute("cid", process.SystemID()), @@ -245,7 +255,7 @@ func (process *Process) waitBackground() { } } } - log.G(ctx).WithField("exitCode", exitCode).Debug("process exited") + log.G(ctx).WithField("exitCode", exitCode).Debug("hcs::Process process exited") process.closedWaitOnce.Do(func() { process.exitCode = exitCode @@ -264,11 +274,15 @@ func (process *Process) Wait() error { // ResizeConsole resizes the console of the process. func (process *Process) ResizeConsole(ctx context.Context, width, height uint16) error { + operation := "hcs::Process::ResizeConsole" + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.ProcessID: process.processID, + logfields.ContainerID: process.SystemID()}) + etr.Trace(operation) + process.handleLock.RLock() defer process.handleLock.RUnlock() - operation := "hcs::Process::ResizeConsole" - if process.handle == 0 { return makeProcessError(process, operation, ErrAlreadyClosed, nil) } @@ -314,7 +328,7 @@ func (process *Process) ExitCode() (int, error) { // are the responsibility of the caller to close. func (process *Process) StdioLegacy() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) { operation := "hcs::Process::StdioLegacy" - ctx, span := trace.StartSpan(context.Background(), operation) + ctx, span := oc.StartSpan(context.Background(), operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -361,12 +375,18 @@ func (process *Process) Stdio() (stdin io.Writer, stdout, stderr io.Reader) { // CloseStdin closes the write side of the stdin pipe so that the process is // notified on the read side that there is no more data in stdin. -func (process *Process) CloseStdin(ctx context.Context) error { +func (process *Process) CloseStdin(ctx context.Context) (err error) { + operation := "hcs::Process::CloseStdin" + ctx, span := oc.StartSpan(ctx, operation) //nolint:ineffassign,staticcheck + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute("cid", process.SystemID()), + trace.Int64Attribute("pid", int64(process.processID))) + process.handleLock.RLock() defer process.handleLock.RUnlock() - operation := "hcs::Process::CloseStdin" - if process.handle == 0 { return makeProcessError(process, operation, ErrAlreadyClosed, nil) } @@ -400,7 +420,7 @@ func (process *Process) CloseStdin(ctx context.Context) error { } func (process *Process) CloseStdout(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "hcs::Process::CloseStdout") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "hcs::Process::CloseStdout") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -424,7 +444,7 @@ func (process *Process) CloseStdout(ctx context.Context) (err error) { } func (process *Process) CloseStderr(ctx context.Context) (err error) { - ctx, span := trace.StartSpan(ctx, "hcs::Process::CloseStderr") //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, "hcs::Process::CloseStderr") //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -451,7 +471,7 @@ func (process *Process) CloseStderr(ctx context.Context) (err error) { // or wait on it. func (process *Process) Close() (err error) { operation := "hcs::Process::Close" - ctx, span := trace.StartSpan(context.Background(), operation) + ctx, span := oc.StartSpan(context.Background(), operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go index 052d08ccc3..4e8bfb2a2e 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go @@ -14,9 +14,11 @@ import ( "github.com/Microsoft/hcsshim/internal/hcs/schema1" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/timeout" "github.com/Microsoft/hcsshim/internal/vmcompute" + "github.com/sirupsen/logrus" "go.opencensus.io/trace" ) @@ -46,7 +48,7 @@ func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface in // hcsCreateComputeSystemContext is an async operation. Start the outer span // here to measure the full create time. - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := oc.StartSpan(ctx, operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", id)) @@ -99,6 +101,7 @@ func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface in // OpenComputeSystem opens an existing compute system by ID. func OpenComputeSystem(ctx context.Context, id string) (*System, error) { operation := "hcs::OpenComputeSystem" + log.G(ctx).WithField(logfields.ContainerID, id).Trace(operation) computeSystem := newSystem(id) handle, resultJSON, err := vmcompute.HcsOpenComputeSystem(ctx, id) @@ -151,6 +154,7 @@ func (computeSystem *System) IsOCI() bool { // GetComputeSystems gets a list of the compute systems on the system that match the query func GetComputeSystems(ctx context.Context, q schema1.ComputeSystemQuery) ([]schema1.ContainerProperties, error) { operation := "hcs::GetComputeSystems" + log.G(ctx).WithField("query", log.FormatEnabled(ctx, logrus.TraceLevel, q)).Trace(operation) queryb, err := json.Marshal(q) if err != nil { @@ -180,7 +184,7 @@ func (computeSystem *System) Start(ctx context.Context) (err error) { // hcsStartComputeSystemContext is an async operation. Start the outer span // here to measure the full start time. - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := oc.StartSpan(ctx, operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -208,11 +212,12 @@ func (computeSystem *System) ID() string { // Shutdown requests a compute system shutdown. func (computeSystem *System) Shutdown(ctx context.Context) error { + operation := "hcs::System::Shutdown" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::Shutdown" - if computeSystem.handle == 0 { return nil } @@ -229,11 +234,12 @@ func (computeSystem *System) Shutdown(ctx context.Context) error { // Terminate requests a compute system terminate. func (computeSystem *System) Terminate(ctx context.Context) error { + operation := "hcs::System::Terminate" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::Terminate" - if computeSystem.handle == 0 { return nil } @@ -255,7 +261,7 @@ func (computeSystem *System) Terminate(ctx context.Context) error { // safe to call multiple times. func (computeSystem *System) waitBackground() { operation := "hcs::System::waitBackground" - ctx, span := trace.StartSpan(context.Background(), operation) + ctx, span := oc.StartSpan(context.Background(), operation) defer span.End() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -299,11 +305,12 @@ func (computeSystem *System) ExitError() error { // Properties returns the requested container properties targeting a V1 schema container. func (computeSystem *System) Properties(ctx context.Context, types ...schema1.PropertyType) (*schema1.ContainerProperties, error) { + operation := "hcs::System::Properties" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::Properties" - queryBytes, err := json.Marshal(schema1.PropertyQuery{PropertyTypes: types}) if err != nil { return nil, makeSystemError(computeSystem, operation, err, nil) @@ -328,11 +335,12 @@ func (computeSystem *System) Properties(ctx context.Context, types ...schema1.Pr // PropertiesV2 returns the requested container properties targeting a V2 schema container. func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (*hcsschema.Properties, error) { + operation := "hcs::System::PropertiesV2" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::PropertiesV2" - queryBytes, err := json.Marshal(hcsschema.PropertyQuery{PropertyTypes: types}) if err != nil { return nil, makeSystemError(computeSystem, operation, err, nil) @@ -361,7 +369,7 @@ func (computeSystem *System) Pause(ctx context.Context) (err error) { // hcsPauseComputeSystemContext is an async peration. Start the outer span // here to measure the full pause time. - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := oc.StartSpan(ctx, operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -388,7 +396,7 @@ func (computeSystem *System) Resume(ctx context.Context) (err error) { // hcsResumeComputeSystemContext is an async operation. Start the outer span // here to measure the full restore time. - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := oc.StartSpan(ctx, operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -413,9 +421,9 @@ func (computeSystem *System) Resume(ctx context.Context) (err error) { func (computeSystem *System) Save(ctx context.Context, options interface{}) (err error) { operation := "hcs::System::Save" - // hcsSaveComputeSystemContext is an async peration. Start the outer span + // hcsSaveComputeSystemContext is an async operation. Start the outer span // here to measure the full save time. - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := oc.StartSpan(ctx, operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -468,6 +476,9 @@ func (computeSystem *System) createProcess(ctx context.Context, operation string // CreateProcess launches a new process within the computeSystem. func (computeSystem *System) CreateProcess(ctx context.Context, c interface{}) (cow.Process, error) { operation := "hcs::System::CreateProcess" + ctx, etr := log.S(ctx, logrus.Fields{logfields.ContainerID: computeSystem.id}) + etr.Trace(operation) + process, processInfo, err := computeSystem.createProcess(ctx, operation, c) if err != nil { return nil, err @@ -497,11 +508,12 @@ func (computeSystem *System) CreateProcess(ctx context.Context, c interface{}) ( // OpenProcess gets an interface to an existing process within the computeSystem. func (computeSystem *System) OpenProcess(ctx context.Context, pid int) (*Process, error) { + operation := "hcs::System::OpenProcess" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::OpenProcess" - if computeSystem.handle == 0 { return nil, makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) } @@ -524,7 +536,7 @@ func (computeSystem *System) OpenProcess(ctx context.Context, pid int) (*Process // Close cleans up any state associated with the compute system but does not terminate or wait for it. func (computeSystem *System) Close() (err error) { operation := "hcs::System::Close" - ctx, span := trace.StartSpan(context.Background(), operation) + ctx, span := oc.StartSpan(context.Background(), operation) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) @@ -614,11 +626,12 @@ func (computeSystem *System) unregisterCallback(ctx context.Context) error { // Modify the System by sending a request to HCS func (computeSystem *System) Modify(ctx context.Context, config interface{}) error { + operation := "hcs::System::Modify" + log.G(ctx).WithField(logfields.ContainerID, computeSystem.id).Trace(operation) + computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() - operation := "hcs::System::Modify" - if computeSystem.handle == 0 { return makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/create.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/create.go index 6df67ee876..978ca9b297 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/create.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/create.go @@ -18,6 +18,8 @@ import ( "github.com/Microsoft/hcsshim/internal/hcs" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/oci" "github.com/Microsoft/hcsshim/internal/resources" "github.com/Microsoft/hcsshim/internal/schemaversion" @@ -25,6 +27,7 @@ import ( "github.com/Microsoft/hcsshim/pkg/annotations" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" ) var ( @@ -216,9 +219,9 @@ func initializeCreateOptions(ctx context.Context, createOptions *CreateOptions) coi.templateID = oci.ParseAnnotationsTemplateID(ctx, createOptions.Spec) log.G(ctx).WithFields(logrus.Fields{ - "options": fmt.Sprintf("%+v", createOptions), - "schema": coi.actualSchemaVersion, - }).Debug("hcsshim::initializeCreateOptions") + "options": log.FormatEnabled(ctx, logrus.DebugLevel, createOptions), + "schema": log.FormatEnabled(ctx, logrus.DebugLevel, coi.actualSchemaVersion), + }).Debug("hcsshim::initializeCreateOptions options") return coi, nil } @@ -269,6 +272,11 @@ func configureSandboxNetwork(ctx context.Context, coi *createOptionsInternal, r // release the resources on failure, so that the client can make the necessary // call to release resources that have been allocated as part of calling this function. func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.Container, _ *resources.Resources, err error) { + ctx, span := oc.StartSpan(ctx, "hcsoci::CreateContainer") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.ID, createOptions.ID)) + coi, err := initializeCreateOptions(ctx, createOptions) if err != nil { return nil, nil, err @@ -321,12 +329,13 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C } var hcsDocument, gcsDocument interface{} - log.G(ctx).Debug("hcsshim::CreateContainer allocating resources") + etr := log.G(ctx) + etr.Debug("hcsshim::CreateContainer allocating resources") if coi.Spec.Linux != nil { if schemaversion.IsV10(coi.actualSchemaVersion) { return nil, r, errors.New("LCOW v1 not supported") } - log.G(ctx).Debug("hcsshim::CreateContainer allocateLinuxResources") + etr.Debug("hcsshim::CreateContainer allocateLinuxResources") err = allocateLinuxResources(ctx, coi, r, isSandbox) if err != nil { log.G(ctx).WithError(err).Debug("failed to allocateLinuxResources") @@ -334,19 +343,19 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C } gcsDocument, err = createLinuxContainerDocument(ctx, coi, r.ContainerRootInUVM()) if err != nil { - log.G(ctx).WithError(err).Debug("failed createHCSContainerDocument") + log.G(ctx).WithError(err).Error("failed createHCSContainerDocument") return nil, r, err } } else { err = allocateWindowsResources(ctx, coi, r, isSandbox) if err != nil { - log.G(ctx).WithError(err).Debug("failed to allocateWindowsResources") + etr.WithError(err).Error("failed to allocateWindowsResources") return nil, r, err } - log.G(ctx).Debug("hcsshim::CreateContainer creating container document") + etr.Debug("hcsshim::CreateContainer creating container document") v1, v2, err := createWindowsContainerDocument(ctx, coi) if err != nil { - log.G(ctx).WithError(err).Debug("failed createHCSContainerDocument") + etr.WithError(err).Error("failed createHCSContainerDocument") return nil, r, err } @@ -370,7 +379,7 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C } } - log.G(ctx).Debug("hcsshim::CreateContainer creating compute system") + etr.Debug("hcsshim::CreateContainer creating compute system") if gcsDocument != nil { c, err := coi.HostingSystem.CreateContainer(ctx, coi.actualID, gcsDocument) if err != nil { @@ -390,6 +399,11 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C // CreateContainer does. Also, instead of sending create container request it sends a modify // request to an existing container. CloneContainer only works for WCOW. func CloneContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.Container, _ *resources.Resources, err error) { + ctx, span := oc.StartSpan(ctx, "hcsoci::CloneContainer") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.ID, createOptions.ID)) + coi, err := initializeCreateOptions(ctx, createOptions) if err != nil { return nil, nil, err diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/devices.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/devices.go index ccc19d4af8..8964224259 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/devices.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/devices.go @@ -13,6 +13,7 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/Microsoft/hcsshim/internal/devices" "github.com/Microsoft/hcsshim/internal/guestpath" @@ -158,7 +159,7 @@ func handleAssignedDevicesWindows( ID: value, IDType: uvm.VPCILocationPathIDType, } - log.G(ctx).WithField("parsed devices", specDev).Info("added windows device to spec") + log.G(ctx).WithField("parsed devices", log.FormatEnabled(ctx, logrus.DebugLevel, specDev)).Debug("added windows device to spec") resultDevs = append(resultDevs, specDev) } } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/hcsdoc_lcow.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/hcsdoc_lcow.go index 5612cd18f0..26308a7a47 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/hcsdoc_lcow.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/hcsdoc_lcow.go @@ -78,12 +78,13 @@ type linuxHostedSystem struct { } func createLinuxContainerDocument(ctx context.Context, coi *createOptionsInternal, guestRoot string) (*linuxHostedSystem, error) { + log.G(ctx).WithField("guestRoot", guestRoot).Trace("hcsshim::createLinuxContainerDoc") + spec, err := createLCOWSpec(coi) if err != nil { return nil, err } - log.G(ctx).WithField("guestRoot", guestRoot).Debug("hcsshim::createLinuxContainerDoc") return &linuxHostedSystem{ SchemaVersion: schemaversion.SchemaV21(), OciBundlePath: guestRoot, diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/hcsdoc_wcow.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/hcsdoc_wcow.go index 1d25b44438..3cc0eba7e1 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/hcsdoc_wcow.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/hcsdoc_wcow.go @@ -19,6 +19,7 @@ import ( hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/layers" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oci" "github.com/Microsoft/hcsshim/internal/processorinfo" "github.com/Microsoft/hcsshim/internal/uvm" @@ -143,7 +144,12 @@ func ConvertCPULimits(ctx context.Context, cid string, spec *specs.Spec, maxCPUC // a container, both hosted and process isolated. It creates both v1 and v2 // container objects, WCOW only. The containers storage should have been mounted already. func createWindowsContainerDocument(ctx context.Context, coi *createOptionsInternal) (*schema1.ContainerConfig, *hcsschema.Container, error) { - log.G(ctx).Debug("hcsshim: CreateHCSContainerDocument") + ctx, etr := log.S(ctx, logrus.Fields{ + logfields.Name: coi.actualID, + "owner": coi.actualOwner, + }) + etr.Trace("hcsshim: CreateHCSContainerDocument") + // TODO: Make this safe if exported so no null pointer dereferences. if coi.Spec == nil { @@ -227,12 +233,12 @@ func createWindowsContainerDocument(ctx context.Context, coi *createOptionsInter } else if newCPULimit > 10000 { newCPULimit = 10000 } - log.G(ctx).WithFields(logrus.Fields{ + etr.WithFields(logrus.Fields{ "hostCPUCount": hostCPUCount, "uvmCPUCount": uvmCPUCount, "oldCPULimit": cpuLimit, "newCPULimit": newCPULimit, - }).Info("rescaling CPU limit for UVM sandbox") + }).Debug("rescaling CPU limit for UVM sandbox") cpuLimit = newCPULimit } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/network.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/network.go index 27bf2669d2..c6e0ed01b7 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/network.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/network.go @@ -8,18 +8,18 @@ import ( "github.com/Microsoft/hcsshim/hcn" "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/resources" "github.com/Microsoft/hcsshim/internal/uvm" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" ) -func createNetworkNamespace(ctx context.Context, coi *createOptionsInternal, r *resources.Resources) error { - op := "hcsoci::createNetworkNamespace" - l := log.G(ctx).WithField(logfields.ContainerID, coi.ID) - l.Debug(op + " - Begin") - defer func() { - l.Debug(op + " - End") - }() +func createNetworkNamespace(ctx context.Context, coi *createOptionsInternal, r *resources.Resources) (err error) { + ctx, span := oc.StartSpan(ctx, "hcsoci::createNetworkNamespace") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.ContainerID, coi.ID)) ns, err := hcn.NewNamespace("").Create() if err != nil { @@ -29,7 +29,7 @@ func createNetworkNamespace(ctx context.Context, coi *createOptionsInternal, r * log.G(ctx).WithFields(logrus.Fields{ "netID": ns.Id, logfields.ContainerID: coi.ID, - }).Info("created network namespace for container") + }).Debug("created network namespace for container") r.SetNetNS(ns.Id) r.SetCreatedNetNS(true) @@ -43,7 +43,7 @@ func createNetworkNamespace(ctx context.Context, coi *createOptionsInternal, r * log.G(ctx).WithFields(logrus.Fields{ "netID": ns.Id, "endpointID": endpointID, - }).Info("added network endpoint to namespace") + }).Debug("added network endpoint to namespace") endpoints = append(endpoints, endpointID) } r.Add(&uvm.NetworkEndpoints{EndpointIDs: endpoints, Namespace: ns.Id}) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources.go index 46ad55660f..d42fe79f0f 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources.go @@ -14,7 +14,7 @@ func NormalizeProcessorCount(ctx context.Context, cid string, requestedCount, ho "id": cid, "requested count": requestedCount, "assigned count": hostCount, - }).Warn("Changing user requested cpu count to current number of processors on the host") + }).Warn("Changing user requested cpu count to current number of processors on the host") return hostCount } else { return requestedCount diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources_lcow.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources_lcow.go index d438738c28..a3e24e4c4b 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources_lcow.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources_lcow.go @@ -15,6 +15,7 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/Microsoft/hcsshim/internal/guestpath" "github.com/Microsoft/hcsshim/internal/layers" @@ -78,9 +79,9 @@ func allocateLinuxResources(ctx context.Context, coi *createOptionsInternal, r * } } - l := log.G(ctx).WithField("mount", fmt.Sprintf("%+v", mount)) + entry := log.G(ctx).WithField("mount", log.FormatEnabled(ctx, logrus.DebugLevel, mount)) if mount.Type == "physical-disk" { - l.Debug("hcsshim::allocateLinuxResources Hot-adding SCSI physical disk for OCI mount") + entry.Debug("hcsshim::allocateLinuxResources Hot-adding SCSI physical disk for OCI mount") uvmPathForShare = fmt.Sprintf(guestpath.LCOWGlobalMountPrefixFmt, coi.HostingSystem.UVMMountCounter()) scsiMount, err := coi.HostingSystem.AddSCSIPhysicalDisk(ctx, hostPath, uvmPathForShare, readOnly, mount.Options) if err != nil { @@ -91,7 +92,7 @@ func allocateLinuxResources(ctx context.Context, coi *createOptionsInternal, r * r.Add(scsiMount) coi.Spec.Mounts[i].Type = "none" } else if mount.Type == "virtual-disk" { - l.Debug("hcsshim::allocateLinuxResources Hot-adding SCSI virtual disk for OCI mount") + entry.Debug("hcsshim::allocateLinuxResources Hot-adding SCSI virtual disk for OCI mount") uvmPathForShare = fmt.Sprintf(guestpath.LCOWGlobalMountPrefixFmt, coi.HostingSystem.UVMMountCounter()) // if the scsi device is already attached then we take the uvm path that the function below returns @@ -149,7 +150,7 @@ func allocateLinuxResources(ctx context.Context, coi *createOptionsInternal, r * restrictAccess = true uvmPathForFile = path.Join(uvmPathForShare, fileName) } - l.Debug("hcsshim::allocateLinuxResources Hot-adding Plan9 for OCI mount") + entry.Debug("hcsshim::allocateLinuxResources Hot-adding Plan9 for OCI mount") share, err := coi.HostingSystem.AddPlan9(ctx, hostPath, uvmPathForShare, readOnly, restrictAccess, allowedNames) if err != nil { diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources_wcow.go b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources_wcow.go index fa22c8047e..92c6d06c08 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources_wcow.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/hcsoci/resources_wcow.go @@ -15,6 +15,7 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/Microsoft/hcsshim/internal/cmd" "github.com/Microsoft/hcsshim/internal/credentials" @@ -150,16 +151,17 @@ func setupMounts(ctx context.Context, coi *createOptionsInternal, r *resources.R break } } - l := log.G(ctx).WithField("mount", fmt.Sprintf("%+v", mount)) + + entry := log.G(ctx).WithField("mount", log.FormatEnabled(ctx, logrus.DebugLevel, mount)) if mount.Type == "physical-disk" { - l.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI physical disk for OCI mount") + entry.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI physical disk for OCI mount") scsiMount, err := coi.HostingSystem.AddSCSIPhysicalDisk(ctx, mount.Source, uvmPath, readOnly, mount.Options) if err != nil { return errors.Wrapf(err, "adding SCSI physical disk mount %+v", mount) } r.Add(scsiMount) } else if mount.Type == "virtual-disk" { - l.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI virtual disk for OCI mount") + entry.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI virtual disk for OCI mount") scsiMount, err := coi.HostingSystem.AddSCSI( ctx, mount.Source, @@ -174,7 +176,7 @@ func setupMounts(ctx context.Context, coi *createOptionsInternal, r *resources.R } r.Add(scsiMount) } else if mount.Type == "extensible-virtual-disk" { - l.Debug("hcsshim::allocateWindowsResource Hot-adding ExtensibleVirtualDisk") + entry.Debug("hcsshim::allocateWindowsResource Hot-adding ExtensibleVirtualDisk") scsiMount, err := coi.HostingSystem.AddSCSIExtensibleVirtualDisk(ctx, mount.Source, uvmPath, readOnly) if err != nil { return errors.Wrapf(err, "adding SCSI EVD mount failed %+v", mount) @@ -214,7 +216,7 @@ func setupMounts(ctx context.Context, coi *createOptionsInternal, r *resources.R } r.Add(pipe) } else { - l.Debug("hcsshim::allocateWindowsResources Hot-adding VSMB share for OCI mount") + entry.Debug("hcsshim::allocateWindowsResources Hot-adding VSMB share for OCI mount") options := coi.HostingSystem.DefaultVSMBOptions(readOnly) share, err := coi.HostingSystem.AddVSMB(ctx, mount.Source, options) if err != nil { diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/layers/layers.go b/test/vendor/github.com/Microsoft/hcsshim/internal/layers/layers.go index e0fa566b63..fb2682caaa 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/layers/layers.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/layers/layers.go @@ -12,12 +12,15 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" "golang.org/x/sys/windows" "github.com/Microsoft/hcsshim/internal/guestpath" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/hcserror" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/ospath" "github.com/Microsoft/hcsshim/internal/uvm" "github.com/Microsoft/hcsshim/internal/wclayer" @@ -46,7 +49,12 @@ func NewImageLayers(vm *uvm.UtilityVM, containerRootInUVM string, layers []strin } // Release unmounts all of the layers located in the layers array. -func (layers *ImageLayers) Release(ctx context.Context, all bool) error { +func (layers *ImageLayers) Release(ctx context.Context, all bool) (err error) { + ctx, span := oc.StartSpan(ctx, "layers::Release") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute("ImageLayers", log.Format(ctx, layers))) + if layers.skipCleanup && layers.vm != nil { return nil } @@ -58,7 +66,7 @@ func (layers *ImageLayers) Release(ctx context.Context, all bool) error { if layers.vm != nil { crp = containerRootfsPath(layers.vm, layers.containerRootInUVM) } - err := UnmountContainerLayers(ctx, layers.layers, crp, layers.volumeMountPath, layers.vm, op) + err = UnmountContainerLayers(ctx, layers.layers, crp, layers.volumeMountPath, layers.vm, op) if err != nil { return err } @@ -79,7 +87,13 @@ func (layers *ImageLayers) Release(ctx context.Context, all bool) error { // // TODO dcantah: Keep better track of the layers that are added, don't simply discard the SCSI, VSMB, etc. resource types gotten inside. func MountContainerLayers(ctx context.Context, containerID string, layerFolders []string, guestRoot string, volumeMountPath string, vm *uvm.UtilityVM) (_ string, err error) { - log.G(ctx).WithField("layerFolders", layerFolders).Debug("hcsshim::mountContainerLayers") + ctx, span := oc.StartSpan(ctx, "layers::MountContainerLayers") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute("layerFolders", log.Format(ctx, layerFolders)), + trace.StringAttribute("guestRoot", guestRoot), + trace.StringAttribute("volumeMountPath", volumeMountPath)) if vm == nil { if len(layerFolders) < 2 { @@ -161,7 +175,7 @@ func MountContainerLayers(ctx context.Context, containerID string, layerFolders } // V2 UVM - log.G(ctx).WithField("os", vm.OS()).Debug("hcsshim::mountContainerLayers V2 UVM") + log.G(ctx).WithField("os", vm.OS()).Debug("layers::MountContainerLayers V2 UVM") var ( layersAdded []string @@ -268,7 +282,6 @@ func MountContainerLayers(ctx context.Context, containerID string, layerFolders if err != nil { return "", err } - log.G(ctx).Debug("hcsshim::mountContainerLayers Succeeded") return rootfs, nil } @@ -341,8 +354,12 @@ const ( ) // UnmountContainerLayers is a helper for clients to hide all the complexity of layer unmounting -func UnmountContainerLayers(ctx context.Context, layerFolders []string, containerRootPath, volumeMountPath string, vm *uvm.UtilityVM, op UnmountOperation) error { - log.G(ctx).WithField("layerFolders", layerFolders).Debug("hcsshim::unmountContainerLayers") +func UnmountContainerLayers(ctx context.Context, layerFolders []string, containerRootPath, volumeMountPath string, vm *uvm.UtilityVM, op UnmountOperation) (err error) { + ctx, span := oc.StartSpan(ctx, "layers::UnmountContainerLayers") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute("layerFolders", fmt.Sprint(layerFolders))) + if vm == nil { // Must be an argon - folders are mounted on the host if op != UnmountOperationAll { @@ -443,6 +460,12 @@ func UnmountContainerLayers(ctx context.Context, layerFolders []string, containe // GetHCSLayers converts host paths corresponding to container layers into HCS schema V2 layers func GetHCSLayers(ctx context.Context, vm *uvm.UtilityVM, paths []string) (layers []hcsschema.Layer, err error) { + ctx, span := oc.StartSpan(ctx, "layers::GetHCSLayers") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute(logfields.UVMID, vm.ID()), + trace.StringAttribute("paths", fmt.Sprint(paths))) + for _, path := range paths { uvmPath, err := vm.GetVSMBUvmPath(ctx, path, true) if err != nil { @@ -484,7 +507,7 @@ func mountSandboxVolume(ctx context.Context, hostPath, volumeName string) (err e log.G(ctx).WithFields(logrus.Fields{ "hostpath": hostPath, "volumeName": volumeName, - }).Debug("mounting volume for container") + }).Trace("layers::mountSandboxVolume") if _, err := os.Stat(hostPath); os.IsNotExist(err) { if err := os.MkdirAll(hostPath, 0777); err != nil { @@ -510,10 +533,10 @@ func mountSandboxVolume(ctx context.Context, hostPath, volumeName string) (err e } // Remove volume mount point. And remove folder afterwards. -func removeSandboxMountPoint(ctx context.Context, hostPath string) error { +func removeSandboxMountPoint(ctx context.Context, hostPath string) (err error) { log.G(ctx).WithFields(logrus.Fields{ "hostpath": hostPath, - }).Debug("removing volume mount point for container") + }).Trace("layers::removeSandboxMountPoint") if err := windows.DeleteVolumeMountPoint(windows.StringToUTF16Ptr(hostPath)); err != nil { return errors.Wrap(err, "failed to delete sandbox volume mount point") diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/log/context.go b/test/vendor/github.com/Microsoft/hcsshim/internal/log/context.go new file mode 100644 index 0000000000..8c9a741bb3 --- /dev/null +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/log/context.go @@ -0,0 +1,139 @@ +package log + +import ( + "context" + + "github.com/sirupsen/logrus" + "go.opencensus.io/trace" + + "github.com/Microsoft/hcsshim/internal/logfields" +) + +type entryContextKeyType int + +const _entryContextKey entryContextKeyType = iota + +var ( + // L is the default, blank logging entry. WithField and co. all return a copy + // of the original entry, so this will not leak fields between calls. + // + // Do NOT modify fields directly, as that will corrupt state for all users and + // is not thread safe. + L = logrus.NewEntry(logrus.StandardLogger()) + + // G is an alias for GetEntry + G = GetEntry + + // S is an alias for SetEntry + S = SetEntry + + // U is an alias for UpdateContext + U = UpdateContext +) + +// GetContext returns a `logrus.Entry` stored in context (if any), appended with +// the `TraceID, SpanID` from `ctx` if `ctx` contains an OpenCensus `trace.Span`. +// +// Unlike FromContext, this will overwrite any tracing information already +// present in the entry. +func GetEntry(ctx context.Context) *logrus.Entry { + entry := FromContext(ctx) + + //TODO: remove this and modify the etw hooks to extract span info via `trace.FromContext(entry.Context)` + if span := trace.FromContext(ctx); span != nil { + sctx := span.SpanContext() + entry = logrus.WithFields(logrus.Fields{ + logfields.TraceID: sctx.TraceID.String(), + logfields.SpanID: sctx.SpanID.String(), + }) + } + + return entry +} + +// SetEntry updates the log entry in the context with the provided fields, and +// returns both. It is equivlent to: +// entry := G(ctx).WithFields(fields) +// ctx = WithContext(ctx, entry) +func SetEntry(ctx context.Context, fields logrus.Fields) (context.Context, *logrus.Entry) { + e := G(ctx) + if len(fields) > 0 { + e = e.WithFields(fields) + } + ctx = WithContext(ctx, e) + + return ctx, e +} + +// UpdateContext extracts the log entry from the context, and, if the entry's +// context points to a parent's of the current context, ands the entry +// to the most recent context. +// +// This allows the entry to reference the most recent context and any new +// values (such as span contexts) added to it. +func UpdateContext(ctx context.Context) context.Context { + e := FromContext(ctx) + if e.Context != ctx { + ctx = WithContext(ctx, e) + } + + return ctx +} + +// WithContext returns a context that contains the provided log entry. +// The entry can be extracted with `G` (preferred) or `FromContext`. +// +// The entry in the context is a copy of `entry` (generated by `entry.WithContext`) +func WithContext(ctx context.Context, entry *logrus.Entry) context.Context { + entry = entry.WithContext(ctx) + + return context.WithValue(ctx, _entryContextKey, entry) +} + +// FromContext returns the log entry stored in the context, if one exits, or +// the default logging entry otherwise. +func FromContext(ctx context.Context) *logrus.Entry { + entry := fromContext(ctx) + + if entry == nil { + return L.WithContext(ctx) + } + + return entry +} + +// Copy extracts the tracing Span and logging entry from the src Context, if they +// exist, and adds them to the dst Context. +// +// This is useful to share tracing and logging between contexts, but not the +// cancellation. For example, if the src Context has been cancelled but cleanup +// operations triggered by the cancellation require a non-cancelled context to +// execute +func Copy(dst context.Context, src context.Context) context.Context { + if s := trace.FromContext(src); s != nil { + dst = trace.NewContext(dst, s) + } + + if e := fromContext(src); e != nil { + dst = WithContext(dst, e) + } + + return dst +} + +func fromContext(ctx context.Context) *logrus.Entry { + e, _ := ctx.Value(_entryContextKey).(*logrus.Entry) + + return e +} + +// IsLevelEnabled checks if the level of the logger stored in the context +// (or the default logger) is greather than the specified logging level. +func IsLevelEnabled(ctx context.Context, level logrus.Level) bool { + l := L.Logger + if e := fromContext(ctx); e != nil { + l = e.Logger + } + + return l.IsLevelEnabled(level) +} diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/log/format.go b/test/vendor/github.com/Microsoft/hcsshim/internal/log/format.go new file mode 100644 index 0000000000..1c67e7193b --- /dev/null +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/log/format.go @@ -0,0 +1,89 @@ +package log + +import ( + "bytes" + "context" + "encoding/json" + "net" + "reflect" + "strings" + "time" + + "github.com/sirupsen/logrus" +) + +const TimeFormat = time.RFC3339Nano + +func FormatTime(t time.Time) string { + return t.Format(TimeFormat) +} + +// FormatIO formats net.Conn and other types that have an `Addr()` or `Name()`. +// +// See FormatEnabled for more information. +func FormatIO(ctx context.Context, l logrus.Level, v interface{}) string { + if !IsLevelEnabled(ctx, l) { + return "" + } + + m := make(map[string]string) + m["type"] = reflect.TypeOf(v).String() + + switch t := v.(type) { + case net.Conn: + m["local_address"] = formatAddr(t.LocalAddr()) + m["remote_address"] = formatAddr(t.RemoteAddr()) + case interface{ Addr() net.Addr }: + m["address"] = formatAddr(t.Addr()) + default: + return Format(ctx, t) + } + + return Format(ctx, m) +} + +func formatAddr(a net.Addr) string { + return a.Network() + "://" + a.String() +} + +// FormatAny formats an object into a JSON string, but only if the logger is +// enabled for the level specified. This avoids evaluating an expensive JSON +// conversion unnecessarily. +// +// See Format() for more details. +func FormatEnabled(ctx context.Context, l logrus.Level, v interface{}) string { + if !IsLevelEnabled(ctx, l) { + return "" + } + + return Format(ctx, v) +} + +// Format formats an object into a JSON string, without any indendtation or +// HTML escapes. +// +// Use the FormatEnabled to check before conversion that the logging level is enabled +func Format(ctx context.Context, v interface{}) string { + buff := &bytes.Buffer{} + + if err := encode(buff, v); err != nil { + G(ctx).WithError(err).Warning("could not JSON encode %T for logging", v) + + return "" + } + + return strings.TrimSpace(buff.String()) +} + +// used by scrubber +func encode(buf *bytes.Buffer, v interface{}) error { + enc := json.NewEncoder(buf) + enc.SetEscapeHTML(false) + enc.SetIndent("", "") + + if err := enc.Encode(v); err != nil { + return err + } + + return nil +} diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/log/g.go b/test/vendor/github.com/Microsoft/hcsshim/internal/log/g.go deleted file mode 100644 index ba6b1a4a53..0000000000 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/log/g.go +++ /dev/null @@ -1,23 +0,0 @@ -package log - -import ( - "context" - - "github.com/sirupsen/logrus" - "go.opencensus.io/trace" -) - -// G returns a `logrus.Entry` with the `TraceID, SpanID` from `ctx` if `ctx` -// contains an OpenCensus `trace.Span`. -func G(ctx context.Context) *logrus.Entry { - span := trace.FromContext(ctx) - if span != nil { - sctx := span.SpanContext() - return logrus.WithFields(logrus.Fields{ - "traceID": sctx.TraceID.String(), - "spanID": sctx.SpanID.String(), - // "parentSpanID": TODO: JTERRY75 - Try to convince OC to export this? - }) - } - return logrus.NewEntry(logrus.StandardLogger()) -} diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go b/test/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go index d51e0fd89f..0ff5e44506 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go @@ -158,14 +158,6 @@ func scrubBytes(b []byte, scrub scrubberFunc) ([]byte, error) { return bytes.TrimSpace(buf.Bytes()), nil } -func encode(buf *bytes.Buffer, v interface{}) error { - enc := json.NewEncoder(buf) - enc.SetEscapeHTML(false) - if err := enc.Encode(v); err != nil { - return err - } - return nil -} func isRequestBase(m genMap) bool { // neither of these are (currently) `omitempty` diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/logfields/fields.go b/test/vendor/github.com/Microsoft/hcsshim/internal/logfields/fields.go index cf2c166d9b..7f2dfe2626 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/logfields/fields.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/logfields/fields.go @@ -3,21 +3,42 @@ package logfields const ( // Identifiers + Name = "name" + Operation = "operation" + + ID = "id" ContainerID = "cid" - UVMID = "uvm-id" + ExecID = "eid" ProcessID = "pid" + TaskID = "tid" + UVMID = "uvm-id" + + // networking and IO + + File = "file" + Path = "path" + Bytes = "bytes" + Pipe = "pipe" // Common Misc - // Timeout represents an operation timeout. - Timeout = "timeout" + Attempt = "attemptNo" JSON = "json" + // Time + + StartTime = "startTime" + EndTime = "endTime" + Duration = "duration" + Timeout = "timeout" + // Keys/values Field = "field" + Key = "key" OCIAnnotation = "oci-annotation" Value = "value" + Options = "options" // Golang type's @@ -29,4 +50,10 @@ const ( // runhcs VMShimOperation = "vmshim-op" + + // logging and tracing + + TraceID = "traceID" + SpanID = "spanID" + ParentSpanID = "parentSpanID" ) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/oc/errors.go b/test/vendor/github.com/Microsoft/hcsshim/internal/oc/errors.go new file mode 100644 index 0000000000..38adbf52cf --- /dev/null +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/oc/errors.go @@ -0,0 +1,58 @@ +package oc + +import ( + "context" + "errors" + + "go.opencensus.io/trace" + // "github.com/Microsoft/hcsshim/internal/hcs" +) + +// todo: break import cycle with "internal/hcs" + +func toStatusCode(err error) uint32 { + switch { + case checkErrors(err, context.Canceled): + return trace.StatusCodeCancelled + // case checkErrors(err, hcs.ErrVmcomputeInvalidJSON): + // return trace.StatusCodeInvalidArgument + case checkErrors(err, context.DeadlineExceeded): + return trace.StatusCodeDeadlineExceeded + // case checkErrors(err): + // return trace.StatusCodeNotFound + // case checkErrors(err): + // return trace.StatusCodeAlreadyExists + // case checkErrors(err): + // return trace.StatusCodePermissionDenied + // case checkErrors(err): + // return trace.StatusCodeResourceExhausted + // case checkErrors(err): + // return trace.StatusCodeFailedPrecondition + // case checkErrors(err): + // return trace.StatusCodeAborted + // case checkErrors(err): + // return trace.StatusCodeOutOfRange + // case checkErrors(err): + // return trace.StatusCodeUnimplemented + // case checkErrors(err): + // return trace.StatusCodeInternal + // case checkErrors(err): + // return trace.StatusCodeUnavailable + // case checkErrors(err): + // return trace.StatusCodeDataLoss + // case checkErrors(err): + // return trace.StatusCodeUnauthenticated + default: + return trace.StatusCodeUnknown + } +} + +func checkErrors(err error, errs ...error) bool { + for _, e := range errs { + if errors.Is(err, e) { + return true + } + } + + return false +} diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/oc/exporter.go b/test/vendor/github.com/Microsoft/hcsshim/internal/oc/exporter.go index f428bdaf72..62f6fc1c75 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/oc/exporter.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/oc/exporter.go @@ -3,19 +3,21 @@ package oc import ( "github.com/sirupsen/logrus" "go.opencensus.io/trace" -) -var _ = (trace.Exporter)(&LogrusExporter{}) + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" +) // LogrusExporter is an OpenCensus `trace.Exporter` that exports // `trace.SpanData` to logrus output. -type LogrusExporter struct { -} +type LogrusExporter struct{} + +var _ trace.Exporter = &LogrusExporter{} // ExportSpan exports `s` based on the the following rules: // -// 1. All output will contain `s.Attributes`, `s.TraceID`, `s.SpanID`, -// `s.ParentSpanID` for correlation +// 1. All output will contain `s.Attributes`, `s.SpanKind`, `s.TraceID`, +// `s.SpanID`, and `s.ParentSpanID` for correlation // // 2. Any calls to .Annotate will not be supported. // @@ -23,21 +25,44 @@ type LogrusExporter struct { // `s.Status.Code != 0` in which case it will be written at `logrus.ErrorLevel` // providing `s.Status.Message` as the error value. func (le *LogrusExporter) ExportSpan(s *trace.SpanData) { - // Combine all span annotations with traceID, spanID, parentSpanID - baseEntry := logrus.WithFields(logrus.Fields(s.Attributes)) - baseEntry.Data["traceID"] = s.TraceID.String() - baseEntry.Data["spanID"] = s.SpanID.String() - baseEntry.Data["parentSpanID"] = s.ParentSpanID.String() - baseEntry.Data["startTime"] = s.StartTime - baseEntry.Data["endTime"] = s.EndTime - baseEntry.Data["duration"] = s.EndTime.Sub(s.StartTime).String() - baseEntry.Data["name"] = s.Name - baseEntry.Time = s.StartTime + if s.DroppedAnnotationCount > 0 { + logrus.WithFields(logrus.Fields{ + "name": s.Name, + logfields.TraceID: s.TraceID.String(), + logfields.SpanID: s.SpanID.String(), + "dropped": s.DroppedAttributeCount, + "maxAttributes": len(s.Attributes), + }).Warning("span had dropped attributes") + } + + // Combine all span annotations with traceID, spanID, parentSpanID, and error + entry := logrus.WithFields(logrus.Fields(s.Attributes)) + // All span fields are string, so we can safely skip overhead in entry.WithFields + // and add them directly to entry.Data. + // Avoid growing the entry.Data map and reallocating buckets by creating new + // `logrus.Fields` and copying data over. + data := make(logrus.Fields, len(entry.Data)+9) // should only add 9 new entries + for k, v := range entry.Data { //copy old data + data[k] = v + } + data[logfields.Name] = s.Name + data[logfields.TraceID] = s.TraceID.String() + data[logfields.SpanID] = s.SpanID.String() + data[logfields.ParentSpanID] = s.ParentSpanID.String() + data[logfields.StartTime] = log.FormatTime(s.StartTime) + data[logfields.EndTime] = log.FormatTime(s.EndTime) + data[logfields.Duration] = s.EndTime.Sub(s.StartTime).String() + if sk := spanKindToString(s.SpanKind); sk != "" { + data["spanKind"] = sk + } level := logrus.InfoLevel if s.Status.Code != 0 { level = logrus.ErrorLevel - baseEntry.Data[logrus.ErrorKey] = s.Status.Message + data[logrus.ErrorKey] = s.Status.Message } - baseEntry.Log(level, "Span") + + entry.Data = data + entry.Time = s.StartTime + entry.Log(level, "Span") } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/oc/span.go b/test/vendor/github.com/Microsoft/hcsshim/internal/oc/span.go index fee4765cbc..1dd8c1b942 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/oc/span.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/oc/span.go @@ -1,17 +1,48 @@ package oc import ( + "context" + + "github.com/Microsoft/hcsshim/internal/log" "go.opencensus.io/trace" ) +var DefaultSampler = trace.AlwaysSample() + // SetSpanStatus sets `span.SetStatus` to the proper status depending on `err`. If // `err` is `nil` assumes `trace.StatusCodeOk`. func SetSpanStatus(span *trace.Span, err error) { status := trace.Status{} if err != nil { - // TODO: JTERRY75 - Handle errors in a non-generic way - status.Code = trace.StatusCodeUnknown + status.Code = int32(toStatusCode(err)) status.Message = err.Error() } span.SetStatus(status) } + +// StartSpan wraps go.opencensus.io/oc.StartSpan, but, if the span is sampling, +// updates the context of the log entry in the context to the newly created value. +func StartSpan(ctx context.Context, name string, o ...trace.StartOption) (context.Context, *trace.Span) { + ctx, s := trace.StartSpan(ctx, name, o...) + if s.IsRecordingEvents() { + ctx = log.UpdateContext(ctx) + } + + return ctx, s +} + +var WithServerSpanKind = trace.WithSpanKind(trace.SpanKindServer) +var WithClientSpanKind = trace.WithSpanKind(trace.SpanKindServer) + +func spanKindToString(sk int) string { + switch sk { + case trace.SpanKindUnspecified: + return "unknown" + case trace.SpanKindClient: + return "client" + case trace.SpanKindServer: + return "server" + default: + return "" + } +} diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/resources/resources.go b/test/vendor/github.com/Microsoft/hcsshim/internal/resources/resources.go index 90fe116ae5..234fa70500 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/resources/resources.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/resources/resources.go @@ -9,7 +9,10 @@ import ( "github.com/Microsoft/hcsshim/internal/credentials" "github.com/Microsoft/hcsshim/internal/layers" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/uvm" + "go.opencensus.io/trace" ) // NetNS returns the network namespace for the container @@ -95,8 +98,15 @@ func NewContainerResources(id string) *Resources { // ReleaseResources releases/frees all of the resources associated with a container. This includes // Plan9 shares, vsmb mounts, pipe mounts, network endpoints, scsi mounts, vpci devices and layers. // TODO: make method on Resources struct. -func ReleaseResources(ctx context.Context, r *Resources, vm *uvm.UtilityVM, all bool) error { +// TODO: group together all the different errors into one +func ReleaseResources(ctx context.Context, r *Resources, vm *uvm.UtilityVM, all bool) (err error) { + ctx, span := oc.StartSpan(ctx, "resources::ReleaseResources") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + if vm != nil { + span.AddAttributes(trace.StringAttribute(logfields.ID, vm.ID())) + if r.addedNetNSToVM { if err := vm.TearDownNetworking(ctx, r.netNS); err != nil { log.G(ctx).Warn(err) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/computeagent.go b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/computeagent.go index 44b328ad37..05bc6f9bb1 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/computeagent.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/computeagent.go @@ -65,7 +65,7 @@ func (ca *computeAgent) AssignPCI(ctx context.Context, req *computeagent.AssignP "containerID": req.ContainerID, "deviceID": req.DeviceID, "virtualFunctionIndex": req.VirtualFunctionIndex, - }).Info("AssignPCI request") + }).Trace("computeAgent::AssignPCI") if req.DeviceID == "" { return nil, status.Error(codes.InvalidArgument, "received empty field in request") @@ -82,7 +82,7 @@ func (ca *computeAgent) RemovePCI(ctx context.Context, req *computeagent.RemoveP log.G(ctx).WithFields(logrus.Fields{ "containerID": req.ContainerID, "deviceID": req.DeviceID, - }).Info("RemovePCI request") + }).Trace("computeAgent::RemovePCI") if req.DeviceID == "" { return nil, status.Error(codes.InvalidArgument, "received empty field in request") @@ -97,9 +97,9 @@ func (ca *computeAgent) RemovePCI(ctx context.Context, req *computeagent.RemoveP func (ca *computeAgent) AddNIC(ctx context.Context, req *computeagent.AddNICInternalRequest) (*computeagent.AddNICInternalResponse, error) { log.G(ctx).WithFields(logrus.Fields{ "containerID": req.ContainerID, - "endpoint": req.Endpoint, + "endpoint": req.Endpoint.String(), "nicID": req.NicID, - }).Info("AddNIC request") + }).Trace("computeAgent::AddNIC") if req.NicID == "" || req.Endpoint == nil { return nil, status.Error(codes.InvalidArgument, "received empty field in request") @@ -141,9 +141,9 @@ func (ca *computeAgent) AddNIC(ctx context.Context, req *computeagent.AddNICInte // ModifyNIC will modify a NIC from the computeagent services hosting UVM. func (ca *computeAgent) ModifyNIC(ctx context.Context, req *computeagent.ModifyNICInternalRequest) (*computeagent.ModifyNICInternalResponse, error) { log.G(ctx).WithFields(logrus.Fields{ + "endpoint": req.Endpoint.String(), "nicID": req.NicID, - "endpoint": req.Endpoint, - }).Info("ModifyNIC request") + }).Trace("computeAgent::ModifyNIC") if req.NicID == "" || req.Endpoint == nil || req.IovPolicySettings == nil { return nil, status.Error(codes.InvalidArgument, "received empty field in request") @@ -191,10 +191,9 @@ func (ca *computeAgent) ModifyNIC(ctx context.Context, req *computeagent.ModifyN // DeleteNIC will delete a NIC from the computeagent services hosting UVM. func (ca *computeAgent) DeleteNIC(ctx context.Context, req *computeagent.DeleteNICInternalRequest) (*computeagent.DeleteNICInternalResponse, error) { log.G(ctx).WithFields(logrus.Fields{ - "containerID": req.ContainerID, - "nicID": req.NicID, - "endpoint": req.Endpoint, - }).Info("DeleteNIC request") + "endpoint": req.Endpoint.String(), + "nicID": req.NicID, + }).Trace("computeAgent::DeleteNIC") if req.NicID == "" || req.Endpoint == nil { return nil, status.Error(codes.InvalidArgument, "received empty field in request") @@ -240,7 +239,7 @@ func setupAndServe(ctx context.Context, caAddr string, vm *UtilityVM) error { } computeagent.RegisterComputeAgentService(s, &computeAgent{vm}) - log.G(ctx).WithField("address", l.Addr().String()).Info("serving compute agent") + log.G(ctx).WithField("address", log.FormatIO(ctx, logrus.DebugLevel, l)).Debug("serving compute agent") go func() { defer l.Close() if err := trapClosedConnErr(s.Serve(ctx, l)); err != nil { diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create.go b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create.go index b07a78bdd3..9b36372ef0 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create.go @@ -243,7 +243,7 @@ func (uvm *UtilityVM) create(ctx context.Context, doc interface{}) error { // Close terminates and releases resources associated with the utility VM. func (uvm *UtilityVM) Close() (err error) { - ctx, span := trace.StartSpan(context.Background(), "uvm::Close") + ctx, span := oc.StartSpan(context.Background(), "uvm::Close") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute(logfields.UVMID, uvm.id)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create_lcow.go b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create_lcow.go index 79a065454e..5e52c8baf9 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create_lcow.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create_lcow.go @@ -707,7 +707,7 @@ func makeLCOWDoc(ctx context.Context, opts *OptionsLCOW, uvm *UtilityVM) (_ *hcs // consumes a set of options derived from various defaults and options // expressed as annotations. func CreateLCOW(ctx context.Context, opts *OptionsLCOW) (_ *UtilityVM, err error) { - ctx, span := trace.StartSpan(ctx, "uvm::CreateLCOW") + ctx, span := oc.StartSpan(ctx, "uvm::CreateLCOW") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -720,7 +720,10 @@ func CreateLCOW(ctx context.Context, opts *OptionsLCOW) (_ *UtilityVM, err error } span.AddAttributes(trace.StringAttribute(logfields.UVMID, opts.ID)) - log.G(ctx).WithField("options", fmt.Sprintf("%+v", opts)).Debug("uvm::CreateLCOW options") + log.G(ctx).WithFields(logrus.Fields{ + logfields.Options: log.FormatEnabled(ctx, logrus.DebugLevel, opts.Options), + "options-lcow": log.FormatEnabled(ctx, logrus.DebugLevel, opts), + }).Debug("uvm::CreateLCOW options") // We dont serialize OutputHandler so if it is missing we need to put it back to the default. if opts.OutputHandler == nil { diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create_wcow.go b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create_wcow.go index ba11257b56..c4cbe0ff45 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create_wcow.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/create_wcow.go @@ -8,11 +8,12 @@ import ( "os" "path/filepath" + "github.com/Microsoft/go-winio" + "github.com/Microsoft/go-winio/pkg/guid" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "go.opencensus.io/trace" - "github.com/Microsoft/go-winio" - "github.com/Microsoft/go-winio/pkg/guid" "github.com/Microsoft/hcsshim/internal/gcs" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" @@ -233,7 +234,7 @@ func prepareConfigDoc(ctx context.Context, uvm *UtilityVM, opts *OptionsWCOW, uv // - The scratch is always attached to SCSI 0:0 // func CreateWCOW(ctx context.Context, opts *OptionsWCOW) (_ *UtilityVM, err error) { - ctx, span := trace.StartSpan(ctx, "uvm::CreateWCOW") + ctx, span := oc.StartSpan(ctx, "uvm::CreateWCOW") defer span.End() defer func() { oc.SetSpanStatus(span, err) }() @@ -246,7 +247,10 @@ func CreateWCOW(ctx context.Context, opts *OptionsWCOW) (_ *UtilityVM, err error } span.AddAttributes(trace.StringAttribute(logfields.UVMID, opts.ID)) - log.G(ctx).WithField("options", fmt.Sprintf("%+v", opts)).Debug("uvm::CreateWCOW options") + log.G(ctx).WithFields(logrus.Fields{ + logfields.Options: log.FormatEnabled(ctx, logrus.DebugLevel, opts.Options), + "options-wcow": log.FormatEnabled(ctx, logrus.DebugLevel, opts), + }).Debug("uvm::CreateWCOW options") uvm := &UtilityVM{ id: opts.ID, diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/network.go b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/network.go index 03509ad882..5f6d7c176a 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/network.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/network.go @@ -12,6 +12,7 @@ import ( "github.com/containerd/ttrpc" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" "github.com/Microsoft/hcsshim/hcn" "github.com/Microsoft/hcsshim/internal/hcs/resourcepaths" @@ -19,6 +20,7 @@ import ( "github.com/Microsoft/hcsshim/internal/hns" "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/ncproxyttrpc" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" "github.com/Microsoft/hcsshim/osversion" @@ -98,13 +100,11 @@ func (uvm *UtilityVM) SetupNetworkNamespace(ctx context.Context, nsid string) er } // GetNamespaceEndpoints gets all endpoints in `netNS` -func GetNamespaceEndpoints(ctx context.Context, netNS string) ([]*hns.HNSEndpoint, error) { - op := "uvm::GetNamespaceEndpoints" - l := log.G(ctx).WithField("netns-id", netNS) - l.Debug(op + " - Begin") - defer func() { - l.Debug(op + " - End") - }() +func GetNamespaceEndpoints(ctx context.Context, netNS string) (_ []*hns.HNSEndpoint, err error) { + ctx, span := oc.StartSpan(ctx, "uvm::GetNamespaceEndpoints") //nolint:ineffassign,staticcheck + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes(trace.StringAttribute("netns-id", netNS)) ids, err := hns.GetNamespaceEndpoints(netNS) if err != nil { diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/plan9.go b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/plan9.go index d8fce975f8..9de1b046ae 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/plan9.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/plan9.go @@ -11,9 +11,13 @@ import ( "github.com/Microsoft/hcsshim/internal/hcs" "github.com/Microsoft/hcsshim/internal/hcs/resourcepaths" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" "github.com/Microsoft/hcsshim/osversion" + "go.opencensus.io/trace" ) // Plan9Share is a struct containing host paths for the UVM @@ -34,7 +38,18 @@ func (p9 *Plan9Share) Release(ctx context.Context) error { const plan9Port = 564 // AddPlan9 adds a Plan9 share to a utility VM. -func (uvm *UtilityVM) AddPlan9(ctx context.Context, hostPath string, uvmPath string, readOnly bool, restrict bool, allowedNames []string) (*Plan9Share, error) { +func (uvm *UtilityVM) AddPlan9(ctx context.Context, hostPath string, uvmPath string, readOnly bool, restrict bool, allowedNames []string) (_ *Plan9Share, err error) { + ctx, span := oc.StartSpan(ctx, "uvm::AddPlan9") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute(logfields.UVMID, uvm.id), + trace.StringAttribute("hostPath", hostPath), + trace.StringAttribute("uvmPath", uvmPath), + trace.BoolAttribute("readOnly", readOnly), + trace.BoolAttribute("restrict", restrict), + trace.StringAttribute("allowedNamed", log.Format(ctx, allowedNames))) + if uvm.operatingSystem != "linux" { return nil, errNotSupported } @@ -110,7 +125,15 @@ func (uvm *UtilityVM) AddPlan9(ctx context.Context, hostPath string, uvmPath str // RemovePlan9 removes a Plan9 share from a utility VM. Each Plan9 share is ref-counted // and only actually removed when the ref-count drops to zero. -func (uvm *UtilityVM) RemovePlan9(ctx context.Context, share *Plan9Share) error { +func (uvm *UtilityVM) RemovePlan9(ctx context.Context, share *Plan9Share) (err error) { + ctx, span := oc.StartSpan(ctx, "uvm::RemovePlan9") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute(logfields.UVMID, uvm.id), + trace.StringAttribute("uvmPath", share.name), + trace.StringAttribute("uvmPath", share.uvmPath)) + if uvm.operatingSystem != "linux" { return errNotSupported } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/start.go b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/start.go index 412717aca6..6f65a2be5c 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/start.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/start.go @@ -115,7 +115,7 @@ func parseLogrus(vmid string) func(r io.Reader) { break } fields[logfields.UVMID] = vmid - fields["vm.time"] = gcsEntry.Time + fields["vm.time"] = log.FormatTime(gcsEntry.Time) e.Log(gcsEntry.Level, gcsEntry.Message) } } diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/vsmb.go b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/vsmb.go index 348058c7ef..9fbd613c00 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/vsmb.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/uvm/vsmb.go @@ -13,12 +13,15 @@ import ( "unsafe" "github.com/sirupsen/logrus" + "go.opencensus.io/trace" "golang.org/x/sys/windows" "github.com/Microsoft/hcsshim/internal/hcs" "github.com/Microsoft/hcsshim/internal/hcs/resourcepaths" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/winapi" "github.com/Microsoft/hcsshim/osversion" @@ -161,7 +164,16 @@ func forceNoDirectMap(path string) (bool, error) { // AddVSMB adds a VSMB share to a Windows utility VM. Each VSMB share is ref-counted and // only added if it isn't already. This is used for read-only layers, mapped directories // to a container, and for mapped pipes. -func (uvm *UtilityVM) AddVSMB(ctx context.Context, hostPath string, options *hcsschema.VirtualSmbShareOptions) (*VSMBShare, error) { +func (uvm *UtilityVM) AddVSMB(ctx context.Context, hostPath string, options *hcsschema.VirtualSmbShareOptions) (_ *VSMBShare, err error) { + ctx, span := oc.StartSpan(ctx, "uvm::AddVSMB") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute(logfields.UVMID, uvm.id), + trace.StringAttribute("hostPath", hostPath), + trace.BoolAttribute("readOnly", options.ReadOnly), + trace.BoolAttribute("restrict", options.RestrictFileAccess)) + if uvm.operatingSystem != "windows" { return nil, errNotSupported } @@ -197,7 +209,7 @@ func (uvm *UtilityVM) AddVSMB(ctx context.Context, hostPath string, options *hcs if force, err := forceNoDirectMap(hostPath); err != nil { return nil, err } else if force { - log.G(ctx).WithField("path", hostPath).Info("Forcing NoDirectmap for VSMB mount") + log.G(ctx).WithField("hostPath", hostPath).Debug("Forcing NoDirectmap for VSMB mount") options.NoDirectmap = true } @@ -230,9 +242,9 @@ func (uvm *UtilityVM) AddVSMB(ctx context.Context, hostPath string, options *hcs log.G(ctx).WithFields(logrus.Fields{ "name": share.name, "path": hostPath, - "options": fmt.Sprintf("%+#v", options), + "options": log.FormatEnabled(ctx, logrus.DebugLevel,options), "operation": requestType, - }).Info("Modifying VSMB share") + }).Debug("Modifying VSMB share") modification := &hcsschema.ModifySettingRequest{ RequestType: requestType, Settings: hcsschema.VirtualSmbShare{ @@ -257,7 +269,15 @@ func (uvm *UtilityVM) AddVSMB(ctx context.Context, hostPath string, options *hcs // RemoveVSMB removes a VSMB share from a utility VM. Each VSMB share is ref-counted // and only actually removed when the ref-count drops to zero. -func (uvm *UtilityVM) RemoveVSMB(ctx context.Context, hostPath string, readOnly bool) error { +func (uvm *UtilityVM) RemoveVSMB(ctx context.Context, hostPath string, readOnly bool) (err error) { + ctx, span := oc.StartSpan(ctx, "uvm::RemoveVSMB") + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + span.AddAttributes( + trace.StringAttribute(logfields.UVMID, uvm.id), + trace.BoolAttribute("readOnly", readOnly), + trace.StringAttribute("hostPath", hostPath)) + if uvm.operatingSystem != "windows" { return errNotSupported } @@ -394,6 +414,12 @@ func (vsmb *VSMBShare) GobDecode(data []byte) error { // clone VSMB share we just need to add it into the config doc of that VM and increase the // vsmb counter. func (vsmb *VSMBShare) Clone(ctx context.Context, vm *UtilityVM, cd *cloneData) error { + log.G(ctx).WithFields(logrus.Fields{ + "hostPath": vsmb.HostPath, + "guestPath": vsmb.guestPath, + "name": vsmb.name, + }).Trace("vsmb::Clone") + cd.doc.VirtualMachine.Devices.VirtualSmb.Shares = append(cd.doc.VirtualMachine.Devices.VirtualSmb.Shares, hcsschema.VirtualSmbShare{ Name: vsmb.name, Path: vsmb.HostPath, diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go b/test/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go index ef2e3708b8..ee3bf80559 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go @@ -4,6 +4,7 @@ package vmcompute import ( gcontext "context" + "errors" "syscall" "time" @@ -87,8 +88,8 @@ func execute(ctx gcontext.Context, timeout time.Duration, f func() error) error }() select { case <-ctx.Done(): - if ctx.Err() == gcontext.DeadlineExceeded { - log.G(ctx).WithField(logfields.Timeout, timeout). + if errors.Is(ctx.Err(), gcontext.DeadlineExceeded) { + log.G(ctx).WithField(logfields.Timeout, timeout.String()). Warning("Syscall did not complete within operation timeout. This may indicate a platform issue. If it appears to be making no forward progress, obtain the stacks and see if there is a syscall stuck in the platform API for a significant length of time.") } return ctx.Err() @@ -98,7 +99,7 @@ func execute(ctx gcontext.Context, timeout time.Duration, f func() error) error } func HcsEnumerateComputeSystems(ctx gcontext.Context, query string) (computeSystems, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsEnumerateComputeSystems") + ctx, span := oc.StartSpan(ctx, "HcsEnumerateComputeSystems") defer span.End() defer func() { if result != "" { @@ -125,7 +126,7 @@ func HcsEnumerateComputeSystems(ctx gcontext.Context, query string) (computeSyst } func HcsCreateComputeSystem(ctx gcontext.Context, id string, configuration string, identity syscall.Handle) (computeSystem HcsSystem, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsCreateComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsCreateComputeSystem") defer span.End() defer func() { if result != "" { @@ -150,7 +151,7 @@ func HcsCreateComputeSystem(ctx gcontext.Context, id string, configuration strin } func HcsOpenComputeSystem(ctx gcontext.Context, id string) (computeSystem HcsSystem, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsOpenComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsOpenComputeSystem") defer span.End() defer func() { if result != "" { @@ -170,7 +171,7 @@ func HcsOpenComputeSystem(ctx gcontext.Context, id string) (computeSystem HcsSys } func HcsCloseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem) (hr error) { - ctx, span := trace.StartSpan(ctx, "HcsCloseComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsCloseComputeSystem") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -180,7 +181,7 @@ func HcsCloseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem) (hr er } func HcsStartComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsStartComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsStartComputeSystem") defer span.End() defer func() { if result != "" { @@ -203,7 +204,7 @@ func HcsStartComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, option } func HcsShutdownComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsShutdownComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsShutdownComputeSystem") defer span.End() defer func() { if result != "" { @@ -226,7 +227,7 @@ func HcsShutdownComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, opt } func HcsTerminateComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsTerminateComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsTerminateComputeSystem") defer span.End() defer func() { if result != "" { @@ -249,7 +250,7 @@ func HcsTerminateComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, op } func HcsPauseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsPauseComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsPauseComputeSystem") defer span.End() defer func() { if result != "" { @@ -272,7 +273,7 @@ func HcsPauseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, option } func HcsResumeComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsResumeComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsResumeComputeSystem") defer span.End() defer func() { if result != "" { @@ -295,7 +296,7 @@ func HcsResumeComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, optio } func HcsGetComputeSystemProperties(ctx gcontext.Context, computeSystem HcsSystem, propertyQuery string) (properties, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsGetComputeSystemProperties") + ctx, span := oc.StartSpan(ctx, "HcsGetComputeSystemProperties") defer span.End() defer func() { if result != "" { @@ -322,7 +323,7 @@ func HcsGetComputeSystemProperties(ctx gcontext.Context, computeSystem HcsSystem } func HcsModifyComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, configuration string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsModifyComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsModifyComputeSystem") defer span.End() defer func() { if result != "" { @@ -343,7 +344,7 @@ func HcsModifyComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, confi } func HcsModifyServiceSettings(ctx gcontext.Context, settings string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsModifyServiceSettings") + ctx, span := oc.StartSpan(ctx, "HcsModifyServiceSettings") defer span.End() defer func() { if result != "" { @@ -364,7 +365,7 @@ func HcsModifyServiceSettings(ctx gcontext.Context, settings string) (result str } func HcsRegisterComputeSystemCallback(ctx gcontext.Context, computeSystem HcsSystem, callback uintptr, context uintptr) (callbackHandle HcsCallback, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsRegisterComputeSystemCallback") + ctx, span := oc.StartSpan(ctx, "HcsRegisterComputeSystemCallback") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -374,7 +375,7 @@ func HcsRegisterComputeSystemCallback(ctx gcontext.Context, computeSystem HcsSys } func HcsUnregisterComputeSystemCallback(ctx gcontext.Context, callbackHandle HcsCallback) (hr error) { - ctx, span := trace.StartSpan(ctx, "HcsUnregisterComputeSystemCallback") + ctx, span := oc.StartSpan(ctx, "HcsUnregisterComputeSystemCallback") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -384,7 +385,7 @@ func HcsUnregisterComputeSystemCallback(ctx gcontext.Context, callbackHandle Hcs } func HcsCreateProcess(ctx gcontext.Context, computeSystem HcsSystem, processParameters string) (processInformation HcsProcessInformation, process HcsProcess, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsCreateProcess") + ctx, span := oc.StartSpan(ctx, "HcsCreateProcess") defer span.End() defer func() { if result != "" { @@ -410,7 +411,7 @@ func HcsCreateProcess(ctx gcontext.Context, computeSystem HcsSystem, processPara } func HcsOpenProcess(ctx gcontext.Context, computeSystem HcsSystem, pid uint32) (process HcsProcess, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsOpenProcess") + ctx, span := oc.StartSpan(ctx, "HcsOpenProcess") defer span.End() defer func() { if result != "" { @@ -431,7 +432,7 @@ func HcsOpenProcess(ctx gcontext.Context, computeSystem HcsSystem, pid uint32) ( } func HcsCloseProcess(ctx gcontext.Context, process HcsProcess) (hr error) { - ctx, span := trace.StartSpan(ctx, "HcsCloseProcess") + ctx, span := oc.StartSpan(ctx, "HcsCloseProcess") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -441,7 +442,7 @@ func HcsCloseProcess(ctx gcontext.Context, process HcsProcess) (hr error) { } func HcsTerminateProcess(ctx gcontext.Context, process HcsProcess) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsTerminateProcess") + ctx, span := oc.StartSpan(ctx, "HcsTerminateProcess") defer span.End() defer func() { if result != "" { @@ -461,7 +462,7 @@ func HcsTerminateProcess(ctx gcontext.Context, process HcsProcess) (result strin } func HcsSignalProcess(ctx gcontext.Context, process HcsProcess, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsSignalProcess") + ctx, span := oc.StartSpan(ctx, "HcsSignalProcess") defer span.End() defer func() { if result != "" { @@ -482,7 +483,7 @@ func HcsSignalProcess(ctx gcontext.Context, process HcsProcess, options string) } func HcsGetProcessInfo(ctx gcontext.Context, process HcsProcess) (processInformation HcsProcessInformation, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsGetProcessInfo") + ctx, span := oc.StartSpan(ctx, "HcsGetProcessInfo") defer span.End() defer func() { if result != "" { @@ -502,7 +503,7 @@ func HcsGetProcessInfo(ctx gcontext.Context, process HcsProcess) (processInforma } func HcsGetProcessProperties(ctx gcontext.Context, process HcsProcess) (processProperties, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsGetProcessProperties") + ctx, span := oc.StartSpan(ctx, "HcsGetProcessProperties") defer span.End() defer func() { if result != "" { @@ -528,7 +529,7 @@ func HcsGetProcessProperties(ctx gcontext.Context, process HcsProcess) (processP } func HcsModifyProcess(ctx gcontext.Context, process HcsProcess, settings string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsModifyProcess") + ctx, span := oc.StartSpan(ctx, "HcsModifyProcess") defer span.End() defer func() { if result != "" { @@ -549,7 +550,7 @@ func HcsModifyProcess(ctx gcontext.Context, process HcsProcess, settings string) } func HcsGetServiceProperties(ctx gcontext.Context, propertyQuery string) (properties, result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsGetServiceProperties") + ctx, span := oc.StartSpan(ctx, "HcsGetServiceProperties") defer span.End() defer func() { if result != "" { @@ -576,7 +577,7 @@ func HcsGetServiceProperties(ctx gcontext.Context, propertyQuery string) (proper } func HcsRegisterProcessCallback(ctx gcontext.Context, process HcsProcess, callback uintptr, context uintptr) (callbackHandle HcsCallback, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsRegisterProcessCallback") + ctx, span := oc.StartSpan(ctx, "HcsRegisterProcessCallback") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -586,7 +587,7 @@ func HcsRegisterProcessCallback(ctx gcontext.Context, process HcsProcess, callba } func HcsUnregisterProcessCallback(ctx gcontext.Context, callbackHandle HcsCallback) (hr error) { - ctx, span := trace.StartSpan(ctx, "HcsUnregisterProcessCallback") + ctx, span := oc.StartSpan(ctx, "HcsUnregisterProcessCallback") defer span.End() defer func() { oc.SetSpanStatus(span, hr) }() @@ -596,7 +597,7 @@ func HcsUnregisterProcessCallback(ctx gcontext.Context, callbackHandle HcsCallba } func HcsSaveComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := trace.StartSpan(ctx, "HcsSaveComputeSystem") + ctx, span := oc.StartSpan(ctx, "HcsSaveComputeSystem") defer span.End() defer func() { if result != "" { diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/activatelayer.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/activatelayer.go index 98a79ef4c5..e12253c947 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/activatelayer.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/activatelayer.go @@ -16,7 +16,7 @@ import ( // An activated layer must later be deactivated via DeactivateLayer. func ActivateLayer(ctx context.Context, path string) (err error) { title := "hcsshim::ActivateLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createlayer.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createlayer.go index 4e81298514..932475723a 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createlayer.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createlayer.go @@ -14,7 +14,7 @@ import ( // the parent layer provided. func CreateLayer(ctx context.Context, path, parent string) (err error) { title := "hcsshim::CreateLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createscratchlayer.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createscratchlayer.go index 5750d53e91..5c9d5d2507 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createscratchlayer.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createscratchlayer.go @@ -15,7 +15,7 @@ import ( // This requires the full list of paths to all parent layers up to the base func CreateScratchLayer(ctx context.Context, path string, parentLayerPaths []string) (err error) { title := "hcsshim::CreateScratchLayer" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/deactivatelayer.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/deactivatelayer.go index 724af6223d..e3bc77cbc8 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/deactivatelayer.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/deactivatelayer.go @@ -13,7 +13,7 @@ import ( // DeactivateLayer will dismount a layer that was mounted via ActivateLayer. func DeactivateLayer(ctx context.Context, path string) (err error) { title := "hcsshim::DeactivateLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go index 20c5afea7f..d0a59efe12 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go @@ -14,7 +14,7 @@ import ( // path, including that layer's containing folder, if any. func DestroyLayer(ctx context.Context, path string) (err error) { title := "hcsshim::DestroyLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go index 38071322b7..e2ec27ad08 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go @@ -18,7 +18,7 @@ import ( // ExpandScratchSize expands the size of a layer to at least size bytes. func ExpandScratchSize(ctx context.Context, path string, size uint64) (err error) { title := "hcsshim::ExpandScratchSize" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/exportlayer.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/exportlayer.go index 3c388ef4bc..62e5d32c06 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/exportlayer.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/exportlayer.go @@ -21,7 +21,7 @@ import ( // perform the export. func ExportLayer(ctx context.Context, path string, exportFolderPath string, parentLayerPaths []string) (err error) { title := "hcsshim::ExportLayer" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -52,7 +52,7 @@ type LayerReader interface { // The caller must have taken the SeBackupPrivilege privilege // to call this and any methods on the resulting LayerReader. func NewLayerReader(ctx context.Context, path string, parentLayerPaths []string) (_ LayerReader, err error) { - ctx, span := trace.StartSpan(ctx, "hcsshim::NewLayerReader") + ctx, span := oc.StartSpan(ctx, "hcsshim::NewLayerReader") defer func() { if err != nil { oc.SetSpanStatus(span, err) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getlayermountpath.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getlayermountpath.go index 761b5bbd1d..715e06e379 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getlayermountpath.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getlayermountpath.go @@ -18,7 +18,7 @@ import ( // folder path at which the layer is stored. func GetLayerMountPath(ctx context.Context, path string) (_ string, err error) { title := "hcsshim::GetLayerMountPath" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getsharedbaseimages.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getsharedbaseimages.go index 1da329c7a4..5e400fb209 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getsharedbaseimages.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getsharedbaseimages.go @@ -16,7 +16,7 @@ import ( // of registering them with the graphdriver, graph, and tagstore. func GetSharedBaseImages(ctx context.Context) (_ string, err error) { title := "hcsshim::GetSharedBaseImages" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/grantvmaccess.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/grantvmaccess.go index b0da3e71df..20217ed81b 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/grantvmaccess.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/grantvmaccess.go @@ -13,7 +13,7 @@ import ( // GrantVmAccess adds access to a file for a given VM func GrantVmAccess(ctx context.Context, vmid string, filepath string) (err error) { title := "hcsshim::GrantVmAccess" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/importlayer.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/importlayer.go index cd4e470837..b9946c5f4a 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/importlayer.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/importlayer.go @@ -22,7 +22,7 @@ import ( // be present on the system at the paths provided in parentLayerPaths. func ImportLayer(ctx context.Context, path string, importFolderPath string, parentLayerPaths []string) (err error) { title := "hcsshim::ImportLayer" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( @@ -126,7 +126,7 @@ func (r *legacyLayerWriterWrapper) Close() (err error) { // The caller must have taken the SeBackupPrivilege and SeRestorePrivilege privileges // to call this and any methods on the resulting LayerWriter. func NewLayerWriter(ctx context.Context, path string, parentLayerPaths []string) (_ LayerWriter, err error) { - ctx, span := trace.StartSpan(ctx, "hcsshim::NewLayerWriter") + ctx, span := oc.StartSpan(ctx, "hcsshim::NewLayerWriter") defer func() { if err != nil { oc.SetSpanStatus(span, err) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerexists.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerexists.go index 5ee3379cfb..4d82977ea1 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerexists.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerexists.go @@ -14,7 +14,7 @@ import ( // to the system. func LayerExists(ctx context.Context, path string) (_ bool, err error) { title := "hcsshim::LayerExists" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go index ea459d2d42..d4805f1444 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go @@ -14,7 +14,7 @@ import ( // LayerID returns the layer ID of a layer on disk. func LayerID(ctx context.Context, path string) (_ guid.GUID, err error) { title := "hcsshim::LayerID" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go index 30938e3d66..c45fa2750c 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go @@ -16,7 +16,7 @@ import ( // across all clients. func NameToGuid(ctx context.Context, name string) (_ guid.GUID, err error) { title := "hcsshim::NameToGuid" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("objectName", name)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/preparelayer.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/preparelayer.go index 2f128ab153..b66e071245 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/preparelayer.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/preparelayer.go @@ -21,7 +21,7 @@ var prepareLayerLock sync.Mutex // Disabling the filter must be done via UnprepareLayer. func PrepareLayer(ctx context.Context, path string, parentLayerPaths []string) (err error) { title := "hcsshim::PrepareLayer" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := oc.StartSpan(ctx, title) defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/processimage.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/processimage.go index aaf55d887b..7c49cbda45 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/processimage.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/processimage.go @@ -14,7 +14,7 @@ import ( // The files should have been extracted to \Files. func ProcessBaseLayer(ctx context.Context, path string) (err error) { title := "hcsshim::ProcessBaseLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) @@ -30,7 +30,7 @@ func ProcessBaseLayer(ctx context.Context, path string) (err error) { // The files should have been extracted to \Files. func ProcessUtilityVMImage(ctx context.Context, path string) (err error) { title := "hcsshim::ProcessUtilityVMImage" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/unpreparelayer.go b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/unpreparelayer.go index c53a06ea2c..fe20702c18 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/unpreparelayer.go +++ b/test/vendor/github.com/Microsoft/hcsshim/internal/wclayer/unpreparelayer.go @@ -14,7 +14,7 @@ import ( // the given id. func UnprepareLayer(ctx context.Context, path string) (err error) { title := "hcsshim::UnprepareLayer" - ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes(trace.StringAttribute("path", path)) diff --git a/test/vendor/github.com/Microsoft/hcsshim/pkg/octtrpc/interceptor.go b/test/vendor/github.com/Microsoft/hcsshim/pkg/octtrpc/interceptor.go index 4bbf9484c3..90a5225bb1 100644 --- a/test/vendor/github.com/Microsoft/hcsshim/pkg/octtrpc/interceptor.go +++ b/test/vendor/github.com/Microsoft/hcsshim/pkg/octtrpc/interceptor.go @@ -67,7 +67,7 @@ func ClientInterceptor(opts ...Option) ttrpc.UnaryClientInterceptor { opt(&o) } return func(ctx context.Context, req *ttrpc.Request, resp *ttrpc.Response, info *ttrpc.UnaryClientInfo, inv ttrpc.Invoker) (err error) { - ctx, span := trace.StartSpan( + ctx, span := oc.StartSpan( ctx, convertMethodName(info.FullMethod), trace.WithSampler(o.sampler), @@ -98,7 +98,7 @@ func ServerInterceptor(opts ...Option) ttrpc.UnaryServerInterceptor { var span *trace.Span parent, ok := getParentSpanFromContext(ctx) if ok { - ctx, span = trace.StartSpanWithRemoteParent( + ctx, span = oc.StartSpanWithRemoteParent( ctx, name, parent, @@ -106,7 +106,7 @@ func ServerInterceptor(opts ...Option) ttrpc.UnaryServerInterceptor { trace.WithSampler(o.sampler), ) } else { - ctx, span = trace.StartSpan( + ctx, span = oc.StartSpan( ctx, name, trace.WithSpanKind(trace.SpanKindServer), From d67f0836c17cef45d16659ca874be1af387c83bc Mon Sep 17 00:00:00 2001 From: Hamza El-Saawy Date: Wed, 20 Apr 2022 17:22:57 -0400 Subject: [PATCH 2/2] Removing spans from guest and other areas Removing unnecessary spans in the codebase and replacing with trace logs Signed-off-by: Hamza El-Saawy --- internal/guest/bridge/bridge.go | 23 ++++---- internal/guest/network/network.go | 33 +++++------ internal/guest/runtime/hcsv2/container.go | 24 +++----- internal/guest/runtime/hcsv2/network.go | 59 +++++++------------ internal/guest/runtime/hcsv2/process.go | 5 +- .../guest/runtime/hcsv2/sandbox_container.go | 9 +-- .../runtime/hcsv2/standalone_container.go | 9 +-- .../guest/runtime/hcsv2/workload_container.go | 15 +++-- .../guest/storage/devicemapper/targets.go | 35 ++++++----- internal/guest/storage/mount.go | 16 +++-- internal/guest/storage/overlay/overlay.go | 23 +++----- internal/guest/storage/plan9/plan9.go | 20 +++---- internal/guest/storage/pmem/pmem.go | 35 +++++------ internal/guest/storage/scsi/scsi.go | 50 ++++++---------- internal/log/hook.go | 25 ++++---- internal/logfields/fields.go | 2 + 16 files changed, 161 insertions(+), 222 deletions(-) diff --git a/internal/guest/bridge/bridge.go b/internal/guest/bridge/bridge.go index ff64f6352d..730b8cb9d6 100644 --- a/internal/guest/bridge/bridge.go +++ b/internal/guest/bridge/bridge.go @@ -17,15 +17,16 @@ import ( "sync/atomic" "time" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "go.opencensus.io/trace" + "go.opencensus.io/trace/tracestate" + "github.com/Microsoft/hcsshim/internal/guest/gcserr" "github.com/Microsoft/hcsshim/internal/guest/prot" "github.com/Microsoft/hcsshim/internal/guest/runtime/hcsv2" "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/oc" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "go.opencensus.io/trace" - "go.opencensus.io/trace/tracestate" ) // UnknownMessage represents the default handler logic for an unmatched request @@ -291,16 +292,18 @@ func (b *Bridge) ListenAndServe(bridgeIn io.ReadCloser, bridgeOut io.WriteCloser } } } - ctx, span = trace.StartSpanWithRemoteParent(context.Background(), + ctx, span = oc.StartSpanWithRemoteParent( + context.Background(), "opengcs::bridge::request", sc, - oc.WithTraceLevelSampler, - oc.WithServerSpanKind) - ctx = log.U(ctx) + oc.WithServerSpanKind, + ) } else { - ctx, span = oc.StartSpan(context.Background(), + ctx, span = oc.StartSpan( + context.Background(), "opengcs::bridge::request", - oc.WithServerSpanKind) + oc.WithServerSpanKind, + ) } span.AddAttributes( diff --git a/internal/guest/network/network.go b/internal/guest/network/network.go index 318671b99b..7343bc40cf 100644 --- a/internal/guest/network/network.go +++ b/internal/guest/network/network.go @@ -13,13 +13,13 @@ import ( "strings" "time" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/Microsoft/hcsshim/internal/guest/storage" "github.com/Microsoft/hcsshim/internal/guest/storage/pci" "github.com/Microsoft/hcsshim/internal/guest/storage/vmbus" "github.com/Microsoft/hcsshim/internal/log" - "github.com/Microsoft/hcsshim/internal/oc" - "github.com/pkg/errors" - "go.opencensus.io/trace" ) // mock out calls for testing @@ -35,9 +35,9 @@ const maxDNSSearches = 6 // GenerateEtcHostsContent generates a /etc/hosts file based on `hostname`. func GenerateEtcHostsContent(ctx context.Context, hostname string) string { - _, span := oc.StartSpan(ctx, "network::GenerateEtcHostsContent") - defer span.End() - span.AddAttributes(trace.StringAttribute("hostname", hostname)) + log.G(ctx).WithFields(logrus.Fields{ + "hostname": hostname, + }).Trace("network::GenerateEtcHostsContent") nameParts := strings.Split(hostname, ".") buf := bytes.Buffer{} @@ -60,14 +60,11 @@ func GenerateEtcHostsContent(ctx context.Context, hostname string) string { // GenerateResolvConfContent generates the resolv.conf file content based on // `searches`, `servers`, and `options`. func GenerateResolvConfContent(ctx context.Context, searches, servers, options []string) (_ string, err error) { - _, span := oc.StartSpan(ctx, "network::GenerateResolvConfContent") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.StringAttribute("searches", strings.Join(searches, ", ")), - trace.StringAttribute("servers", strings.Join(servers, ", ")), - trace.StringAttribute("options", strings.Join(options, ", "))) + log.G(ctx).WithFields(logrus.Fields{ + "searches": searches, + "servers": servers, + "options": options, + }).Trace("network::GenerateResolvConfContent") if len(searches) > maxDNSSearches { return "", errors.Errorf("searches has more than %d domains", maxDNSSearches) @@ -116,12 +113,10 @@ func MergeValues(first, second []string) []string { // // Will retry the operation until `ctx` is exceeded or canceled. func InstanceIDToName(ctx context.Context, id string, vpciAssigned bool) (_ string, err error) { - ctx, span := oc.StartSpan(ctx, "network::InstanceIDToName") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - vmBusID := strings.ToLower(id) - span.AddAttributes(trace.StringAttribute("adapterInstanceID", vmBusID)) + log.G(ctx).WithFields(logrus.Fields{ + "adapterInstanceID": vmBusID, + }).Trace("network::InstanceIDToName") netDevicePath := "" if vpciAssigned { diff --git a/internal/guest/runtime/hcsv2/container.go b/internal/guest/runtime/hcsv2/container.go index 021ef5fb47..a5ec75d798 100644 --- a/internal/guest/runtime/hcsv2/container.go +++ b/internal/guest/runtime/hcsv2/container.go @@ -13,7 +13,6 @@ import ( oci "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "go.opencensus.io/trace" "github.com/Microsoft/hcsshim/internal/guest/gcserr" "github.com/Microsoft/hcsshim/internal/guest/prot" @@ -24,7 +23,6 @@ import ( "github.com/Microsoft/hcsshim/internal/guest/transport" "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/logfields" - "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" ) @@ -47,7 +45,7 @@ type Container struct { } func (c *Container) Start(ctx context.Context, conSettings stdio.ConnectionSettings) (int, error) { - log.G(ctx).WithField(logfields.ContainerID, c.id).Info("opengcs::Container::Start") + log.G(ctx).WithField(logfields.ContainerID, c.id).Trace("opengcs::Container::Start") stdioSet, err := stdio.Connect(c.vsock, conSettings) if err != nil { return -1, err @@ -70,7 +68,7 @@ func (c *Container) Start(ctx context.Context, conSettings stdio.ConnectionSetti } func (c *Container) ExecProcess(ctx context.Context, process *oci.Process, conSettings stdio.ConnectionSettings) (int, error) { - log.G(ctx).WithField(logfields.ContainerID, c.id).Info("opengcs::Container::ExecProcess") + log.G(ctx).WithField(logfields.ContainerID, c.id).Trace("opengcs::Container::ExecProcess") stdioSet, err := stdio.Connect(c.vsock, conSettings) if err != nil { return -1, err @@ -115,7 +113,7 @@ func (c *Container) GetProcess(pid uint32) (Process, error) { logrus.WithFields(logrus.Fields{ logfields.ContainerID: c.id, logfields.ProcessID: pid, - }).Info("opengcs::Container::GetProcesss") + }).Trace("opengcs::Container::GetProcesss") if c.initProcess.pid == pid { return c.initProcess, nil } @@ -132,7 +130,7 @@ func (c *Container) GetProcess(pid uint32) (Process, error) { // GetAllProcessPids returns all process pids in the container namespace. func (c *Container) GetAllProcessPids(ctx context.Context) ([]int, error) { - log.G(ctx).WithField(logfields.ContainerID, c.id).Info("opengcs::Container::GetAllProcessPids") + log.G(ctx).WithField(logfields.ContainerID, c.id).Trace("opengcs::Container::GetAllProcessPids") state, err := c.container.GetAllProcesses() if err != nil { return nil, err @@ -146,7 +144,7 @@ func (c *Container) GetAllProcessPids(ctx context.Context) ([]int, error) { // Kill sends 'signal' to the container process. func (c *Container) Kill(ctx context.Context, signal syscall.Signal) error { - log.G(ctx).WithField(logfields.ContainerID, c.id).Info("opengcs::Container::Kill") + log.G(ctx).WithField(logfields.ContainerID, c.id).Trace("opengcs::Container::Kill") err := c.container.Kill(signal) if err != nil { return err @@ -157,7 +155,7 @@ func (c *Container) Kill(ctx context.Context, signal syscall.Signal) error { func (c *Container) Delete(ctx context.Context) error { entity := log.G(ctx).WithField(logfields.ContainerID, c.id) - entity.Info("opengcs::Container::Delete") + entity.Trace("opengcs::Container::Delete") if c.isSandbox { // remove user mounts in sandbox container if err := storage.UnmountAllInPath(ctx, specInternal.SandboxMountsDir(c.id), true); err != nil { @@ -174,15 +172,13 @@ func (c *Container) Delete(ctx context.Context) error { } func (c *Container) Update(ctx context.Context, resources interface{}) error { - log.G(ctx).WithField(logfields.ContainerID, c.id).Info("opengcs::Container::Update") + log.G(ctx).WithField(logfields.ContainerID, c.id).Trace("opengcs::Container::Update") return c.container.Update(resources) } // Wait waits for the container's init process to exit. func (c *Container) Wait() prot.NotificationType { - _, span := oc.StartSpan(context.Background(), "opengcs::Container::Wait") - defer span.End() - span.AddAttributes(trace.StringAttribute(logfields.ContainerID, c.id)) + log.L.WithField(logfields.ContainerID, c.id).Trace("opengcs::Container::Wait") c.initProcess.writersWg.Wait() c.etL.Lock() @@ -205,9 +201,7 @@ func (c *Container) setExitType(signal syscall.Signal) { // GetStats returns the cgroup metrics for the container. func (c *Container) GetStats(ctx context.Context) (*v1.Metrics, error) { - _, span := oc.StartSpan(ctx, "opengcs::Container::GetStats") - defer span.End() - span.AddAttributes(trace.StringAttribute("cid", c.id)) + log.G(ctx).WithField(logfields.ContainerID, c.id).Trace("opengcs::Container::GetStats") cgroupPath := c.spec.Linux.CgroupsPath cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(cgroupPath)) diff --git a/internal/guest/runtime/hcsv2/network.go b/internal/guest/runtime/hcsv2/network.go index 8ff63b317d..979da9ef2e 100644 --- a/internal/guest/runtime/hcsv2/network.go +++ b/internal/guest/runtime/hcsv2/network.go @@ -5,19 +5,19 @@ package hcsv2 import ( "context" - "fmt" "strings" "sync" "time" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/vishvananda/netns" - "go.opencensus.io/trace" "github.com/Microsoft/hcsshim/internal/guest/gcserr" "github.com/Microsoft/hcsshim/internal/guest/network" "github.com/Microsoft/hcsshim/internal/guest/prot" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" ) @@ -71,12 +71,8 @@ func getOrAddNetworkNamespace(id string) *namespace { // removeNetworkNamespace removes the in-memory `namespace` found by `id`. func removeNetworkNamespace(ctx context.Context, id string) (err error) { - _, span := oc.StartSpan(ctx, "hcsv2::removeNetworkNamespace") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - id = strings.ToLower(id) - span.AddAttributes(trace.StringAttribute("id", id)) + log.G(ctx).WithField(logfields.ID, id).Trace("hcsv2::removeNetworkNamespace") namespaceSync.Lock() defer namespaceSync.Unlock() @@ -112,12 +108,10 @@ func (n *namespace) ID() string { // assigned adapters into this namespace. The caller MUST call `Sync()` to // complete this operation. func (n *namespace) AssignContainerPid(ctx context.Context, pid int) (err error) { - _, span := oc.StartSpan(ctx, "namespace::AssignContainerPid") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("namespace", n.id), - trace.Int64Attribute("pid", int64(pid))) + log.G(ctx).WithFields(logrus.Fields{ + logfields.ProcessID: pid, + logfields.Namespace: n.id, + }).Trace("namespace::AssignContainerPid") n.m.Lock() defer n.m.Unlock() @@ -147,12 +141,10 @@ func (n *namespace) Adapters() []*guestresource.LCOWNetworkAdapter { // namespace assigned to `n`. A user must call `Sync()` to complete this // operation. func (n *namespace) AddAdapter(ctx context.Context, adp *guestresource.LCOWNetworkAdapter) (err error) { - ctx, span := oc.StartSpan(ctx, "namespace::AddAdapter") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("namespace", n.id), - trace.StringAttribute("adapter", log.Format(ctx, adp))) + log.G(ctx).WithFields(logrus.Fields{ + logfields.Namespace: n.id, + "adapter": adp, + }).Trace("namespace::AddAdapter") n.m.Lock() defer n.m.Unlock() @@ -179,12 +171,10 @@ func (n *namespace) AddAdapter(ctx context.Context, adp *guestresource.LCOWNetwo // RemoveAdapter removes the adapter matching `id` from `n`. If `id` is not // found returns no error. func (n *namespace) RemoveAdapter(ctx context.Context, id string) (err error) { - _, span := oc.StartSpan(ctx, "namespace::RemoveAdapter") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("namespace", n.id), - trace.StringAttribute("adapterID", id)) + log.G(ctx).WithFields(logrus.Fields{ + logfields.Namespace: n.id, + "adapterID": id, + }).Trace("namespace::RemoveAdapter") n.m.Lock() defer n.m.Unlock() @@ -206,10 +196,7 @@ func (n *namespace) RemoveAdapter(ctx context.Context, id string) (err error) { // Sync moves all adapters to the network namespace of `n` if assigned. func (n *namespace) Sync(ctx context.Context) (err error) { - ctx, span := oc.StartSpan(ctx, "namespace::Sync") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("namespace", n.id)) + log.G(ctx).WithField(logfields.Namespace, n.id).Trace("namespace::Sync") n.m.Lock() defer n.m.Unlock() @@ -244,13 +231,11 @@ type nicInNamespace struct { // assignToPid assigns `nin.adapter`, represented by `nin.ifname` to `pid`. func (nin *nicInNamespace) assignToPid(ctx context.Context, pid int) (err error) { - ctx, span := oc.StartSpan(ctx, "nicInNamespace::assignToPid") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("adapterID", nin.adapter.ID), - trace.StringAttribute("ifname", nin.ifname), - trace.Int64Attribute("pid", int64(pid))) + log.G(ctx).WithFields(logrus.Fields{ + "adapterID": nin.adapter.ID, + "ifname": nin.ifname, + logfields.ProcessID: int64(pid), + }).Trace("nicInNamespace::assignToPid") v1Adapter := &prot.NetworkAdapter{ NatEnabled: nin.adapter.IPAddress != "", diff --git a/internal/guest/runtime/hcsv2/process.go b/internal/guest/runtime/hcsv2/process.go index 227aae1197..cf3f6a2016 100644 --- a/internal/guest/runtime/hcsv2/process.go +++ b/internal/guest/runtime/hcsv2/process.go @@ -14,6 +14,7 @@ import ( "github.com/Microsoft/hcsshim/internal/guest/runtime" "github.com/Microsoft/hcsshim/internal/guest/stdio" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" oci "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -87,8 +88,8 @@ func newProcess(c *Container, spec *oci.Process, process runtime.Process, pid ui ctx, span := oc.StartSpan(context.Background(), "newProcess::waitBackground") defer span.End() span.AddAttributes( - trace.StringAttribute("cid", p.cid), - trace.Int64Attribute("pid", int64(p.pid))) + trace.StringAttribute(logfields.ContainerID, p.cid), + trace.Int64Attribute(logfields.ProcessID, int64(p.pid))) // Wait for the process to exit exitCode, err := p.process.Wait() diff --git a/internal/guest/runtime/hcsv2/sandbox_container.go b/internal/guest/runtime/hcsv2/sandbox_container.go index 4280eeb329..7068fd14d1 100644 --- a/internal/guest/runtime/hcsv2/sandbox_container.go +++ b/internal/guest/runtime/hcsv2/sandbox_container.go @@ -12,11 +12,11 @@ import ( oci "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - "go.opencensus.io/trace" "github.com/Microsoft/hcsshim/internal/guest/network" specInternal "github.com/Microsoft/hcsshim/internal/guest/spec" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/pkg/annotations" ) @@ -33,10 +33,7 @@ func getSandboxResolvPath(id string) string { } func setupSandboxContainerSpec(ctx context.Context, id string, spec *oci.Spec) (err error) { - ctx, span := oc.StartSpan(ctx, "hcsv2::setupSandboxContainerSpec") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", id)) + log.G(ctx).WithField(logfields.ContainerID, id).Trace("hcsv2::setupSandboxContainerSpec") // Generate the sandbox root dir rootDir := specInternal.SandboxRootDir(id) diff --git a/internal/guest/runtime/hcsv2/standalone_container.go b/internal/guest/runtime/hcsv2/standalone_container.go index 6da310a1e2..fefa6d7ce5 100644 --- a/internal/guest/runtime/hcsv2/standalone_container.go +++ b/internal/guest/runtime/hcsv2/standalone_container.go @@ -12,12 +12,12 @@ import ( oci "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - "go.opencensus.io/trace" "github.com/Microsoft/hcsshim/internal/guest/network" specInternal "github.com/Microsoft/hcsshim/internal/guest/spec" "github.com/Microsoft/hcsshim/internal/guestpath" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" ) func getStandaloneRootDir(id string) string { @@ -37,10 +37,7 @@ func getStandaloneResolvPath(id string) string { } func setupStandaloneContainerSpec(ctx context.Context, id string, spec *oci.Spec) (err error) { - ctx, span := oc.StartSpan(ctx, "hcsv2::setupStandaloneContainerSpec") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", id)) + log.G(ctx).WithField(logfields.ContainerID, id).Trace("hcsv2::setupStandaloneContainerSpec") // Generate the standalone root dir rootDir := getStandaloneRootDir(id) diff --git a/internal/guest/runtime/hcsv2/workload_container.go b/internal/guest/runtime/hcsv2/workload_container.go index 35ba49744b..646bfd00ad 100644 --- a/internal/guest/runtime/hcsv2/workload_container.go +++ b/internal/guest/runtime/hcsv2/workload_container.go @@ -11,12 +11,13 @@ import ( oci "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - "go.opencensus.io/trace" + "github.com/sirupsen/logrus" "golang.org/x/sys/unix" specInternal "github.com/Microsoft/hcsshim/internal/guest/spec" "github.com/Microsoft/hcsshim/internal/guestpath" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/pkg/annotations" ) @@ -98,12 +99,10 @@ func specHasGPUDevice(spec *oci.Spec) bool { } func setupWorkloadContainerSpec(ctx context.Context, sbid, id string, spec *oci.Spec) (err error) { - ctx, span := oc.StartSpan(ctx, "hcsv2::setupWorkloadContainerSpec") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("sandboxID", sbid), - trace.StringAttribute("cid", id)) + log.G(ctx).WithFields(logrus.Fields{ + logfields.SandboxID: sbid, + logfields.ContainerID: id, + }).Trace("hcsv2::setupWorkloadContainerSpec") // Verify no hostname if spec.Hostname != "" { diff --git a/internal/guest/storage/devicemapper/targets.go b/internal/guest/storage/devicemapper/targets.go index 2235f76c74..ab8df11a9d 100644 --- a/internal/guest/storage/devicemapper/targets.go +++ b/internal/guest/storage/devicemapper/targets.go @@ -8,29 +8,26 @@ import ( "fmt" "github.com/pkg/errors" - "go.opencensus.io/trace" + "github.com/sirupsen/logrus" "github.com/Microsoft/hcsshim/ext4/dmverity" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" ) // CreateZeroSectorLinearTarget creates dm-linear target for a device at `devPath` and `mappingInfo`, returns // virtual block device path. func CreateZeroSectorLinearTarget(ctx context.Context, devPath, devName string, mappingInfo *guestresource.LCOWVPMemMappingInfo) (_ string, err error) { - _, span := oc.StartSpan(ctx, "devicemapper::CreateZeroSectorLinearTarget") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - size := int64(mappingInfo.DeviceSizeInBytes) offset := int64(mappingInfo.DeviceOffsetInBytes) linearTarget := zeroSectorLinearTarget(size, devPath, offset) - span.AddAttributes( - trace.StringAttribute("devicePath", devPath), - trace.Int64Attribute("deviceStart", offset), - trace.Int64Attribute("sectorSize", size), - trace.StringAttribute("linearTable", fmt.Sprintf("%s: '%d %d %s'", devName, linearTarget.SectorStart, linearTarget.LengthInBlocks, linearTarget.Params))) + log.G(ctx).WithFields(logrus.Fields{ + "devicePath": devPath, + "deviceStart": offset, + "sectorSize": size, + "linearTable": fmt.Sprintf("%s: '%d %d %s'", devName, linearTarget.SectorStart, linearTarget.LengthInBlocks, linearTarget.Params), + }).Trace("devicemapper::CreateZeroSectorLinearTarget") devMapperPath, err := CreateDevice(devName, CreateReadOnly, []Target{linearTarget}) if err != nil { @@ -49,9 +46,11 @@ func CreateZeroSectorLinearTarget(ctx context.Context, devPath, devName string, // size | version hash_dev | hash_offset // target hash_block func CreateVerityTarget(ctx context.Context, devPath, devName string, verityInfo *guestresource.DeviceVerityInfo) (_ string, err error) { - _, span := oc.StartSpan(ctx, "devicemapper::CreateVerityTarget") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() + entity := log.G(ctx).WithFields(logrus.Fields{ + "devicePath": devPath, + "deviceName": devName, + }) + entity.Trace("devicemapper::CreateVerityTarget") dmBlocks := verityInfo.Ext4SizeInBytes / blockSize dataBlocks := verityInfo.Ext4SizeInBytes / int64(verityInfo.BlockSize) @@ -70,10 +69,10 @@ func CreateVerityTarget(ctx context.Context, devPath, devName string, verityInfo Params: fmt.Sprintf("%d %s %s %s", verityInfo.Version, devices, blkInfo, hashes), } - span.AddAttributes( - trace.StringAttribute("devicePath", devPath), - trace.Int64Attribute("sectorSize", dmBlocks), - trace.StringAttribute("verityTable", verityTarget.Params)) + entity.WithFields(logrus.Fields{ + "sectorSize": dmBlocks, + "verityTable": verityTarget.Params, + }).Debug("created dm-verity target") mapperPath, err := CreateDevice(devName, CreateReadOnly, []Target{verityTarget}) if err != nil { diff --git a/internal/guest/storage/mount.go b/internal/guest/storage/mount.go index cf7c62d45c..203fc5a105 100644 --- a/internal/guest/storage/mount.go +++ b/internal/guest/storage/mount.go @@ -11,9 +11,10 @@ import ( "strings" "syscall" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/sirupsen/logrus" + + "github.com/Microsoft/hcsshim/internal/log" "github.com/pkg/errors" - "go.opencensus.io/trace" "golang.org/x/sys/unix" ) @@ -114,13 +115,10 @@ func MountRShared(path string) error { // UnmountPath unmounts the target path if it exists and is a mount path. If // removeTarget this will remove the previously mounted folder. func UnmountPath(ctx context.Context, target string, removeTarget bool) (err error) { - _, span := oc.StartSpan(ctx, "storage::UnmountPath") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.StringAttribute("target", target), - trace.BoolAttribute("remove", removeTarget)) + log.G(ctx).WithFields(logrus.Fields{ + "target": target, + "remove": removeTarget, + }).Trace("storage::UnmountPath") if _, err := osStat(target); err != nil { if os.IsNotExist(err) { diff --git a/internal/guest/storage/overlay/overlay.go b/internal/guest/storage/overlay/overlay.go index 329940d89f..869dd62c70 100644 --- a/internal/guest/storage/overlay/overlay.go +++ b/internal/guest/storage/overlay/overlay.go @@ -12,11 +12,9 @@ import ( "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/memory" - "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/pkg/securitypolicy" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "go.opencensus.io/trace" "golang.org/x/sys/unix" ) @@ -60,9 +58,7 @@ func processErrNoSpace(ctx context.Context, path string, err error) { // MountLayer first enforces the security policy for the container's layer paths // and then calls Mount to mount the layer paths as an overlayfs func MountLayer(ctx context.Context, layerPaths []string, upperdirPath, workdirPath, rootfsPath string, readonly bool, containerId string, securityPolicy securitypolicy.SecurityPolicyEnforcer) (err error) { - _, span := oc.StartSpan(ctx, "overlay::MountLayer") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() + log.G(ctx).Trace("overlay::MountLayer") if err := securityPolicy.EnforceOverlayMountPolicy(containerId, layerPaths); err != nil { return err @@ -81,17 +77,14 @@ func MountLayer(ctx context.Context, layerPaths []string, upperdirPath, workdirP // Always creates `target`. On mount failure the created `target` will // be automatically cleaned up. func Mount(ctx context.Context, basePaths []string, upperdirPath, workdirPath, target string, readonly bool) (err error) { - _, span := oc.StartSpan(ctx, "overlay::Mount") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - lowerdir := strings.Join(basePaths, ":") - span.AddAttributes( - trace.StringAttribute("lowerdir", lowerdir), - trace.StringAttribute("upperdirPath", upperdirPath), - trace.StringAttribute("workdirPath", workdirPath), - trace.StringAttribute("target", target), - trace.BoolAttribute("readonly", readonly)) + log.G(ctx).WithFields(logrus.Fields{ + "lowerdir": lowerdir, + "upperdirPath": upperdirPath, + "workdirPath": workdirPath, + "target": target, + "readonly": readonly, + }).Trace("overlay::Mount") // If we got an ENOSPC error on creating any directories, log disk space and inode info for the mount that the directory belongs to get a better // view of the where the problem lies. diff --git a/internal/guest/storage/plan9/plan9.go b/internal/guest/storage/plan9/plan9.go index 2d98a762a6..bfceba261a 100644 --- a/internal/guest/storage/plan9/plan9.go +++ b/internal/guest/storage/plan9/plan9.go @@ -9,10 +9,11 @@ import ( "os" "syscall" + "github.com/sirupsen/logrus" + "github.com/Microsoft/hcsshim/internal/guest/transport" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/log" "github.com/pkg/errors" - "go.opencensus.io/trace" "golang.org/x/sys/unix" ) @@ -30,15 +31,12 @@ var ( // `target` will be created. On mount failure the created `target` will be // automatically cleaned up. func Mount(ctx context.Context, vsock transport.Transport, target, share string, port uint32, readonly bool) (err error) { - _, span := oc.StartSpan(ctx, "plan9::Mount") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.StringAttribute("target", target), - trace.StringAttribute("share", share), - trace.Int64Attribute("port", int64(port)), - trace.BoolAttribute("readonly", readonly)) + log.G(ctx).WithFields(logrus.Fields{ + "target": target, + "share": share, + "port": port, + "readonly": readonly, + }).Trace("plan9::Mount") if err := osMkdirAll(target, 0700); err != nil { return err diff --git a/internal/guest/storage/pmem/pmem.go b/internal/guest/storage/pmem/pmem.go index f6ec60d157..26387fb25d 100644 --- a/internal/guest/storage/pmem/pmem.go +++ b/internal/guest/storage/pmem/pmem.go @@ -9,13 +9,12 @@ import ( "os" "github.com/pkg/errors" - "go.opencensus.io/trace" + "github.com/sirupsen/logrus" "golang.org/x/sys/unix" "github.com/Microsoft/hcsshim/internal/guest/storage" dm "github.com/Microsoft/hcsshim/internal/guest/storage/devicemapper" "github.com/Microsoft/hcsshim/internal/log" - "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" "github.com/Microsoft/hcsshim/pkg/securitypolicy" ) @@ -78,13 +77,10 @@ func Mount( verityInfo *guestresource.DeviceVerityInfo, securityPolicy securitypolicy.SecurityPolicyEnforcer, ) (err error) { - mCtx, span := oc.StartSpan(ctx, "pmem::Mount") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.Int64Attribute("deviceNumber", int64(device)), - trace.StringAttribute("target", target)) + log.G(ctx).WithFields(logrus.Fields{ + "device": device, + "target": target, + }).Trace("pmem::Mount") devicePath := fmt.Sprintf(pMemFmt, device) @@ -101,13 +97,13 @@ func Mount( // device instead of the original VPMem. if mappingInfo != nil { dmLinearName := fmt.Sprintf(linearDeviceFmt, device, mappingInfo.DeviceOffsetInBytes, mappingInfo.DeviceSizeInBytes) - if devicePath, err = createZeroSectorLinearTarget(mCtx, devicePath, dmLinearName, mappingInfo); err != nil { + if devicePath, err = createZeroSectorLinearTarget(ctx, devicePath, dmLinearName, mappingInfo); err != nil { return err } defer func() { if err != nil { if err := removeDevice(dmLinearName); err != nil { - log.G(mCtx).WithError(err).Debugf("failed to cleanup linear target: %s", dmLinearName) + log.G(ctx).WithError(err).Debugf("failed to cleanup linear target: %s", dmLinearName) } } }() @@ -115,19 +111,19 @@ func Mount( if verityInfo != nil { dmVerityName := fmt.Sprintf(verityDeviceFmt, device, verityInfo.RootDigest) - if devicePath, err = createVerityTarget(mCtx, devicePath, dmVerityName, verityInfo); err != nil { + if devicePath, err = createVerityTarget(ctx, devicePath, dmVerityName, verityInfo); err != nil { return err } defer func() { if err != nil { if err := removeDevice(dmVerityName); err != nil { - log.G(mCtx).WithError(err).Debugf("failed to cleanup verity target: %s", dmVerityName) + log.G(ctx).WithError(err).Debugf("failed to cleanup verity target: %s", dmVerityName) } } }() } - return mountInternal(mCtx, devicePath, target) + return mountInternal(ctx, devicePath, target) } // Unmount unmounts `target` and removes corresponding linear and verity targets when needed @@ -139,13 +135,10 @@ func Unmount( verityInfo *guestresource.DeviceVerityInfo, securityPolicy securitypolicy.SecurityPolicyEnforcer, ) (err error) { - _, span := oc.StartSpan(ctx, "pmem::Unmount") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.Int64Attribute("device", int64(devNumber)), - trace.StringAttribute("target", target)) + log.G(ctx).WithFields(logrus.Fields{ + "device": devNumber, + "target": target, + }).Trace(ctx, "pmem::Unmount") if err := securityPolicy.EnforceDeviceUnmountPolicy(target); err != nil { return errors.Wrapf(err, "unmounting pmem device from %s denied by policy", target) diff --git a/internal/guest/storage/scsi/scsi.go b/internal/guest/storage/scsi/scsi.go index 71bdbcc0c4..8a066d1eef 100644 --- a/internal/guest/storage/scsi/scsi.go +++ b/internal/guest/storage/scsi/scsi.go @@ -15,14 +15,13 @@ import ( "time" "github.com/pkg/errors" - "go.opencensus.io/trace" + "github.com/sirupsen/logrus" "golang.org/x/sys/unix" "github.com/Microsoft/hcsshim/internal/guest/storage" "github.com/Microsoft/hcsshim/internal/guest/storage/crypt" dm "github.com/Microsoft/hcsshim/internal/guest/storage/devicemapper" "github.com/Microsoft/hcsshim/internal/log" - "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/protocol/guestresource" "github.com/Microsoft/hcsshim/pkg/securitypolicy" @@ -100,13 +99,11 @@ func mount( verityInfo *guestresource.DeviceVerityInfo, securityPolicy securitypolicy.SecurityPolicyEnforcer, ) (err error) { - spnCtx, span := oc.StartSpan(ctx, "scsi::Mount") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.Int64Attribute("controller", int64(controller)), - trace.Int64Attribute("lun", int64(lun))) + log.G(ctx).WithFields(logrus.Fields{ + "controller": controller, + "lun": lun, + }).Trace("scsi::Mount") + spnCtx := ctx source, err := controllerLunToName(spnCtx, controller, lun) if err != nil { @@ -229,14 +226,11 @@ func unmount( verityInfo *guestresource.DeviceVerityInfo, securityPolicy securitypolicy.SecurityPolicyEnforcer, ) (err error) { - ctx, span := oc.StartSpan(ctx, "scsi::Unmount") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.Int64Attribute("controller", int64(controller)), - trace.Int64Attribute("lun", int64(lun)), - trace.StringAttribute("target", target)) + log.G(ctx).WithFields(logrus.Fields{ + "controller": controller, + "lun": lun, + "target": target, + }).Trace("scsi::Unmount") if err = securityPolicy.EnforceDeviceUnmountPolicy(target); err != nil { return errors.Wrapf(err, "unmounting scsi controller %d lun %d from %s denied by policy", controller, lun, target) @@ -285,13 +279,10 @@ func Unmount( // ControllerLunToName finds the `/dev/sd*` path to the SCSI device on // `controller` index `lun`. func ControllerLunToName(ctx context.Context, controller, lun uint8) (_ string, err error) { - ctx, span := oc.StartSpan(ctx, "scsi::ControllerLunToName") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.Int64Attribute("controller", int64(controller)), - trace.Int64Attribute("lun", int64(lun))) + log.G(ctx).WithFields(logrus.Fields{ + "controller": controller, + "lun": lun, + }).Trace("scsi::ControllerLunToName") scsiID := fmt.Sprintf("%d:0:0:%d", controller, lun) // Devices matching the given SCSI code should each have a subdirectory @@ -329,13 +320,10 @@ func ControllerLunToName(ctx context.Context, controller, lun uint8) (_ string, // // If the device is not attached returns no error. func unplugDevice(ctx context.Context, controller, lun uint8) (err error) { - _, span := oc.StartSpan(ctx, "scsi::UnplugDevice") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.Int64Attribute("controller", int64(controller)), - trace.Int64Attribute("lun", int64(lun))) + log.G(ctx).WithFields(logrus.Fields{ + "controller": controller, + "lun": lun, + }).Trace("scsi::UnplugDevice") scsiID := fmt.Sprintf("%d:0:0:%d", controller, lun) f, err := os.OpenFile(filepath.Join(scsiDevicesPath, scsiID, "delete"), os.O_WRONLY, 0644) diff --git a/internal/log/hook.go b/internal/log/hook.go index 73a7f8c29a..c3afe10f8f 100644 --- a/internal/log/hook.go +++ b/internal/log/hook.go @@ -81,20 +81,17 @@ func (h *Hook) encode(e *logrus.Entry) { d[k] = vv.Format(h.TimeFormat) } continue - case bytes.Buffer, *bytes.Buffer: - // this resolves `vv` to `interface{}`, so cannot use `vv.Bytes` - // Could move to below the `reflect.Indirect()` call below, but - // that would require additional typematching and dereferencing, - // regardless. Easier to keep these duplicate - // branches here - if vp, ok := vv.(bytes.Buffer); ok { - vv = &vp - } - v = (vv.(*bytes.Buffer)).Bytes() - // case bytes.Buffer: - // v = vv.Bytes() - // case *bytes.Buffer: - // v = vv.Bytes() + + // `case bytes.Buffer,*bytes.Buffer` resolves `vv` to `interface{}`, + // so cannot use `vv.Bytes`. + // Could move to below the `reflect.Indirect()` call below, but + // that would require additional typematching and dereferencing, + // regardless. + // Easier to keep these duplicate branches here. + case bytes.Buffer: + v = vv.Bytes() + case *bytes.Buffer: + v = vv.Bytes() } if !h.EncodeAsJSON { continue diff --git a/internal/logfields/fields.go b/internal/logfields/fields.go index 7f2dfe2626..3e175e5222 100644 --- a/internal/logfields/fields.go +++ b/internal/logfields/fields.go @@ -4,9 +4,11 @@ const ( // Identifiers Name = "name" + Namespace = "namespace" Operation = "operation" ID = "id" + SandboxID = "sid" ContainerID = "cid" ExecID = "eid" ProcessID = "pid"