Commit 28ab61e1 authored by Tomasz Maczukin's avatar Tomasz Maczukin

Refactor metrics counting

parent 8e4cf676
...@@ -18,20 +18,18 @@ import ( ...@@ -18,20 +18,18 @@ import (
) )
var ( var (
artifactsUploadRequests = prometheus.NewCounterVec( artifactsUploadRequests = prometheus.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "gitlab_workhorse_artifacts_upload_requests", Name: "gitlab_workhorse_artifacts_upload_requests",
Help: "How many artifacts upload requests have been processed by gitlab-workhorse.", Help: "How many artifacts upload requests have been processed by gitlab-workhorse.",
}, },
nil,
) )
artifactsUploadBytes = prometheus.NewCounterVec( artifactsUploadBytes = prometheus.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "gitlab_workhorse_artifacts_upload_bytes", Name: "gitlab_workhorse_artifacts_upload_bytes",
Help: "How many artifacts upload bytes have been send by gitlab-workhorse.", Help: "How many artifacts upload bytes have been sent by gitlab-workhorse.",
}, },
nil,
) )
) )
...@@ -98,9 +96,9 @@ func (a *artifactsUploadProcessor) Cleanup() { ...@@ -98,9 +96,9 @@ func (a *artifactsUploadProcessor) Cleanup() {
func UploadArtifacts(myAPI *api.API, h http.Handler) http.Handler { func UploadArtifacts(myAPI *api.API, h http.Handler) http.Handler {
return myAPI.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) { return myAPI.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) {
artifactsUploadRequests.WithLabelValues().Inc() artifactsUploadRequests.Inc()
defer func() { defer func() {
artifactsUploadBytes.WithLabelValues().Add(float64(r.ContentLength)) artifactsUploadBytes.Add(float64(r.ContentLength))
}() }()
if a.TempPath == "" { if a.TempPath == "" {
......
...@@ -26,17 +26,17 @@ var ( ...@@ -26,17 +26,17 @@ var (
gitHTTPRequests = prometheus.NewCounterVec( gitHTTPRequests = prometheus.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "gitlab_workhorse_git_http_requests", Name: "gitlab_workhorse_git_http_requests",
Help: "How many Git HTTP requests have been processed by gitlab-workhorse, partitioned by CI yes/no status.", Help: "How many Git HTTP requests have been processed by gitlab-workhorse, partitioned by request type and agent.",
}, },
[]string{"ci"}, []string{"request_type", "agent"},
) )
gitHTTPBytes = prometheus.NewCounterVec( gitHTTPBytes = prometheus.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "gitlab_workhorse_git_http_bytes", Name: "gitlab_workhorse_git_http_bytes",
Help: "How many Git HTTP bytes have been send by gitlab-workhorse, partitioned by CI yes/no status.", Help: "How many Git HTTP bytes have been sent by gitlab-workhorse, partitioned by request type, agent and direction.",
}, },
[]string{"ci"}, []string{"request_type", "agent", "direction"},
) )
) )
...@@ -63,25 +63,19 @@ func looksLikeRepo(p string) bool { ...@@ -63,25 +63,19 @@ func looksLikeRepo(p string) bool {
return true return true
} }
func forCI(r *http.Request) string { func getRequestAgent(r *http.Request) string {
u, _, ok := r.BasicAuth() u, _, ok := r.BasicAuth()
if ok && u == "gitlab-ci-token" { if ok && u == "gitlab-ci-token" {
return "1" return "gitlab-ci"
} else if ok {
return "logged"
} else { } else {
return "0" return "anonymous"
} }
} }
func repoPreAuthorizeHandler(myAPI *api.API, handleFunc api.HandleFunc) http.Handler { func repoPreAuthorizeHandler(myAPI *api.API, handleFunc api.HandleFunc) http.Handler {
return myAPI.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) { return myAPI.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) {
gitHTTPRequests.WithLabelValues(forCI(r)).Inc()
defer func() {
lw, ok := w.(*helper.LoggingResponseWriter)
if ok {
gitHTTPBytes.WithLabelValues(forCI(r)).Add(float64(lw.Size()))
}
}()
if a.RepoPath == "" { if a.RepoPath == "" {
helper.Fail500(w, r, fmt.Errorf("repoPreAuthorizeHandler: RepoPath empty")) helper.Fail500(w, r, fmt.Errorf("repoPreAuthorizeHandler: RepoPath empty"))
return return
...@@ -104,6 +98,13 @@ func handleGetInfoRefs(w http.ResponseWriter, r *http.Request, a *api.Response) ...@@ -104,6 +98,13 @@ func handleGetInfoRefs(w http.ResponseWriter, r *http.Request, a *api.Response)
return return
} }
requestType := "get-info-refs"
gitHTTPRequests.WithLabelValues(requestType, getRequestAgent(r)).Inc()
var writtenOut int64
defer func() {
gitHTTPBytes.WithLabelValues(requestType, getRequestAgent(r), "out").Add(float64(writtenOut))
}()
// Prepare our Git subprocess // Prepare our Git subprocess
cmd := gitCommand(a.GL_ID, "git", subCommand(rpc), "--stateless-rpc", "--advertise-refs", a.RepoPath) cmd := gitCommand(a.GL_ID, "git", subCommand(rpc), "--stateless-rpc", "--advertise-refs", a.RepoPath)
stdout, err := cmd.StdoutPipe() stdout, err := cmd.StdoutPipe()
...@@ -130,7 +131,7 @@ func handleGetInfoRefs(w http.ResponseWriter, r *http.Request, a *api.Response) ...@@ -130,7 +131,7 @@ func handleGetInfoRefs(w http.ResponseWriter, r *http.Request, a *api.Response)
helper.LogError(r, fmt.Errorf("handleGetInfoRefs: pktFlush: %v", err)) helper.LogError(r, fmt.Errorf("handleGetInfoRefs: pktFlush: %v", err))
return return
} }
if _, err := io.Copy(w, stdout); err != nil { if writtenOut, err = io.Copy(w, stdout); err != nil {
helper.LogError( helper.LogError(
r, r,
&copyError{fmt.Errorf("handleGetInfoRefs: copy output of %v: %v", cmd.Args, err)}, &copyError{fmt.Errorf("handleGetInfoRefs: copy output of %v: %v", cmd.Args, err)},
...@@ -156,6 +157,14 @@ func handlePostRPC(w http.ResponseWriter, r *http.Request, a *api.Response) { ...@@ -156,6 +157,14 @@ func handlePostRPC(w http.ResponseWriter, r *http.Request, a *api.Response) {
return return
} }
requestType := "post-" + action
gitHTTPRequests.WithLabelValues(requestType, getRequestAgent(r)).Inc()
var writtenIn, writtenOut int64
defer func() {
gitHTTPBytes.WithLabelValues(requestType, getRequestAgent(r), "in").Add(float64(writtenIn))
gitHTTPBytes.WithLabelValues(requestType, getRequestAgent(r), "out").Add(float64(writtenOut))
}()
if action == "git-upload-pack" { if action == "git-upload-pack" {
buffer := &bytes.Buffer{} buffer := &bytes.Buffer{}
// Only sniff on the first 4096 bytes: we assume that if we find no // Only sniff on the first 4096 bytes: we assume that if we find no
...@@ -194,7 +203,7 @@ func handlePostRPC(w http.ResponseWriter, r *http.Request, a *api.Response) { ...@@ -194,7 +203,7 @@ func handlePostRPC(w http.ResponseWriter, r *http.Request, a *api.Response) {
defer helper.CleanUpProcessGroup(cmd) // Ensure brute force subprocess clean-up defer helper.CleanUpProcessGroup(cmd) // Ensure brute force subprocess clean-up
// Write the client request body to Git's standard input // Write the client request body to Git's standard input
if _, err := io.Copy(stdin, body); err != nil { if writtenIn, err = io.Copy(stdin, body); err != nil {
helper.Fail500(w, r, fmt.Errorf("handlePostRPC: write to %v: %v", cmd.Args, err)) helper.Fail500(w, r, fmt.Errorf("handlePostRPC: write to %v: %v", cmd.Args, err))
return return
} }
...@@ -211,7 +220,7 @@ func handlePostRPC(w http.ResponseWriter, r *http.Request, a *api.Response) { ...@@ -211,7 +220,7 @@ func handlePostRPC(w http.ResponseWriter, r *http.Request, a *api.Response) {
w.WriteHeader(200) // Don't bother with HTTP 500 from this point on, just return w.WriteHeader(200) // Don't bother with HTTP 500 from this point on, just return
// This io.Copy may take a long time, both for Git push and pull. // This io.Copy may take a long time, both for Git push and pull.
if _, err := io.Copy(w, stdout); err != nil { if writtenOut, err = io.Copy(w, stdout); err != nil {
helper.LogError( helper.LogError(
r, r,
&copyError{fmt.Errorf("handlePostRPC: copy output of %v: %v", cmd.Args, err)}, &copyError{fmt.Errorf("handlePostRPC: copy output of %v: %v", cmd.Args, err)},
......
...@@ -91,7 +91,3 @@ func (l *LoggingResponseWriter) Log(r *http.Request) { ...@@ -91,7 +91,3 @@ func (l *LoggingResponseWriter) Log(r *http.Request) {
sessionsActive.Dec() sessionsActive.Dec()
requestsTotal.WithLabelValues(strconv.Itoa(l.status), r.Method).Inc() requestsTotal.WithLabelValues(strconv.Itoa(l.status), r.Method).Inc()
} }
func (l *LoggingResponseWriter) Size() int64 {
return l.written
}
...@@ -30,7 +30,7 @@ var ( ...@@ -30,7 +30,7 @@ var (
sendFileBytes = prometheus.NewCounterVec( sendFileBytes = prometheus.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "gitlab_workhorse_sendfile_bytes", Name: "gitlab_workhorse_sendfile_bytes",
Help: "How many X-Sendfile bytes have been send by gitlab-workhorse, partitioned by sendfile type.", Help: "How many X-Sendfile bytes have been sent by gitlab-workhorse, partitioned by sendfile type.",
}, },
[]string{"type"}, []string{"type"},
) )
...@@ -125,9 +125,7 @@ func countSendFileMetrics(size int64, r *http.Request) { ...@@ -125,9 +125,7 @@ func countSendFileMetrics(size int64, r *http.Request) {
} }
sendFileRequests.WithLabelValues(requestType).Inc() sendFileRequests.WithLabelValues(requestType).Inc()
defer func() {
sendFileBytes.WithLabelValues(requestType).Add(float64(size)) sendFileBytes.WithLabelValues(requestType).Add(float64(size))
}()
} }
func (s *sendFileResponseWriter) Flush() { func (s *sendFileResponseWriter) Flush() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment