swarm: initial instrumentation (#15969)
* swarm: initial instrumentation with go-metrics * swarm: initialise metrics collection and add ResettingTimer to HTTP requests * swarm: update metrics flags names. remove redundant Timer. * swarm: rename method for periodically updating gauges * swarm: finalise metrics after feedback * swarm/network: always init kad metrics containers * swarm/network: off-by-one index in metrics containers * swarm, metrics: resolved conflicts
This commit is contained in:
committed by
Balint Gabor
parent
b677a07d36
commit
dcca613a0b
@ -32,11 +32,31 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/swarm/storage"
|
||||
)
|
||||
|
||||
var hashMatcher = regexp.MustCompile("^[0-9A-Fa-f]{64}")
|
||||
|
||||
//setup metrics
|
||||
var (
|
||||
apiResolveCount = metrics.NewRegisteredCounter("api.resolve.count", nil)
|
||||
apiResolveFail = metrics.NewRegisteredCounter("api.resolve.fail", nil)
|
||||
apiPutCount = metrics.NewRegisteredCounter("api.put.count", nil)
|
||||
apiPutFail = metrics.NewRegisteredCounter("api.put.fail", nil)
|
||||
apiGetCount = metrics.NewRegisteredCounter("api.get.count", nil)
|
||||
apiGetNotFound = metrics.NewRegisteredCounter("api.get.notfound", nil)
|
||||
apiGetHttp300 = metrics.NewRegisteredCounter("api.get.http.300", nil)
|
||||
apiModifyCount = metrics.NewRegisteredCounter("api.modify.count", nil)
|
||||
apiModifyFail = metrics.NewRegisteredCounter("api.modify.fail", nil)
|
||||
apiAddFileCount = metrics.NewRegisteredCounter("api.addfile.count", nil)
|
||||
apiAddFileFail = metrics.NewRegisteredCounter("api.addfile.fail", nil)
|
||||
apiRmFileCount = metrics.NewRegisteredCounter("api.removefile.count", nil)
|
||||
apiRmFileFail = metrics.NewRegisteredCounter("api.removefile.fail", nil)
|
||||
apiAppendFileCount = metrics.NewRegisteredCounter("api.appendfile.count", nil)
|
||||
apiAppendFileFail = metrics.NewRegisteredCounter("api.appendfile.fail", nil)
|
||||
)
|
||||
|
||||
type Resolver interface {
|
||||
Resolve(string) (common.Hash, error)
|
||||
}
|
||||
@ -155,6 +175,7 @@ type ErrResolve error
|
||||
|
||||
// DNS Resolver
|
||||
func (self *Api) Resolve(uri *URI) (storage.Key, error) {
|
||||
apiResolveCount.Inc(1)
|
||||
log.Trace(fmt.Sprintf("Resolving : %v", uri.Addr))
|
||||
|
||||
// if the URI is immutable, check if the address is a hash
|
||||
@ -169,6 +190,7 @@ func (self *Api) Resolve(uri *URI) (storage.Key, error) {
|
||||
// if DNS is not configured, check if the address is a hash
|
||||
if self.dns == nil {
|
||||
if !isHash {
|
||||
apiResolveFail.Inc(1)
|
||||
return nil, fmt.Errorf("no DNS to resolve name: %q", uri.Addr)
|
||||
}
|
||||
return common.Hex2Bytes(uri.Addr), nil
|
||||
@ -179,6 +201,7 @@ func (self *Api) Resolve(uri *URI) (storage.Key, error) {
|
||||
if err == nil {
|
||||
return resolved[:], nil
|
||||
} else if !isHash {
|
||||
apiResolveFail.Inc(1)
|
||||
return nil, err
|
||||
}
|
||||
return common.Hex2Bytes(uri.Addr), nil
|
||||
@ -186,16 +209,19 @@ func (self *Api) Resolve(uri *URI) (storage.Key, error) {
|
||||
|
||||
// Put provides singleton manifest creation on top of dpa store
|
||||
func (self *Api) Put(content, contentType string) (storage.Key, error) {
|
||||
apiPutCount.Inc(1)
|
||||
r := strings.NewReader(content)
|
||||
wg := &sync.WaitGroup{}
|
||||
key, err := self.dpa.Store(r, int64(len(content)), wg, nil)
|
||||
if err != nil {
|
||||
apiPutFail.Inc(1)
|
||||
return nil, err
|
||||
}
|
||||
manifest := fmt.Sprintf(`{"entries":[{"hash":"%v","contentType":"%s"}]}`, key, contentType)
|
||||
r = strings.NewReader(manifest)
|
||||
key, err = self.dpa.Store(r, int64(len(manifest)), wg, nil)
|
||||
if err != nil {
|
||||
apiPutFail.Inc(1)
|
||||
return nil, err
|
||||
}
|
||||
wg.Wait()
|
||||
@ -206,8 +232,10 @@ func (self *Api) Put(content, contentType string) (storage.Key, error) {
|
||||
// to resolve basePath to content using dpa retrieve
|
||||
// it returns a section reader, mimeType, status and an error
|
||||
func (self *Api) Get(key storage.Key, path string) (reader storage.LazySectionReader, mimeType string, status int, err error) {
|
||||
apiGetCount.Inc(1)
|
||||
trie, err := loadManifest(self.dpa, key, nil)
|
||||
if err != nil {
|
||||
apiGetNotFound.Inc(1)
|
||||
status = http.StatusNotFound
|
||||
log.Warn(fmt.Sprintf("loadManifestTrie error: %v", err))
|
||||
return
|
||||
@ -221,6 +249,7 @@ func (self *Api) Get(key storage.Key, path string) (reader storage.LazySectionRe
|
||||
key = common.Hex2Bytes(entry.Hash)
|
||||
status = entry.Status
|
||||
if status == http.StatusMultipleChoices {
|
||||
apiGetHttp300.Inc(1)
|
||||
return
|
||||
} else {
|
||||
mimeType = entry.ContentType
|
||||
@ -229,6 +258,7 @@ func (self *Api) Get(key storage.Key, path string) (reader storage.LazySectionRe
|
||||
}
|
||||
} else {
|
||||
status = http.StatusNotFound
|
||||
apiGetNotFound.Inc(1)
|
||||
err = fmt.Errorf("manifest entry for '%s' not found", path)
|
||||
log.Warn(fmt.Sprintf("%v", err))
|
||||
}
|
||||
@ -236,9 +266,11 @@ func (self *Api) Get(key storage.Key, path string) (reader storage.LazySectionRe
|
||||
}
|
||||
|
||||
func (self *Api) Modify(key storage.Key, path, contentHash, contentType string) (storage.Key, error) {
|
||||
apiModifyCount.Inc(1)
|
||||
quitC := make(chan bool)
|
||||
trie, err := loadManifest(self.dpa, key, quitC)
|
||||
if err != nil {
|
||||
apiModifyFail.Inc(1)
|
||||
return nil, err
|
||||
}
|
||||
if contentHash != "" {
|
||||
@ -253,19 +285,23 @@ func (self *Api) Modify(key storage.Key, path, contentHash, contentType string)
|
||||
}
|
||||
|
||||
if err := trie.recalcAndStore(); err != nil {
|
||||
apiModifyFail.Inc(1)
|
||||
return nil, err
|
||||
}
|
||||
return trie.hash, nil
|
||||
}
|
||||
|
||||
func (self *Api) AddFile(mhash, path, fname string, content []byte, nameresolver bool) (storage.Key, string, error) {
|
||||
apiAddFileCount.Inc(1)
|
||||
|
||||
uri, err := Parse("bzz:/" + mhash)
|
||||
if err != nil {
|
||||
apiAddFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
}
|
||||
mkey, err := self.Resolve(uri)
|
||||
if err != nil {
|
||||
apiAddFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
@ -284,16 +320,19 @@ func (self *Api) AddFile(mhash, path, fname string, content []byte, nameresolver
|
||||
|
||||
mw, err := self.NewManifestWriter(mkey, nil)
|
||||
if err != nil {
|
||||
apiAddFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
fkey, err := mw.AddEntry(bytes.NewReader(content), entry)
|
||||
if err != nil {
|
||||
apiAddFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
newMkey, err := mw.Store()
|
||||
if err != nil {
|
||||
apiAddFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
|
||||
}
|
||||
@ -303,13 +342,16 @@ func (self *Api) AddFile(mhash, path, fname string, content []byte, nameresolver
|
||||
}
|
||||
|
||||
func (self *Api) RemoveFile(mhash, path, fname string, nameresolver bool) (string, error) {
|
||||
apiRmFileCount.Inc(1)
|
||||
|
||||
uri, err := Parse("bzz:/" + mhash)
|
||||
if err != nil {
|
||||
apiRmFileFail.Inc(1)
|
||||
return "", err
|
||||
}
|
||||
mkey, err := self.Resolve(uri)
|
||||
if err != nil {
|
||||
apiRmFileFail.Inc(1)
|
||||
return "", err
|
||||
}
|
||||
|
||||
@ -320,16 +362,19 @@ func (self *Api) RemoveFile(mhash, path, fname string, nameresolver bool) (strin
|
||||
|
||||
mw, err := self.NewManifestWriter(mkey, nil)
|
||||
if err != nil {
|
||||
apiRmFileFail.Inc(1)
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = mw.RemoveEntry(filepath.Join(path, fname))
|
||||
if err != nil {
|
||||
apiRmFileFail.Inc(1)
|
||||
return "", err
|
||||
}
|
||||
|
||||
newMkey, err := mw.Store()
|
||||
if err != nil {
|
||||
apiRmFileFail.Inc(1)
|
||||
return "", err
|
||||
|
||||
}
|
||||
@ -338,6 +383,7 @@ func (self *Api) RemoveFile(mhash, path, fname string, nameresolver bool) (strin
|
||||
}
|
||||
|
||||
func (self *Api) AppendFile(mhash, path, fname string, existingSize int64, content []byte, oldKey storage.Key, offset int64, addSize int64, nameresolver bool) (storage.Key, string, error) {
|
||||
apiAppendFileCount.Inc(1)
|
||||
|
||||
buffSize := offset + addSize
|
||||
if buffSize < existingSize {
|
||||
@ -366,10 +412,12 @@ func (self *Api) AppendFile(mhash, path, fname string, existingSize int64, conte
|
||||
|
||||
uri, err := Parse("bzz:/" + mhash)
|
||||
if err != nil {
|
||||
apiAppendFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
}
|
||||
mkey, err := self.Resolve(uri)
|
||||
if err != nil {
|
||||
apiAppendFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
@ -380,11 +428,13 @@ func (self *Api) AppendFile(mhash, path, fname string, existingSize int64, conte
|
||||
|
||||
mw, err := self.NewManifestWriter(mkey, nil)
|
||||
if err != nil {
|
||||
apiAppendFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
err = mw.RemoveEntry(filepath.Join(path, fname))
|
||||
if err != nil {
|
||||
apiAppendFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
@ -398,11 +448,13 @@ func (self *Api) AppendFile(mhash, path, fname string, existingSize int64, conte
|
||||
|
||||
fkey, err := mw.AddEntry(io.Reader(combinedReader), entry)
|
||||
if err != nil {
|
||||
apiAppendFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
newMkey, err := mw.Store()
|
||||
if err != nil {
|
||||
apiAppendFileFail.Inc(1)
|
||||
return nil, "", err
|
||||
|
||||
}
|
||||
@ -412,6 +464,7 @@ func (self *Api) AppendFile(mhash, path, fname string, existingSize int64, conte
|
||||
}
|
||||
|
||||
func (self *Api) BuildDirectoryTree(mhash string, nameresolver bool) (key storage.Key, manifestEntryMap map[string]*manifestTrieEntry, err error) {
|
||||
|
||||
uri, err := Parse("bzz:/" + mhash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -29,12 +29,19 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/swarm/api"
|
||||
)
|
||||
|
||||
//templateMap holds a mapping of an HTTP error code to a template
|
||||
var templateMap map[int]*template.Template
|
||||
|
||||
//metrics variables
|
||||
var (
|
||||
htmlCounter = metrics.NewRegisteredCounter("api.http.errorpage.html.count", nil)
|
||||
jsonCounter = metrics.NewRegisteredCounter("api.http.errorpage.json.count", nil)
|
||||
)
|
||||
|
||||
//parameters needed for formatting the correct HTML page
|
||||
type ErrorParams struct {
|
||||
Msg string
|
||||
@ -132,6 +139,7 @@ func respond(w http.ResponseWriter, r *http.Request, params *ErrorParams) {
|
||||
|
||||
//return a HTML page
|
||||
func respondHtml(w http.ResponseWriter, params *ErrorParams) {
|
||||
htmlCounter.Inc(1)
|
||||
err := params.template.Execute(w, params)
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
@ -140,6 +148,7 @@ func respondHtml(w http.ResponseWriter, params *ErrorParams) {
|
||||
|
||||
//return JSON
|
||||
func respondJson(w http.ResponseWriter, params *ErrorParams) {
|
||||
jsonCounter.Inc(1)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(params)
|
||||
}
|
||||
|
@ -37,11 +37,35 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/swarm/api"
|
||||
"github.com/ethereum/go-ethereum/swarm/storage"
|
||||
"github.com/rs/cors"
|
||||
)
|
||||
|
||||
//setup metrics
|
||||
var (
|
||||
postRawCount = metrics.NewRegisteredCounter("api.http.post.raw.count", nil)
|
||||
postRawFail = metrics.NewRegisteredCounter("api.http.post.raw.fail", nil)
|
||||
postFilesCount = metrics.NewRegisteredCounter("api.http.post.files.count", nil)
|
||||
postFilesFail = metrics.NewRegisteredCounter("api.http.post.files.fail", nil)
|
||||
deleteCount = metrics.NewRegisteredCounter("api.http.delete.count", nil)
|
||||
deleteFail = metrics.NewRegisteredCounter("api.http.delete.fail", nil)
|
||||
getCount = metrics.NewRegisteredCounter("api.http.get.count", nil)
|
||||
getFail = metrics.NewRegisteredCounter("api.http.get.fail", nil)
|
||||
getFileCount = metrics.NewRegisteredCounter("api.http.get.file.count", nil)
|
||||
getFileNotFound = metrics.NewRegisteredCounter("api.http.get.file.notfound", nil)
|
||||
getFileFail = metrics.NewRegisteredCounter("api.http.get.file.fail", nil)
|
||||
getFilesCount = metrics.NewRegisteredCounter("api.http.get.files.count", nil)
|
||||
getFilesFail = metrics.NewRegisteredCounter("api.http.get.files.fail", nil)
|
||||
getListCount = metrics.NewRegisteredCounter("api.http.get.list.count", nil)
|
||||
getListFail = metrics.NewRegisteredCounter("api.http.get.list.fail", nil)
|
||||
requestCount = metrics.NewRegisteredCounter("http.request.count", nil)
|
||||
htmlRequestCount = metrics.NewRegisteredCounter("http.request.html.count", nil)
|
||||
jsonRequestCount = metrics.NewRegisteredCounter("http.request.json.count", nil)
|
||||
requestTimer = metrics.NewRegisteredResettingTimer("http.request.time", nil)
|
||||
)
|
||||
|
||||
// ServerConfig is the basic configuration needed for the HTTP server and also
|
||||
// includes CORS settings.
|
||||
type ServerConfig struct {
|
||||
@ -89,18 +113,22 @@ type Request struct {
|
||||
// HandlePostRaw handles a POST request to a raw bzz-raw:/ URI, stores the request
|
||||
// body in swarm and returns the resulting storage key as a text/plain response
|
||||
func (s *Server) HandlePostRaw(w http.ResponseWriter, r *Request) {
|
||||
postRawCount.Inc(1)
|
||||
if r.uri.Path != "" {
|
||||
postRawFail.Inc(1)
|
||||
s.BadRequest(w, r, "raw POST request cannot contain a path")
|
||||
return
|
||||
}
|
||||
|
||||
if r.Header.Get("Content-Length") == "" {
|
||||
postRawFail.Inc(1)
|
||||
s.BadRequest(w, r, "missing Content-Length header in request")
|
||||
return
|
||||
}
|
||||
|
||||
key, err := s.api.Store(r.Body, r.ContentLength, nil)
|
||||
if err != nil {
|
||||
postRawFail.Inc(1)
|
||||
s.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
@ -117,8 +145,10 @@ func (s *Server) HandlePostRaw(w http.ResponseWriter, r *Request) {
|
||||
// existing manifest or to a new manifest under <path> and returns the
|
||||
// resulting manifest hash as a text/plain response
|
||||
func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) {
|
||||
postFilesCount.Inc(1)
|
||||
contentType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
postFilesFail.Inc(1)
|
||||
s.BadRequest(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
@ -127,12 +157,14 @@ func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) {
|
||||
if r.uri.Addr != "" {
|
||||
key, err = s.api.Resolve(r.uri)
|
||||
if err != nil {
|
||||
postFilesFail.Inc(1)
|
||||
s.Error(w, r, fmt.Errorf("error resolving %s: %s", r.uri.Addr, err))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
key, err = s.api.NewManifest()
|
||||
if err != nil {
|
||||
postFilesFail.Inc(1)
|
||||
s.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
@ -152,6 +184,7 @@ func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) {
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
postFilesFail.Inc(1)
|
||||
s.Error(w, r, fmt.Errorf("error creating manifest: %s", err))
|
||||
return
|
||||
}
|
||||
@ -270,8 +303,10 @@ func (s *Server) handleDirectUpload(req *Request, mw *api.ManifestWriter) error
|
||||
// <path> from <manifest> and returns the resulting manifest hash as a
|
||||
// text/plain response
|
||||
func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) {
|
||||
deleteCount.Inc(1)
|
||||
key, err := s.api.Resolve(r.uri)
|
||||
if err != nil {
|
||||
deleteFail.Inc(1)
|
||||
s.Error(w, r, fmt.Errorf("error resolving %s: %s", r.uri.Addr, err))
|
||||
return
|
||||
}
|
||||
@ -281,6 +316,7 @@ func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) {
|
||||
return mw.RemoveEntry(r.uri.Path)
|
||||
})
|
||||
if err != nil {
|
||||
deleteFail.Inc(1)
|
||||
s.Error(w, r, fmt.Errorf("error updating manifest: %s", err))
|
||||
return
|
||||
}
|
||||
@ -296,8 +332,10 @@ func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) {
|
||||
// - bzz-hash://<key> and responds with the hash of the content stored
|
||||
// at the given storage key as a text/plain response
|
||||
func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
||||
getCount.Inc(1)
|
||||
key, err := s.api.Resolve(r.uri)
|
||||
if err != nil {
|
||||
getFail.Inc(1)
|
||||
s.Error(w, r, fmt.Errorf("error resolving %s: %s", r.uri.Addr, err))
|
||||
return
|
||||
}
|
||||
@ -307,6 +345,7 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
||||
if r.uri.Path != "" {
|
||||
walker, err := s.api.NewManifestWalker(key, nil)
|
||||
if err != nil {
|
||||
getFail.Inc(1)
|
||||
s.BadRequest(w, r, fmt.Sprintf("%s is not a manifest", key))
|
||||
return
|
||||
}
|
||||
@ -335,6 +374,7 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
||||
return api.SkipManifest
|
||||
})
|
||||
if entry == nil {
|
||||
getFail.Inc(1)
|
||||
s.NotFound(w, r, fmt.Errorf("Manifest entry could not be loaded"))
|
||||
return
|
||||
}
|
||||
@ -344,6 +384,7 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
||||
// check the root chunk exists by retrieving the file's size
|
||||
reader := s.api.Retrieve(key)
|
||||
if _, err := reader.Size(nil); err != nil {
|
||||
getFail.Inc(1)
|
||||
s.NotFound(w, r, fmt.Errorf("Root chunk not found %s: %s", key, err))
|
||||
return
|
||||
}
|
||||
@ -370,19 +411,23 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
||||
// header of "application/x-tar" and returns a tar stream of all files
|
||||
// contained in the manifest
|
||||
func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) {
|
||||
getFilesCount.Inc(1)
|
||||
if r.uri.Path != "" {
|
||||
getFilesFail.Inc(1)
|
||||
s.BadRequest(w, r, "files request cannot contain a path")
|
||||
return
|
||||
}
|
||||
|
||||
key, err := s.api.Resolve(r.uri)
|
||||
if err != nil {
|
||||
getFilesFail.Inc(1)
|
||||
s.Error(w, r, fmt.Errorf("error resolving %s: %s", r.uri.Addr, err))
|
||||
return
|
||||
}
|
||||
|
||||
walker, err := s.api.NewManifestWalker(key, nil)
|
||||
if err != nil {
|
||||
getFilesFail.Inc(1)
|
||||
s.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
@ -430,6 +475,7 @@ func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) {
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
getFilesFail.Inc(1)
|
||||
s.logError("error generating tar stream: %s", err)
|
||||
}
|
||||
}
|
||||
@ -438,6 +484,7 @@ func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) {
|
||||
// a list of all files contained in <manifest> under <path> grouped into
|
||||
// common prefixes using "/" as a delimiter
|
||||
func (s *Server) HandleGetList(w http.ResponseWriter, r *Request) {
|
||||
getListCount.Inc(1)
|
||||
// ensure the root path has a trailing slash so that relative URLs work
|
||||
if r.uri.Path == "" && !strings.HasSuffix(r.URL.Path, "/") {
|
||||
http.Redirect(w, &r.Request, r.URL.Path+"/", http.StatusMovedPermanently)
|
||||
@ -446,6 +493,7 @@ func (s *Server) HandleGetList(w http.ResponseWriter, r *Request) {
|
||||
|
||||
key, err := s.api.Resolve(r.uri)
|
||||
if err != nil {
|
||||
getListFail.Inc(1)
|
||||
s.Error(w, r, fmt.Errorf("error resolving %s: %s", r.uri.Addr, err))
|
||||
return
|
||||
}
|
||||
@ -453,6 +501,7 @@ func (s *Server) HandleGetList(w http.ResponseWriter, r *Request) {
|
||||
list, err := s.getManifestList(key, r.uri.Path)
|
||||
|
||||
if err != nil {
|
||||
getListFail.Inc(1)
|
||||
s.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
@ -470,6 +519,7 @@ func (s *Server) HandleGetList(w http.ResponseWriter, r *Request) {
|
||||
List: &list,
|
||||
})
|
||||
if err != nil {
|
||||
getListFail.Inc(1)
|
||||
s.logError("error rendering list HTML: %s", err)
|
||||
}
|
||||
return
|
||||
@ -538,6 +588,7 @@ func (s *Server) getManifestList(key storage.Key, prefix string) (list api.Manif
|
||||
// HandleGetFile handles a GET request to bzz://<manifest>/<path> and responds
|
||||
// with the content of the file at <path> from the given <manifest>
|
||||
func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
|
||||
getFileCount.Inc(1)
|
||||
// ensure the root path has a trailing slash so that relative URLs work
|
||||
if r.uri.Path == "" && !strings.HasSuffix(r.URL.Path, "/") {
|
||||
http.Redirect(w, &r.Request, r.URL.Path+"/", http.StatusMovedPermanently)
|
||||
@ -546,6 +597,7 @@ func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
|
||||
|
||||
key, err := s.api.Resolve(r.uri)
|
||||
if err != nil {
|
||||
getFileFail.Inc(1)
|
||||
s.Error(w, r, fmt.Errorf("error resolving %s: %s", r.uri.Addr, err))
|
||||
return
|
||||
}
|
||||
@ -554,8 +606,10 @@ func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
|
||||
if err != nil {
|
||||
switch status {
|
||||
case http.StatusNotFound:
|
||||
getFileNotFound.Inc(1)
|
||||
s.NotFound(w, r, err)
|
||||
default:
|
||||
getFileFail.Inc(1)
|
||||
s.Error(w, r, err)
|
||||
}
|
||||
return
|
||||
@ -567,6 +621,7 @@ func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
|
||||
list, err := s.getManifestList(key, r.uri.Path)
|
||||
|
||||
if err != nil {
|
||||
getFileFail.Inc(1)
|
||||
s.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
@ -579,6 +634,7 @@ func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
|
||||
|
||||
// check the root chunk exists by retrieving the file's size
|
||||
if _, err := reader.Size(nil); err != nil {
|
||||
getFileNotFound.Inc(1)
|
||||
s.NotFound(w, r, fmt.Errorf("File not found %s: %s", r.uri, err))
|
||||
return
|
||||
}
|
||||
@ -589,6 +645,19 @@ func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
|
||||
}
|
||||
|
||||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if metrics.Enabled {
|
||||
//The increment for request count and request timer themselves have a flag check
|
||||
//for metrics.Enabled. Nevertheless, we introduce the if here because we
|
||||
//are looking into the header just to see what request type it is (json/html).
|
||||
//So let's take advantage and add all metrics related stuff here
|
||||
requestCount.Inc(1)
|
||||
defer requestTimer.UpdateSince(time.Now())
|
||||
if r.Header.Get("Accept") == "application/json" {
|
||||
jsonRequestCount.Inc(1)
|
||||
} else {
|
||||
htmlRequestCount.Inc(1)
|
||||
}
|
||||
}
|
||||
s.logDebug("HTTP %s request URL: '%s', Host: '%s', Path: '%s', Referer: '%s', Accept: '%s'", r.Method, r.RequestURI, r.URL.Host, r.URL.Path, r.Referer(), r.Header.Get("Accept"))
|
||||
|
||||
uri, err := api.Parse(strings.TrimLeft(r.URL.Path, "/"))
|
||||
|
Reference in New Issue
Block a user