You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
2.9 KiB
130 lines
2.9 KiB
8 years ago
|
/*
|
||
|
* Minio Cloud Storage, (C) 2017 Minio, Inc.
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
package cmd
|
||
|
|
||
|
import (
|
||
|
"net/http"
|
||
|
"sync/atomic"
|
||
|
)
|
||
|
|
||
|
// counter - simplify atomic counting
|
||
|
type counter struct {
|
||
|
val uint64
|
||
|
}
|
||
|
|
||
|
// Inc increases counter atomically
|
||
|
func (c *counter) Inc(n uint64) {
|
||
|
atomic.AddUint64(&c.val, n)
|
||
|
}
|
||
|
|
||
|
// Value fetches counter's value atomically
|
||
|
func (c *counter) Value() uint64 {
|
||
|
return atomic.LoadUint64(&c.val)
|
||
|
}
|
||
|
|
||
|
// ConnStats - Network statistics
|
||
|
// Count total input/output transferred bytes during
|
||
|
// the server's life.
|
||
|
type ConnStats struct {
|
||
|
totalInputBytes counter
|
||
|
totalOutputBytes counter
|
||
|
}
|
||
|
|
||
|
// Increase total input bytes
|
||
|
func (s *ConnStats) incInputBytes(n int) {
|
||
|
s.totalInputBytes.Inc(uint64(n))
|
||
|
}
|
||
|
|
||
|
// Increase total output bytes
|
||
|
func (s *ConnStats) incOutputBytes(n int) {
|
||
|
s.totalOutputBytes.Inc(uint64(n))
|
||
|
}
|
||
|
|
||
|
// Return total input bytes
|
||
|
func (s *ConnStats) getTotalInputBytes() uint64 {
|
||
|
return s.totalInputBytes.Value()
|
||
|
}
|
||
|
|
||
|
// Return total output bytes
|
||
|
func (s *ConnStats) getTotalOutputBytes() uint64 {
|
||
|
return s.totalOutputBytes.Value()
|
||
|
}
|
||
|
|
||
|
// Prepare new ConnStats structure
|
||
|
func newConnStats() *ConnStats {
|
||
|
return &ConnStats{}
|
||
|
}
|
||
|
|
||
|
// httpStats holds statistics information about
|
||
|
// HTTP requests made by all clients
|
||
|
type httpStats struct {
|
||
|
// HEAD request stats
|
||
|
totalHEADs counter
|
||
|
successHEADs counter
|
||
|
// GET request stats
|
||
|
totalGETs counter
|
||
|
successGETs counter
|
||
|
// PUT request
|
||
|
totalPUTs counter
|
||
|
successPUTs counter
|
||
|
// POST request
|
||
|
totalPOSTs counter
|
||
|
successPOSTs counter
|
||
|
// DELETE request
|
||
|
totalDELETEs counter
|
||
|
successDELETEs counter
|
||
|
}
|
||
|
|
||
|
// Update statistics from http request and response data
|
||
|
func (st *httpStats) updateStats(r *http.Request, w *httpResponseRecorder) {
|
||
|
// A successful request has a 2xx response code
|
||
|
successReq := (w.respStatusCode >= 200 && w.respStatusCode < 300)
|
||
|
// Update stats according to method verb
|
||
|
switch r.Method {
|
||
|
case "HEAD":
|
||
|
st.totalHEADs.Inc(1)
|
||
|
if successReq {
|
||
|
st.successHEADs.Inc(1)
|
||
|
}
|
||
|
case "GET":
|
||
|
st.totalGETs.Inc(1)
|
||
|
if successReq {
|
||
|
st.successGETs.Inc(1)
|
||
|
}
|
||
|
case "PUT":
|
||
|
st.totalPUTs.Inc(1)
|
||
|
if successReq {
|
||
|
st.successPUTs.Inc(1)
|
||
|
}
|
||
|
case "POST":
|
||
|
st.totalPOSTs.Inc(1)
|
||
|
if successReq {
|
||
|
st.successPOSTs.Inc(1)
|
||
|
}
|
||
|
case "DELETE":
|
||
|
st.totalDELETEs.Inc(1)
|
||
|
if successReq {
|
||
|
st.successDELETEs.Inc(1)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Prepare new HttpStats structure
|
||
|
func newHTTPStats() *httpStats {
|
||
|
return &httpStats{}
|
||
|
}
|