metrics_unix.go 2.3 KB

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