From 85398442d095524c5b2f315c294ea81f9d17853b Mon Sep 17 00:00:00 2001 From: Tom Clegg Date: Tue, 6 Feb 2018 17:52:18 -0500 Subject: [PATCH] 13025: Add request time metrics at /metrics and /metrics.json. Arvados-DCO-1.1-Signed-off-by: Tom Clegg --- sdk/go/httpserver/logger.go | 21 +++-- sdk/go/httpserver/responsewriter.go | 10 ++ services/keepstore/azure_blob_volume.go | 1 - services/keepstore/azure_blob_volume_test.go | 1 - services/keepstore/bufferpool.go | 2 - services/keepstore/bufferpool_test.go | 3 +- services/keepstore/config.go | 97 +++++++++++++++++--- services/keepstore/config_test.go | 3 +- services/keepstore/handlers.go | 50 +++++----- services/keepstore/keepstore.go | 7 +- services/keepstore/mounts_test.go | 63 +++++++++++-- services/keepstore/pull_worker.go | 2 - services/keepstore/s3_volume.go | 1 - services/keepstore/s3_volume_test.go | 1 - services/keepstore/trash_worker.go | 1 - services/keepstore/volume_unix.go | 2 - vendor/vendor.json | 90 ++++++++++++++++++ 17 files changed, 285 insertions(+), 70 deletions(-) diff --git a/sdk/go/httpserver/logger.go b/sdk/go/httpserver/logger.go index decb2ff28b..fab850fd91 100644 --- a/sdk/go/httpserver/logger.go +++ b/sdk/go/httpserver/logger.go @@ -10,7 +10,7 @@ import ( "time" "git.curoverse.com/arvados.git/sdk/go/stats" - log "github.com/Sirupsen/logrus" + "github.com/Sirupsen/logrus" ) type contextKey struct { @@ -19,13 +19,15 @@ type contextKey struct { var requestTimeContextKey = contextKey{"requestTime"} +var Logger logrus.FieldLogger = logrus.StandardLogger() + // LogRequests wraps an http.Handler, logging each request and // response via logrus. func LogRequests(h http.Handler) http.Handler { return http.HandlerFunc(func(wrapped http.ResponseWriter, req *http.Request) { w := &responseTimer{ResponseWriter: WrapResponseWriter(wrapped)} req = req.WithContext(context.WithValue(req.Context(), &requestTimeContextKey, time.Now())) - lgr := log.WithFields(log.Fields{ + lgr := Logger.WithFields(logrus.Fields{ "RequestID": req.Header.Get("X-Request-Id"), "remoteAddr": req.RemoteAddr, "reqForwardedFor": req.Header.Get("X-Forwarded-For"), @@ -39,20 +41,20 @@ func LogRequests(h http.Handler) http.Handler { }) } -func logRequest(w *responseTimer, req *http.Request, lgr *log.Entry) { +func logRequest(w *responseTimer, req *http.Request, lgr *logrus.Entry) { lgr.Info("request") } -func logResponse(w *responseTimer, req *http.Request, lgr *log.Entry) { +func logResponse(w *responseTimer, req *http.Request, lgr *logrus.Entry) { if tStart, ok := req.Context().Value(&requestTimeContextKey).(time.Time); ok { tDone := time.Now() - lgr = lgr.WithFields(log.Fields{ + lgr = lgr.WithFields(logrus.Fields{ "timeTotal": stats.Duration(tDone.Sub(tStart)), "timeToStatus": stats.Duration(w.writeTime.Sub(tStart)), "timeWriteBody": stats.Duration(tDone.Sub(w.writeTime)), }) } - lgr.WithFields(log.Fields{ + lgr.WithFields(logrus.Fields{ "respStatusCode": w.WroteStatus(), "respStatus": http.StatusText(w.WroteStatus()), "respBytes": w.WroteBodyBytes(), @@ -65,6 +67,13 @@ type responseTimer struct { writeTime time.Time } +func (rt *responseTimer) CloseNotify() <-chan bool { + if cn, ok := rt.ResponseWriter.(http.CloseNotifier); ok { + return cn.CloseNotify() + } + return nil +} + func (rt *responseTimer) WriteHeader(code int) { if !rt.wrote { rt.wrote = true diff --git a/sdk/go/httpserver/responsewriter.go b/sdk/go/httpserver/responsewriter.go index f17bc820a9..5fb810efa5 100644 --- a/sdk/go/httpserver/responsewriter.go +++ b/sdk/go/httpserver/responsewriter.go @@ -28,6 +28,13 @@ func WrapResponseWriter(orig http.ResponseWriter) ResponseWriter { return &responseWriter{ResponseWriter: orig} } +func (w *responseWriter) CloseNotify() <-chan bool { + if cn, ok := w.ResponseWriter.(http.CloseNotifier); ok { + return cn.CloseNotify() + } + return nil +} + func (w *responseWriter) WriteHeader(s int) { w.wroteStatus = s w.ResponseWriter.WriteHeader(s) @@ -41,6 +48,9 @@ func (w *responseWriter) Write(data []byte) (n int, err error) { } func (w *responseWriter) WroteStatus() int { + if w.wroteStatus == 0 { + return http.StatusOK + } return w.wroteStatus } diff --git a/services/keepstore/azure_blob_volume.go b/services/keepstore/azure_blob_volume.go index 62c856da34..2638bf08cd 100644 --- a/services/keepstore/azure_blob_volume.go +++ b/services/keepstore/azure_blob_volume.go @@ -21,7 +21,6 @@ import ( "time" "git.curoverse.com/arvados.git/sdk/go/arvados" - log "github.com/Sirupsen/logrus" "github.com/curoverse/azure-sdk-for-go/storage" ) diff --git a/services/keepstore/azure_blob_volume_test.go b/services/keepstore/azure_blob_volume_test.go index 06216edcb8..31b79da298 100644 --- a/services/keepstore/azure_blob_volume_test.go +++ b/services/keepstore/azure_blob_volume_test.go @@ -26,7 +26,6 @@ import ( "testing" "time" - log "github.com/Sirupsen/logrus" "github.com/curoverse/azure-sdk-for-go/storage" check "gopkg.in/check.v1" ) diff --git a/services/keepstore/bufferpool.go b/services/keepstore/bufferpool.go index 91417fd52c..d2e7c9ebd3 100644 --- a/services/keepstore/bufferpool.go +++ b/services/keepstore/bufferpool.go @@ -8,8 +8,6 @@ import ( "sync" "sync/atomic" "time" - - log "github.com/Sirupsen/logrus" ) type bufferPool struct { diff --git a/services/keepstore/bufferpool_test.go b/services/keepstore/bufferpool_test.go index a6479e4437..21b03edd49 100644 --- a/services/keepstore/bufferpool_test.go +++ b/services/keepstore/bufferpool_test.go @@ -5,8 +5,9 @@ package main import ( - . "gopkg.in/check.v1" "time" + + . "gopkg.in/check.v1" ) var _ = Suite(&BufferPoolSuite{}) diff --git a/services/keepstore/config.go b/services/keepstore/config.go index 0a3ece41ad..bbce883504 100644 --- a/services/keepstore/config.go +++ b/services/keepstore/config.go @@ -9,11 +9,17 @@ import ( "encoding/json" "fmt" "io/ioutil" + "net/http" + "strconv" "strings" "time" "git.curoverse.com/arvados.git/sdk/go/arvados" - log "github.com/Sirupsen/logrus" + "git.curoverse.com/arvados.git/sdk/go/stats" + "github.com/Sirupsen/logrus" + "github.com/golang/protobuf/jsonpb" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" ) type Config struct { @@ -42,9 +48,23 @@ type Config struct { debugLogf func(string, ...interface{}) ManagementToken string + + metrics } -var theConfig = DefaultConfig() +var ( + theConfig = DefaultConfig() + formatter = map[string]logrus.Formatter{ + "text": &logrus.TextFormatter{ + FullTimestamp: true, + TimestampFormat: rfc3339NanoFixed, + }, + "json": &logrus.JSONFormatter{ + TimestampFormat: rfc3339NanoFixed, + }, + } + log = logrus.StandardLogger() +) const rfc3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" @@ -66,25 +86,18 @@ func DefaultConfig() *Config { // fields, and before using the config. func (cfg *Config) Start() error { if cfg.Debug { - log.SetLevel(log.DebugLevel) + log.Level = logrus.DebugLevel cfg.debugLogf = log.Printf cfg.debugLogf("debugging enabled") } else { + log.Level = logrus.InfoLevel cfg.debugLogf = func(string, ...interface{}) {} } - switch strings.ToLower(cfg.LogFormat) { - case "text": - log.SetFormatter(&log.TextFormatter{ - FullTimestamp: true, - TimestampFormat: rfc3339NanoFixed, - }) - case "json": - log.SetFormatter(&log.JSONFormatter{ - TimestampFormat: rfc3339NanoFixed, - }) - default: + if f := formatter[strings.ToLower(cfg.LogFormat)]; f == nil { return fmt.Errorf(`unsupported log format %q (try "text" or "json")`, cfg.LogFormat) + } else { + log.Formatter = f } if cfg.MaxBuffers < 0 { @@ -142,6 +155,62 @@ func (cfg *Config) Start() error { return nil } +type metrics struct { + registry *prometheus.Registry + reqDuration *prometheus.SummaryVec + timeToStatus *prometheus.SummaryVec + exportProm http.Handler +} + +func (*metrics) Levels() []logrus.Level { + return logrus.AllLevels +} + +func (m *metrics) Fire(ent *logrus.Entry) error { + if tts, ok := ent.Data["timeToStatus"].(stats.Duration); !ok { + } else if method, ok := ent.Data["reqMethod"].(string); !ok { + } else if code, ok := ent.Data["respStatusCode"].(int); !ok { + } else { + m.timeToStatus.WithLabelValues(strconv.Itoa(code), strings.ToLower(method)).Observe(time.Duration(tts).Seconds()) + } + return nil +} + +func (m *metrics) setup() { + m.registry = prometheus.NewRegistry() + m.timeToStatus = prometheus.NewSummaryVec(prometheus.SummaryOpts{ + Name: "time_to_status_seconds", + Help: "Summary of request TTFB.", + }, []string{"code", "method"}) + m.reqDuration = prometheus.NewSummaryVec(prometheus.SummaryOpts{ + Name: "request_duration_seconds", + Help: "Summary of request duration.", + }, []string{"code", "method"}) + m.registry.MustRegister(m.timeToStatus) + m.registry.MustRegister(m.reqDuration) + m.exportProm = promhttp.HandlerFor(m.registry, promhttp.HandlerOpts{ + ErrorLog: log, + }) + log.AddHook(m) +} + +func (m *metrics) exportJSON(w http.ResponseWriter, req *http.Request) { + jm := jsonpb.Marshaler{Indent: " "} + mfs, _ := m.registry.Gather() + w.Write([]byte{'['}) + for i, mf := range mfs { + if i > 0 { + w.Write([]byte{','}) + } + jm.Marshal(w, mf) + } + w.Write([]byte{']'}) +} + +func (m *metrics) Instrument(next http.Handler) http.Handler { + return promhttp.InstrumentHandlerDuration(m.reqDuration, next) +} + // VolumeTypes is built up by init() funcs in the source files that // define the volume types. var VolumeTypes = []func() VolumeWithExamples{} diff --git a/services/keepstore/config_test.go b/services/keepstore/config_test.go index 5e55042c28..d6471e3d45 100644 --- a/services/keepstore/config_test.go +++ b/services/keepstore/config_test.go @@ -5,9 +5,10 @@ package main import ( - log "github.com/Sirupsen/logrus" + "github.com/Sirupsen/logrus" ) func init() { + log.Level = logrus.DebugLevel theConfig.debugLogf = log.Printf } diff --git a/services/keepstore/handlers.go b/services/keepstore/handlers.go index daf4fc69dd..258604ce59 100644 --- a/services/keepstore/handlers.go +++ b/services/keepstore/handlers.go @@ -31,7 +31,6 @@ import ( "git.curoverse.com/arvados.git/sdk/go/health" "git.curoverse.com/arvados.git/sdk/go/httpserver" - log "github.com/Sirupsen/logrus" ) type router struct { @@ -41,54 +40,63 @@ type router struct { // MakeRESTRouter returns a new router that forwards all Keep requests // to the appropriate handlers. -func MakeRESTRouter() *router { - rest := mux.NewRouter() - rtr := &router{Router: rest} +func MakeRESTRouter() http.Handler { + rtr := &router{Router: mux.NewRouter()} - rest.HandleFunc( + rtr.HandleFunc( `/{hash:[0-9a-f]{32}}`, GetBlockHandler).Methods("GET", "HEAD") - rest.HandleFunc( + rtr.HandleFunc( `/{hash:[0-9a-f]{32}}+{hints}`, GetBlockHandler).Methods("GET", "HEAD") - rest.HandleFunc(`/{hash:[0-9a-f]{32}}`, PutBlockHandler).Methods("PUT") - rest.HandleFunc(`/{hash:[0-9a-f]{32}}`, DeleteHandler).Methods("DELETE") + rtr.HandleFunc(`/{hash:[0-9a-f]{32}}`, PutBlockHandler).Methods("PUT") + rtr.HandleFunc(`/{hash:[0-9a-f]{32}}`, DeleteHandler).Methods("DELETE") // List all blocks stored here. Privileged client only. - rest.HandleFunc(`/index`, rtr.IndexHandler).Methods("GET", "HEAD") + rtr.HandleFunc(`/index`, rtr.IndexHandler).Methods("GET", "HEAD") // List blocks stored here whose hash has the given prefix. // Privileged client only. - rest.HandleFunc(`/index/{prefix:[0-9a-f]{0,32}}`, rtr.IndexHandler).Methods("GET", "HEAD") + rtr.HandleFunc(`/index/{prefix:[0-9a-f]{0,32}}`, rtr.IndexHandler).Methods("GET", "HEAD") // Internals/debugging info (runtime.MemStats) - rest.HandleFunc(`/debug.json`, rtr.DebugHandler).Methods("GET", "HEAD") + rtr.HandleFunc(`/debug.json`, rtr.DebugHandler).Methods("GET", "HEAD") // List volumes: path, device number, bytes used/avail. - rest.HandleFunc(`/status.json`, rtr.StatusHandler).Methods("GET", "HEAD") + rtr.HandleFunc(`/status.json`, rtr.StatusHandler).Methods("GET", "HEAD") // List mounts: UUID, readonly, tier, device ID, ... - rest.HandleFunc(`/mounts`, rtr.MountsHandler).Methods("GET") - rest.HandleFunc(`/mounts/{uuid}/blocks`, rtr.IndexHandler).Methods("GET") - rest.HandleFunc(`/mounts/{uuid}/blocks/`, rtr.IndexHandler).Methods("GET") + rtr.HandleFunc(`/mounts`, rtr.MountsHandler).Methods("GET") + rtr.HandleFunc(`/mounts/{uuid}/blocks`, rtr.IndexHandler).Methods("GET") + rtr.HandleFunc(`/mounts/{uuid}/blocks/`, rtr.IndexHandler).Methods("GET") // Replace the current pull queue. - rest.HandleFunc(`/pull`, PullHandler).Methods("PUT") + rtr.HandleFunc(`/pull`, PullHandler).Methods("PUT") // Replace the current trash queue. - rest.HandleFunc(`/trash`, TrashHandler).Methods("PUT") + rtr.HandleFunc(`/trash`, TrashHandler).Methods("PUT") // Untrash moves blocks from trash back into store - rest.HandleFunc(`/untrash/{hash:[0-9a-f]{32}}`, UntrashHandler).Methods("PUT") + rtr.HandleFunc(`/untrash/{hash:[0-9a-f]{32}}`, UntrashHandler).Methods("PUT") - rest.Handle("/_health/{check}", &health.Handler{ + rtr.Handle("/_health/{check}", &health.Handler{ Token: theConfig.ManagementToken, Prefix: "/_health/", }).Methods("GET") // Any request which does not match any of these routes gets // 400 Bad Request. - rest.NotFoundHandler = http.HandlerFunc(BadRequestHandler) + rtr.NotFoundHandler = http.HandlerFunc(BadRequestHandler) - return rtr + theConfig.metrics.setup() + + rtr.limiter = httpserver.NewRequestLimiter(theConfig.MaxRequests, rtr) + + mux := http.NewServeMux() + mux.Handle("/", theConfig.metrics.Instrument( + httpserver.AddRequestIDs(httpserver.LogRequests(rtr.limiter)))) + mux.HandleFunc("/metrics.json", theConfig.metrics.exportJSON) + mux.Handle("/metrics", theConfig.metrics.exportProm) + + return mux } // BadRequestHandler is a HandleFunc to address bad requests. diff --git a/services/keepstore/keepstore.go b/services/keepstore/keepstore.go index b8a0ffb1cb..03eef7e76b 100644 --- a/services/keepstore/keepstore.go +++ b/services/keepstore/keepstore.go @@ -16,9 +16,7 @@ import ( "git.curoverse.com/arvados.git/sdk/go/arvadosclient" "git.curoverse.com/arvados.git/sdk/go/config" - "git.curoverse.com/arvados.git/sdk/go/httpserver" "git.curoverse.com/arvados.git/sdk/go/keepclient" - log "github.com/Sirupsen/logrus" "github.com/coreos/go-systemd/daemon" ) @@ -160,9 +158,6 @@ func main() { // Middleware/handler stack router := MakeRESTRouter() - limiter := httpserver.NewRequestLimiter(theConfig.MaxRequests, router) - router.limiter = limiter - http.Handle("/", httpserver.AddRequestIDs(httpserver.LogRequests(limiter))) // Set up a TCP listener. listener, err := net.Listen("tcp", theConfig.Listen) @@ -204,7 +199,7 @@ func main() { log.Printf("Error notifying init daemon: %v", err) } log.Println("listening at", listener.Addr()) - srv := &http.Server{} + srv := &http.Server{Handler: router} srv.Serve(listener) } diff --git a/services/keepstore/mounts_test.go b/services/keepstore/mounts_test.go index b4544d0f92..883aa712e3 100644 --- a/services/keepstore/mounts_test.go +++ b/services/keepstore/mounts_test.go @@ -5,6 +5,7 @@ package main import ( + "bytes" "context" "encoding/json" "net/http" @@ -24,8 +25,10 @@ type MountsSuite struct { func (s *MountsSuite) SetUpTest(c *check.C) { s.vm = MakeTestVolumeManager(2) KeepVM = s.vm - s.rtr = MakeRESTRouter() + theConfig = DefaultConfig() theConfig.systemAuthToken = arvadostest.DataManagerToken + theConfig.Start() + s.rtr = MakeRESTRouter() } func (s *MountsSuite) TearDownTest(c *check.C) { @@ -40,7 +43,7 @@ func (s *MountsSuite) TestMounts(c *check.C) { vols[0].Put(context.Background(), TestHash, TestBlock) vols[1].Put(context.Background(), TestHash2, TestBlock2) - resp := s.call("GET", "/mounts", "") + resp := s.call("GET", "/mounts", "", nil) c.Check(resp.Code, check.Equals, http.StatusOK) var mntList []struct { UUID string @@ -64,7 +67,7 @@ func (s *MountsSuite) TestMounts(c *check.C) { // Bad auth for _, tok := range []string{"", "xyzzy"} { - resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks", tok) + resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks", tok, nil) c.Check(resp.Code, check.Equals, http.StatusUnauthorized) c.Check(resp.Body.String(), check.Equals, "Unauthorized\n") } @@ -72,34 +75,74 @@ func (s *MountsSuite) TestMounts(c *check.C) { tok := arvadostest.DataManagerToken // Nonexistent mount UUID - resp = s.call("GET", "/mounts/X/blocks", tok) + resp = s.call("GET", "/mounts/X/blocks", tok, nil) c.Check(resp.Code, check.Equals, http.StatusNotFound) c.Check(resp.Body.String(), check.Equals, "mount not found\n") // Complete index of first mount - resp = s.call("GET", "/mounts/"+mntList[0].UUID+"/blocks", tok) + resp = s.call("GET", "/mounts/"+mntList[0].UUID+"/blocks", tok, nil) c.Check(resp.Code, check.Equals, http.StatusOK) c.Check(resp.Body.String(), check.Matches, TestHash+`\+[0-9]+ [0-9]+\n\n`) // Partial index of first mount (one block matches prefix) - resp = s.call("GET", "/mounts/"+mntList[0].UUID+"/blocks?prefix="+TestHash[:2], tok) + resp = s.call("GET", "/mounts/"+mntList[0].UUID+"/blocks?prefix="+TestHash[:2], tok, nil) c.Check(resp.Code, check.Equals, http.StatusOK) c.Check(resp.Body.String(), check.Matches, TestHash+`\+[0-9]+ [0-9]+\n\n`) // Complete index of second mount (note trailing slash) - resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks/", tok) + resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks/", tok, nil) c.Check(resp.Code, check.Equals, http.StatusOK) c.Check(resp.Body.String(), check.Matches, TestHash2+`\+[0-9]+ [0-9]+\n\n`) // Partial index of second mount (no blocks match prefix) - resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks/?prefix="+TestHash[:2], tok) + resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks/?prefix="+TestHash[:2], tok, nil) c.Check(resp.Code, check.Equals, http.StatusOK) c.Check(resp.Body.String(), check.Equals, "\n") } -func (s *MountsSuite) call(method, path, tok string) *httptest.ResponseRecorder { +func (s *MountsSuite) TestMetrics(c *check.C) { + s.call("PUT", "/"+TestHash, "", TestBlock) + s.call("PUT", "/"+TestHash2, "", TestBlock2) + resp := s.call("GET", "/metrics.json", "", nil) + c.Check(resp.Code, check.Equals, http.StatusOK) + var j []struct { + Name string + Help string + Type string + Metric []struct { + Label []struct { + Name string + Value string + } + Summary struct { + SampleCount string `json:"sample_count"` + SampleSum float64 `json:"sample_sum"` + Quantile []struct { + Quantile float64 + Value float64 + } + } + } + } + json.NewDecoder(resp.Body).Decode(&j) + found := make(map[string]bool) + for _, g := range j { + for _, m := range g.Metric { + if len(m.Label) == 2 && m.Label[0].Name == "code" && m.Label[0].Value == "200" && m.Label[1].Name == "method" && m.Label[1].Value == "put" { + c.Check(m.Summary.SampleCount, check.Equals, "2") + c.Check(len(m.Summary.Quantile), check.Not(check.Equals), 0) + c.Check(m.Summary.Quantile[0].Value, check.Not(check.Equals), float64(0)) + found[g.Name] = true + } + } + } + c.Check(found["request_duration_seconds"], check.Equals, true) + c.Check(found["time_to_status_seconds"], check.Equals, true) +} + +func (s *MountsSuite) call(method, path, tok string, body []byte) *httptest.ResponseRecorder { resp := httptest.NewRecorder() - req, _ := http.NewRequest(method, path, nil) + req, _ := http.NewRequest(method, path, bytes.NewReader(body)) if tok != "" { req.Header.Set("Authorization", "OAuth2 "+tok) } diff --git a/services/keepstore/pull_worker.go b/services/keepstore/pull_worker.go index f821fb5483..42b5d5889d 100644 --- a/services/keepstore/pull_worker.go +++ b/services/keepstore/pull_worker.go @@ -13,8 +13,6 @@ import ( "time" "git.curoverse.com/arvados.git/sdk/go/keepclient" - - log "github.com/Sirupsen/logrus" ) // RunPullWorker receives PullRequests from pullq, invokes diff --git a/services/keepstore/s3_volume.go b/services/keepstore/s3_volume.go index 61e69f9096..90e8a1b4f6 100644 --- a/services/keepstore/s3_volume.go +++ b/services/keepstore/s3_volume.go @@ -23,7 +23,6 @@ import ( "git.curoverse.com/arvados.git/sdk/go/arvados" "github.com/AdRoll/goamz/aws" "github.com/AdRoll/goamz/s3" - log "github.com/Sirupsen/logrus" ) const ( diff --git a/services/keepstore/s3_volume_test.go b/services/keepstore/s3_volume_test.go index 3d4a195623..acc1b11df3 100644 --- a/services/keepstore/s3_volume_test.go +++ b/services/keepstore/s3_volume_test.go @@ -19,7 +19,6 @@ import ( "git.curoverse.com/arvados.git/sdk/go/arvados" "github.com/AdRoll/goamz/s3" "github.com/AdRoll/goamz/s3/s3test" - log "github.com/Sirupsen/logrus" check "gopkg.in/check.v1" ) diff --git a/services/keepstore/trash_worker.go b/services/keepstore/trash_worker.go index 51fbb94791..cbb831ebc0 100644 --- a/services/keepstore/trash_worker.go +++ b/services/keepstore/trash_worker.go @@ -9,7 +9,6 @@ import ( "time" "git.curoverse.com/arvados.git/sdk/go/arvados" - log "github.com/Sirupsen/logrus" ) // RunTrashWorker is used by Keepstore to initiate trash worker channel goroutine. diff --git a/services/keepstore/volume_unix.go b/services/keepstore/volume_unix.go index da9b110c56..ea9aa489c5 100644 --- a/services/keepstore/volume_unix.go +++ b/services/keepstore/volume_unix.go @@ -20,8 +20,6 @@ import ( "sync" "syscall" "time" - - log "github.com/Sirupsen/logrus" ) type unixVolumeAdder struct { diff --git a/vendor/vendor.json b/vendor/vendor.json index aeac93e475..483ab70b6d 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -35,6 +35,12 @@ "revision": "d682213848ed68c0a260ca37d6dd5ace8423f5ba", "revisionTime": "2017-12-05T20:32:29Z" }, + { + "checksumSHA1": "spyv5/YFBjYyZLZa1U2LBfDR8PM=", + "path": "github.com/beorn7/perks/quantile", + "revision": "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9", + "revisionTime": "2016-08-04T10:47:26Z" + }, { "checksumSHA1": "+Zz+leZHHC9C0rx8DoRuffSRPso=", "path": "github.com/coreos/go-systemd/daemon", @@ -197,6 +203,24 @@ "revision": "160de10b2537169b5ae3e7e221d28269ef40d311", "revisionTime": "2018-01-04T10:21:28Z" }, + { + "checksumSHA1": "iVfdaLxIDjfk2KLP8dCMIbsxZZM=", + "path": "github.com/golang/protobuf/jsonpb", + "revision": "1e59b77b52bf8e4b449a57e6f79f21226d571845", + "revisionTime": "2017-11-13T18:07:20Z" + }, + { + "checksumSHA1": "yqF125xVSkmfLpIVGrLlfE05IUk=", + "path": "github.com/golang/protobuf/proto", + "revision": "1e59b77b52bf8e4b449a57e6f79f21226d571845", + "revisionTime": "2017-11-13T18:07:20Z" + }, + { + "checksumSHA1": "Ylq6kq3KWBy6mu68oyEwenhNMdg=", + "path": "github.com/golang/protobuf/ptypes/struct", + "revision": "1e59b77b52bf8e4b449a57e6f79f21226d571845", + "revisionTime": "2017-11-13T18:07:20Z" + }, { "checksumSHA1": "iIUYZyoanCQQTUaWsu8b+iOSPt4=", "origin": "github.com/docker/docker/vendor/github.com/gorilla/context", @@ -246,6 +270,12 @@ "revision": "83612a56d3dd153a94a629cd64925371c9adad78", "revisionTime": "2017-11-26T05:04:59Z" }, + { + "checksumSHA1": "bKMZjd2wPw13VwoE7mBeSv5djFA=", + "path": "github.com/matttproud/golang_protobuf_extensions/pbutil", + "revision": "c12348ce28de40eed0136aa2b644d0ee0650e56c", + "revisionTime": "2016-04-24T11:30:07Z" + }, { "checksumSHA1": "V/quM7+em2ByJbWBLOsEwnY3j/Q=", "path": "github.com/mitchellh/go-homedir", @@ -282,6 +312,66 @@ "revision": "e881fd58d78e04cf6d0de1217f8707c8cc2249bc", "revisionTime": "2017-12-16T07:03:16Z" }, + { + "checksumSHA1": "Ajt29IHVbX99PUvzn8Gc/lMCXBY=", + "path": "github.com/prometheus/client_golang/prometheus", + "revision": "9bb6ab929dcbe1c8393cd9ef70387cb69811bd1c", + "revisionTime": "2018-02-03T14:28:15Z" + }, + { + "checksumSHA1": "c3Ui7nnLiJ4CAGWZ8dGuEgqHd8s=", + "path": "github.com/prometheus/client_golang/prometheus/promhttp", + "revision": "9bb6ab929dcbe1c8393cd9ef70387cb69811bd1c", + "revisionTime": "2018-02-03T14:28:15Z" + }, + { + "checksumSHA1": "DvwvOlPNAgRntBzt3b3OSRMS2N4=", + "path": "github.com/prometheus/client_model/go", + "revision": "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c", + "revisionTime": "2017-11-17T10:05:41Z" + }, + { + "checksumSHA1": "xfnn0THnqNwjwimeTClsxahYrIo=", + "path": "github.com/prometheus/common/expfmt", + "revision": "89604d197083d4781071d3c65855d24ecfb0a563", + "revisionTime": "2018-01-10T21:49:58Z" + }, + { + "checksumSHA1": "GWlM3d2vPYyNATtTFgftS10/A9w=", + "path": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", + "revision": "89604d197083d4781071d3c65855d24ecfb0a563", + "revisionTime": "2018-01-10T21:49:58Z" + }, + { + "checksumSHA1": "YU+/K48IMawQnToO4ETE6a+hhj4=", + "path": "github.com/prometheus/common/model", + "revision": "89604d197083d4781071d3c65855d24ecfb0a563", + "revisionTime": "2018-01-10T21:49:58Z" + }, + { + "checksumSHA1": "lolK0h7LSVERIX8zLyVQ/+7wEyA=", + "path": "github.com/prometheus/procfs", + "revision": "cb4147076ac75738c9a7d279075a253c0cc5acbd", + "revisionTime": "2018-01-25T13:30:57Z" + }, + { + "checksumSHA1": "lv9rIcjbVEGo8AT1UCUZXhXrfQc=", + "path": "github.com/prometheus/procfs/internal/util", + "revision": "cb4147076ac75738c9a7d279075a253c0cc5acbd", + "revisionTime": "2018-01-25T13:30:57Z" + }, + { + "checksumSHA1": "BXJH5h2ri8SU5qC6kkDvTIGCky4=", + "path": "github.com/prometheus/procfs/nfs", + "revision": "cb4147076ac75738c9a7d279075a253c0cc5acbd", + "revisionTime": "2018-01-25T13:30:57Z" + }, + { + "checksumSHA1": "yItvTQLUVqm/ArLEbvEhqG0T5a0=", + "path": "github.com/prometheus/procfs/xfs", + "revision": "cb4147076ac75738c9a7d279075a253c0cc5acbd", + "revisionTime": "2018-01-25T13:30:57Z" + }, { "checksumSHA1": "UwtyqB7CaUWPlw0DVJQvw0IFQZs=", "path": "github.com/sergi/go-diff/diffmatchpatch", -- 2.30.2