Skip to content
Permalink
Browse files

Fixing concurrency access to map

  • Loading branch information...
Depado committed Oct 31, 2017
1 parent 16930c4 commit 0c28c9ea599e462a941c155ecdd4a67f32a9814e
Showing with 30 additions and 14 deletions.
  1. +3 −3 README.md
  2. +27 −11 prom.go
@@ -17,7 +17,6 @@ Simply run :
## Differences with go-gin-prometheus

- No support for Prometheus' Push Gateway
- Need to call middleware on each route
- Options on constructor
- Adds a `path` label to get the matched route

@@ -34,9 +33,10 @@ import (
func main() {
r := gin.Default()
p := ginprom.New(ginprom.Subsystem("gin"), ginprom.Path("/metrics"), ginprom.Engine(r))
r.Use(p.Instrument())
r.GET("/hello/:id", p.Instrument("/hello/:id"), func(c *gin.Context) {})
r.GET("/world/:id", p.Instrument("/world/:id"), func(c *gin.Context) {})
r.GET("/hello/:id", func(c *gin.Context) {})
r.GET("/world/:id", func(c *gin.Context) {})
r.Run("127.0.0.1:8080")
}
```
38 prom.go
@@ -2,6 +2,7 @@ package ginprom

import (
"strconv"
"sync"
"time"

"github.com/gin-gonic/gin"
@@ -12,6 +13,11 @@ import (
var defaultPath = "/metrics"
var defaultSys = "gin"

type pmap struct {
sync.RWMutex
values map[string]string
}

// Prometheus contains the metrics gathered by the instance and its path
type Prometheus struct {
reqCnt *prometheus.CounterVec
@@ -20,7 +26,7 @@ type Prometheus struct {
MetricsPath string
Subsystem string
Engine *gin.Engine
PathMap map[string]string
PathMap pmap
}

// Path is an option allowing to set the metrics path when intializing with New.
@@ -66,14 +72,31 @@ func New(options ...func(*Prometheus)) *Prometheus {
if p.Engine != nil {
p.Engine.GET(p.MetricsPath, prometheusHandler())
}
p.PathMap = make(map[string]string)
p.PathMap.values = make(map[string]string)
return p
}

func (p *Prometheus) updatePathMap() {
p.PathMap.Lock()
defer p.PathMap.Unlock()
for _, ri := range p.Engine.Routes() {
p.PathMap[ri.Handler] = ri.Path
p.PathMap.values[ri.Handler] = ri.Path
}
}

func (p *Prometheus) getPathFromHandler(handler string) string {
p.PathMap.RLock()
defer p.PathMap.RUnlock()
if in, ok := p.PathMap.values[handler]; ok {
return in
}
p.PathMap.RUnlock()
p.updatePathMap()
p.PathMap.RLock()
if in, ok := p.PathMap.values[handler]; ok {
return in
}
return ""
}

func (p *Prometheus) register() {
@@ -129,14 +152,7 @@ func (p *Prometheus) Instrument() gin.HandlerFunc {
return
}

if in, ok := p.PathMap[c.HandlerName()]; ok {
path = in
} else {
p.updatePathMap()
if in, ok := p.PathMap[c.HandlerName()]; ok {
path = in
}
}
path = p.getPathFromHandler(c.HandlerName())

c.Next()

0 comments on commit 0c28c9e

Please sign in to comment.
You can’t perform that action at this time.