feat: prometheus metrics
This commit is contained in:
parent
c8e82d5d43
commit
afabaec45b
7 changed files with 120 additions and 17 deletions
50
internal/metrics/metrics.go
Normal file
50
internal/metrics/metrics.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
var (
|
||||
pasteLengthHistogram = promauto.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Namespace: "goblin",
|
||||
Subsystem: "paste",
|
||||
Name: "length",
|
||||
Help: "Length of pastes",
|
||||
Buckets: prometheus.ExponentialBuckets(1, 2, 10), // Example buckets
|
||||
},
|
||||
[]string{"status"}, // Labels for success/failure
|
||||
)
|
||||
|
||||
pasteCreatedCounter = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: "goblin",
|
||||
Subsystem: "paste",
|
||||
Name: "created_total",
|
||||
Help: "Total number of pastes created",
|
||||
},
|
||||
[]string{"status"}, // Labels for success/failure
|
||||
)
|
||||
)
|
||||
|
||||
// ObservePasteLength records the length of pastes.
|
||||
func ObservePasteLength(status string, length float64) {
|
||||
pasteLengthHistogram.WithLabelValues(status).Observe(length)
|
||||
}
|
||||
|
||||
// IncrementPasteCreatedCounter increments the paste creation counter.
|
||||
func IncrementPasteCreatedCounter(status string) {
|
||||
pasteCreatedCounter.WithLabelValues(status).Inc()
|
||||
}
|
||||
|
||||
// InitPrometheus initializes Prometheus metrics and registers a handler for /metrics endpoint.
|
||||
func InitPrometheus(router *mux.Router) {
|
||||
// Register Prometheus metrics collectors here
|
||||
// For example, you can use promauto to define and register metrics
|
||||
|
||||
// Register Prometheus HTTP handler for /metrics endpoint with the Mux router
|
||||
router.Handle("/metrics", promhttp.Handler())
|
||||
}
|
|
@ -8,9 +8,9 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"goblin/internal/metrics"
|
||||
"goblin/internal/util"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
@ -62,6 +62,7 @@ func CreatePasteHandler(w http.ResponseWriter, r *http.Request) {
|
|||
content, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to read request body", http.StatusBadRequest)
|
||||
metrics.IncrementPasteCreatedCounter("failure")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -96,6 +97,7 @@ func CreatePasteHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if err := util.CreateDirectoryIfNotExists(pasteDir); err != nil {
|
||||
logger.Errorf("Failed to create paste directory: %v", err)
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
metrics.IncrementPasteCreatedCounter("failure")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -105,6 +107,7 @@ func CreatePasteHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
logger.Errorf("Failed to create paste file: %v", err)
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
metrics.IncrementPasteCreatedCounter("failure")
|
||||
return
|
||||
}
|
||||
defer pasteFile.Close()
|
||||
|
@ -114,32 +117,38 @@ func CreatePasteHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
logger.Errorf("Failed to write paste content to file: %v", err)
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
metrics.IncrementPasteCreatedCounter("failure")
|
||||
return
|
||||
}
|
||||
|
||||
// Determine the protocol based on the request's TLS connection
|
||||
protocol := "http"
|
||||
// Construct the complete paste URL including the protocol
|
||||
var protocol string
|
||||
if r.TLS != nil {
|
||||
protocol = "https"
|
||||
} else {
|
||||
protocol = "http"
|
||||
}
|
||||
|
||||
// Construct the complete paste URL with the protocol
|
||||
pasteURL := fmt.Sprintf("%s://%s/%s", protocol, r.Host, pasteID)
|
||||
|
||||
// Remove any trailing '%' character from the pasteURL
|
||||
if strings.HasSuffix(pasteURL, "%") {
|
||||
pasteURL = pasteURL[:len(pasteURL)-1]
|
||||
}
|
||||
|
||||
// Write the paste URL in the response
|
||||
response := fmt.Sprintf("Paste available at %s", pasteURL)
|
||||
w.Write([]byte(response))
|
||||
|
||||
// Record metrics
|
||||
metrics.IncrementPasteCreatedCounter("success")
|
||||
metrics.ObservePasteLength("success", float64(len(content)))
|
||||
}
|
||||
|
||||
func GetPasteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
pasteID := vars["id"]
|
||||
|
||||
// Exclude the "/metrics" path
|
||||
if pasteID == "metrics" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
p, exists := pasteMap[pasteID]
|
||||
if !exists {
|
||||
http.Error(w, "Paste not found", http.StatusNotFound)
|
||||
|
|
|
@ -9,7 +9,9 @@ import (
|
|||
|
||||
func NewRouter() http.Handler {
|
||||
r := mux.NewRouter()
|
||||
|
||||
r.HandleFunc("/", paste.CreatePasteHandler).Methods("POST")
|
||||
r.HandleFunc("/{id}", paste.GetPasteHandler).Methods("GET")
|
||||
|
||||
return r
|
||||
}
|
||||
|
|
Reference in a new issue