github.com/moby/docker@v26.1.3+incompatible/daemon/metrics_unix.go (about)

     1  //go:build !windows
     2  
     3  package daemon // import "github.com/docker/docker/daemon"
     4  
     5  import (
     6  	"context"
     7  	"net"
     8  	"net/http"
     9  	"path/filepath"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/containerd/log"
    14  	"github.com/docker/docker/daemon/config"
    15  	"github.com/docker/docker/pkg/plugingetter"
    16  	"github.com/docker/docker/pkg/plugins"
    17  	"github.com/docker/docker/plugin"
    18  	metrics "github.com/docker/go-metrics"
    19  	specs "github.com/opencontainers/runtime-spec/specs-go"
    20  	"github.com/pkg/errors"
    21  	"golang.org/x/sys/unix"
    22  )
    23  
    24  func (daemon *Daemon) listenMetricsSock(cfg *config.Config) (string, error) {
    25  	path := filepath.Join(cfg.ExecRoot, "metrics.sock")
    26  	unix.Unlink(path)
    27  	l, err := net.Listen("unix", path)
    28  	if err != nil {
    29  		return "", errors.Wrap(err, "error setting up metrics plugin listener")
    30  	}
    31  
    32  	mux := http.NewServeMux()
    33  	mux.Handle("/metrics", metrics.Handler())
    34  	go func() {
    35  		log.G(context.TODO()).Debugf("metrics API listening on %s", l.Addr())
    36  		srv := &http.Server{
    37  			Handler:           mux,
    38  			ReadHeaderTimeout: 5 * time.Minute, // "G112: Potential Slowloris Attack (gosec)"; not a real concern for our use, so setting a long timeout.
    39  		}
    40  		if err := srv.Serve(l); err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
    41  			log.G(context.TODO()).WithError(err).Error("error serving metrics API")
    42  		}
    43  	}()
    44  	daemon.metricsPluginListener = l
    45  	return path, nil
    46  }
    47  
    48  func registerMetricsPluginCallback(store *plugin.Store, sockPath string) {
    49  	store.RegisterRuntimeOpt(metricsPluginType, func(s *specs.Spec) {
    50  		f := plugin.WithSpecMounts([]specs.Mount{
    51  			{Type: "bind", Source: sockPath, Destination: "/run/docker/metrics.sock", Options: []string{"bind", "ro"}},
    52  		})
    53  		f(s)
    54  	})
    55  	store.Handle(metricsPluginType, func(name string, client *plugins.Client) {
    56  		// Use lookup since nothing in the system can really reference it, no need
    57  		// to protect against removal
    58  		p, err := store.Get(name, metricsPluginType, plugingetter.Lookup)
    59  		if err != nil {
    60  			return
    61  		}
    62  
    63  		adapter, err := makePluginAdapter(p)
    64  		if err != nil {
    65  			log.G(context.TODO()).WithError(err).WithField("plugin", p.Name()).Error("Error creating plugin adapter")
    66  		}
    67  		if err := adapter.StartMetrics(); err != nil {
    68  			log.G(context.TODO()).WithError(err).WithField("plugin", p.Name()).Error("Error starting metrics collector plugin")
    69  		}
    70  	})
    71  }