feat: prometheus metrics
This commit is contained in:
		
					parent
					
						
							
								c8e82d5d43
							
						
					
				
			
			
				commit
				
					
						afabaec45b
					
				
			
		
					 7 changed files with 120 additions and 17 deletions
				
			
		
							
								
								
									
										20
									
								
								cmd/root.go
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								cmd/root.go
									
										
									
									
									
								
							|  | @ -8,12 +8,18 @@ import ( | |||
| 	"github.com/spf13/cobra" | ||||
| 	"github.com/spf13/viper" | ||||
| 
 | ||||
| 	// "github.com/gorilla/mux" // Import Gorilla Mux | ||||
| 	"github.com/prometheus/client_golang/prometheus/promhttp" | ||||
| 
 | ||||
| 	"goblin/config" | ||||
| 	"goblin/internal/paste" | ||||
| 	"goblin/internal/router" | ||||
| 	// "goblin/internal/router" | ||||
| ) | ||||
| 
 | ||||
| var verbose bool | ||||
| var ( | ||||
| 	verbose       bool | ||||
| 	enableMetrics bool | ||||
| ) | ||||
| 
 | ||||
| var rootCmd = &cobra.Command{ | ||||
| 	Use:   "goblin", | ||||
|  | @ -57,13 +63,16 @@ var rootCmd = &cobra.Command{ | |||
| 		log.Infof("Private mode: %v", private) | ||||
| 
 | ||||
| 		// Create the router and start the server using the router package | ||||
| 		r := router.NewRouter() | ||||
| 		// r := router.NewRouter() | ||||
| 
 | ||||
| 		// Add a new route for Prometheus metrics | ||||
| 		http.Handle("/metrics", promhttp.Handler()) // Use Prometheus handler | ||||
| 
 | ||||
| 		log.Info("Server started") | ||||
| 
 | ||||
| 		log.Infof("Listening on port %s\n", port) | ||||
| 
 | ||||
| 		err = http.ListenAndServe(":"+port, r) | ||||
| 		err = http.ListenAndServe(":"+port, nil) // Use nil handler for default routing | ||||
| 		if err != nil { | ||||
| 			log.Errorf("Error starting server: %v\n", err) | ||||
| 		} | ||||
|  | @ -87,8 +96,9 @@ func intializeFlags() { | |||
| 	rootCmd.PersistentFlags().String("templateDirectory", "", "Template directory path") | ||||
| 	rootCmd.PersistentFlags().String("logDir", "", "Log file location") | ||||
| 	rootCmd.PersistentFlags().String("pasteDir", "", "Paste storage location") | ||||
| 	rootCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "Print config values") | ||||
| 	rootCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "Print config values and enable verbose logging") | ||||
| 	rootCmd.PersistentFlags().Int("expire", 24, "Paste expiration duration in hours") | ||||
| 	rootCmd.PersistentFlags().BoolVar(&enableMetrics, "metrics", false, "Enable Prometheus metrics") | ||||
| 
 | ||||
| 	viper.BindPFlag("Port", rootCmd.PersistentFlags().Lookup("port")) | ||||
| 	viper.BindPFlag("Private", rootCmd.PersistentFlags().Lookup("private")) | ||||
|  |  | |||
|  | @ -26,7 +26,8 @@ func LoadConfig() (*AppConfig, error) { | |||
| 	viper.SetDefault("TemplateDir", "templates") | ||||
| 	viper.SetDefault("LogDir", "logs") | ||||
| 	viper.SetDefault("PasteDir", "pastes") | ||||
| 	viper.SetDefault("Expire", 24) // Default expiration duration in hours | ||||
| 	viper.SetDefault("Expire", 24) //  in hours | ||||
| 	viper.SetDefault("Metrics", false) | ||||
| 
 | ||||
| 	// read the configuration file if it's present | ||||
| 	// goblin can also be configured through command lines during runtime | ||||
|  |  | |||
							
								
								
									
										9
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -4,18 +4,26 @@ go 1.20 | |||
| 
 | ||||
| require ( | ||||
| 	github.com/gorilla/mux v1.8.0 | ||||
| 	github.com/prometheus/client_golang v1.16.0 | ||||
| 	github.com/sirupsen/logrus v1.9.3 | ||||
| 	github.com/spf13/cobra v1.7.0 | ||||
| 	github.com/spf13/viper v1.16.0 | ||||
| ) | ||||
| 
 | ||||
| require ( | ||||
| 	github.com/beorn7/perks v1.0.1 // indirect | ||||
| 	github.com/cespare/xxhash/v2 v2.2.0 // indirect | ||||
| 	github.com/fsnotify/fsnotify v1.6.0 // indirect | ||||
| 	github.com/golang/protobuf v1.5.3 // indirect | ||||
| 	github.com/hashicorp/hcl v1.0.0 // indirect | ||||
| 	github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||||
| 	github.com/magiconair/properties v1.8.7 // indirect | ||||
| 	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect | ||||
| 	github.com/mitchellh/mapstructure v1.5.0 // indirect | ||||
| 	github.com/pelletier/go-toml/v2 v2.0.8 // indirect | ||||
| 	github.com/prometheus/client_model v0.3.0 // indirect | ||||
| 	github.com/prometheus/common v0.42.0 // indirect | ||||
| 	github.com/prometheus/procfs v0.10.1 // indirect | ||||
| 	github.com/spf13/afero v1.9.5 // indirect | ||||
| 	github.com/spf13/cast v1.5.1 // indirect | ||||
| 	github.com/spf13/jwalterweatherman v1.1.0 // indirect | ||||
|  | @ -24,6 +32,7 @@ require ( | |||
| 	github.com/subosito/gotenv v1.4.2 // indirect | ||||
| 	golang.org/x/sys v0.8.0 // indirect | ||||
| 	golang.org/x/text v0.9.0 // indirect | ||||
| 	google.golang.org/protobuf v1.30.0 // indirect | ||||
| 	gopkg.in/ini.v1 v1.67.0 // indirect | ||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||
| ) | ||||
|  |  | |||
							
								
								
									
										24
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								go.sum
									
										
									
									
									
								
							|  | @ -38,7 +38,11 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f | |||
| dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= | ||||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||
| github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= | ||||
| github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= | ||||
| github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | ||||
| github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | ||||
| github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= | ||||
| github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | ||||
| github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | ||||
| github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= | ||||
| github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= | ||||
|  | @ -87,6 +91,9 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq | |||
| github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= | ||||
| github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | ||||
| github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | ||||
| github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | ||||
| github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= | ||||
| github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= | ||||
| github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | ||||
|  | @ -98,6 +105,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ | |||
| github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||||
| github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= | ||||
| github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= | ||||
|  | @ -138,6 +146,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | |||
| github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||||
| github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= | ||||
| github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= | ||||
| github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= | ||||
| github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | ||||
| github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= | ||||
|  | @ -146,7 +156,15 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE | |||
| github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= | ||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||
| github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= | ||||
| github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= | ||||
| github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||
| github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= | ||||
| github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= | ||||
| github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= | ||||
| github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= | ||||
| github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= | ||||
| github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= | ||||
| github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= | ||||
| github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||||
|  | @ -471,9 +489,13 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 | |||
| google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | ||||
| google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= | ||||
| google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= | ||||
| google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | ||||
| google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | ||||
| google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= | ||||
| google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||||
| gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= | ||||
| gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= | ||||
| gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= | ||||
|  |  | |||
							
								
								
									
										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